MediaVideoItem.java revision b27f2d3126d68796925f96078fd5ab3eb466e98a
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media.videoeditor;
18
19import java.io.IOException;
20
21import android.graphics.Bitmap;
22import android.view.SurfaceHolder;
23
24/**
25 * This class represents a video clip item on the storyboard
26 * {@hide}
27 */
28public class MediaVideoItem extends MediaItem {
29    // Instance variables
30    private final int mWidth;
31    private final int mHeight;
32    private final int mAspectRatio;
33    private final int mFileType;
34    private final int mVideoType;
35    private final int mVideoProfile;
36    private final int mVideoBitrate;
37    private final long mDurationMs;
38    private final int mAudioBitrate;
39    private final int mFps;
40    private final int mAudioType;
41    private final int mAudioChannels;
42    private final int mAudioSamplingFrequency;
43
44    private long mBeginBoundaryTimeMs;
45    private long mEndBoundaryTimeMs;
46    private int mVolumePercentage;
47    private boolean mMuted;
48    private String mAudioWaveformFilename;
49
50    /**
51     * An object of this type cannot be instantiated with a default constructor
52     */
53    @SuppressWarnings("unused")
54    private MediaVideoItem() throws IOException {
55        this(null, null, null, RENDERING_MODE_BLACK_BORDER);
56    }
57
58    /**
59     * Constructor
60     *
61     * @param editor The video editor reference
62     * @param mediaItemId The MediaItem id
63     * @param filename The image file name
64     * @param renderingMode The rendering mode
65     *
66     * @throws IOException if the file cannot be opened for reading
67     */
68    public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
69            int renderingMode)
70        throws IOException {
71        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
72    }
73
74    /**
75     * Constructor
76     *
77     * @param editor The video editor reference
78     * @param mediaItemId The MediaItem id
79     * @param filename The image file name
80     * @param renderingMode The rendering mode
81     * @param beginMs Start time in milliseconds. Set to 0 to extract from the
82     *           beginning
83     * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to
84     *           extract until the end
85     * @param volumePercent in %/. 100% means no change; 50% means half value, 200%
86     *            means double, 0% means silent.
87     * @param muted true if the audio is muted
88     * @param audioWaveformFilename The name of the audio waveform file
89     *
90     * @throws IOException if the file cannot be opened for reading
91     */
92    MediaVideoItem(VideoEditor editor, String mediaItemId, String filename, int renderingMode,
93            long beginMs, long endMs, int volumePercent, boolean muted,
94            String audioWaveformFilename)  throws IOException {
95        super(editor, mediaItemId, filename, renderingMode);
96        // TODO: Set these variables correctly
97        mWidth = 1080;
98        mHeight = 720;
99        mAspectRatio = MediaProperties.ASPECT_RATIO_3_2;
100        mFileType = MediaProperties.FILE_MP4;
101        mVideoType = MediaProperties.VCODEC_H264BP;
102        // Do we have predefined values for this variable?
103        mVideoProfile = 0;
104        // Can video and audio duration be different?
105        mDurationMs = 10000;
106        mVideoBitrate = 800000;
107        mAudioBitrate = 30000;
108        mFps = 30;
109        mAudioType = MediaProperties.ACODEC_AAC_LC;
110        mAudioChannels = 2;
111        mAudioSamplingFrequency = 16000;
112
113        mBeginBoundaryTimeMs = beginMs;
114        mEndBoundaryTimeMs = endMs == END_OF_FILE ? mDurationMs : endMs;
115        mVolumePercentage = volumePercent;
116        mMuted = muted;
117        mAudioWaveformFilename = audioWaveformFilename;
118    }
119
120    /**
121     * Sets the start and end marks for trimming a video media item.
122     * This method will adjust the duration of bounding transitions, effects
123     * and overlays if the current duration of the transactions become greater
124     * than the maximum allowable duration.
125     *
126     * @param beginMs Start time in milliseconds. Set to 0 to extract from the
127     *           beginning
128     * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to
129     *           extract until the end
130     *
131     * @throws IllegalArgumentException if the start time is greater or equal than
132     *           end time, the end time is beyond the file duration, the start time
133     *           is negative
134     */
135    public void setExtractBoundaries(long beginMs, long endMs) {
136        if (beginMs > mDurationMs) {
137            throw new IllegalArgumentException("Invalid start time");
138        }
139        if (endMs > mDurationMs) {
140            throw new IllegalArgumentException("Invalid end time");
141        }
142
143        if (beginMs != mBeginBoundaryTimeMs) {
144            if (mBeginTransition != null) {
145                mBeginTransition.invalidate();
146            }
147        }
148
149        if (endMs != mEndBoundaryTimeMs) {
150            if (mEndTransition != null) {
151                mEndTransition.invalidate();
152            }
153        }
154
155        mBeginBoundaryTimeMs = beginMs;
156        mEndBoundaryTimeMs = endMs;
157
158        adjustElementsDuration();
159    }
160
161    /**
162     * @return The boundary begin time
163     */
164    public long getBoundaryBeginTime() {
165        return mBeginBoundaryTimeMs;
166    }
167
168    /**
169     * @return The boundary end time
170     */
171    public long getBoundaryEndTime() {
172        return mEndBoundaryTimeMs;
173    }
174
175    /*
176     * {@inheritDoc}
177     */
178    @Override
179    public void addEffect(Effect effect) {
180        if (effect instanceof EffectKenBurns) {
181            throw new IllegalArgumentException("Ken Burns effects cannot be applied to MediaVideoItem");
182        }
183        super.addEffect(effect);
184    }
185
186    /*
187     * {@inheritDoc}
188     */
189    @Override
190    public Bitmap getThumbnail(int width, int height, long timeMs) {
191        return null;
192    }
193
194    /*
195     * {@inheritDoc}
196     */
197    @Override
198    public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs,
199            int thumbnailCount) throws IOException {
200        return null;
201    }
202
203    /*
204     * {@inheritDoc}
205     */
206    @Override
207    public int getAspectRatio() {
208        return mAspectRatio;
209    }
210
211    /*
212     * {@inheritDoc}
213     */
214    @Override
215    public int getFileType() {
216        return mFileType;
217    }
218
219    /*
220     * {@inheritDoc}
221     */
222    @Override
223    public int getWidth() {
224        return mWidth;
225    }
226
227    /*
228     * {@inheritDoc}
229     */
230    @Override
231    public int getHeight() {
232        return mHeight;
233    }
234
235    /**
236     * @return The duration of the video clip
237     */
238    public long getDuration() {
239        return mDurationMs;
240    }
241
242    /**
243     * @return The timeline duration. This is the actual duration in the
244     *      timeline (trimmed duration)
245     */
246    @Override
247    public long getTimelineDuration() {
248        return mEndBoundaryTimeMs - mBeginBoundaryTimeMs;
249    }
250
251    /**
252     * Render a frame according to the playback (in the native aspect ratio) for
253     * the specified media item. All effects and overlays applied to the media
254     * item are ignored. The extract boundaries are also ignored. This method
255     * can be used to playback frames when implementing trimming functionality.
256     *
257     * @param surfaceHolder SurfaceHolder used by the application
258     * @param timeMs time corresponding to the frame to display (relative to the
259     *            the beginning of the media item).
260     * @return The accurate time stamp of the frame that is rendered .
261     * @throws IllegalStateException if a playback, preview or an export is
262     *             already in progress
263     * @throws IllegalArgumentException if time is negative or greater than the
264     *             media item duration
265     */
266    public long renderFrame(SurfaceHolder surfaceHolder, long timeMs) {
267        return timeMs;
268    }
269
270    /**
271     * This API allows to generate a file containing the sample volume levels of
272     * the Audio track of this media item. This function may take significant
273     * time and is blocking. The file can be retrieved using
274     * getAudioWaveformFilename().
275     *
276     * @param listener The progress listener
277     *
278     * @throws IOException if the output file cannot be created
279     * @throws IllegalArgumentException if the mediaItem does not have a valid
280     *             Audio track
281     */
282    public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
283            throws IOException {
284        // TODO: Set mAudioWaveformFilename at the end once the export is complete
285    }
286
287    /**
288     * Get the audio waveform file name if {@link #extractAudioWaveform()} was
289     * successful. The file format is as following:
290     * <ul>
291     *  <li>first 4 bytes provide the number of samples for each value, as big-endian signed</li>
292     *  <li>4 following bytes is the total number of values in the file, as big-endian signed</li>
293     *  <li>all values follow as bytes Name is unique.</li>
294     *</ul>
295     * @return the name of the file, null if the file has not been computed or
296     *         if there is no Audio track in the mediaItem
297     */
298    public String getAudioWaveformFilename() {
299        return mAudioWaveformFilename;
300    }
301
302    /**
303     * Set volume of the Audio track of this mediaItem
304     *
305     * @param volumePercent in %/. 100% means no change; 50% means half value, 200%
306     *            means double, 0% means silent.
307     * @throws UsupportedOperationException if volume value is not supported
308     */
309    public void setVolume(int volumePercent) {
310        mVolumePercentage = volumePercent;
311    }
312
313    /**
314     * Get the volume value of the audio track as percentage. Call of this
315     * method before calling setVolume will always return 100%
316     *
317     * @return the volume in percentage
318     */
319    public int getVolume() {
320        return mVolumePercentage;
321    }
322
323    /**
324     * @param muted true to mute the media item
325     */
326    public void setMute(boolean muted) {
327        mMuted = muted;
328    }
329
330    /**
331     * @return true if the media item is muted
332     */
333    public boolean isMuted() {
334        return mMuted;
335    }
336
337    /**
338     * @return The video type
339     */
340    public int getVideoType() {
341        return mVideoType;
342    }
343
344    /**
345     * @return The video profile
346     */
347    public int getVideoProfile() {
348        return mVideoProfile;
349    }
350
351    /**
352     * @return The video bitrate
353     */
354    public int getVideoBitrate() {
355        return mVideoBitrate;
356    }
357
358    /**
359     * @return The audio bitrate
360     */
361    public int getAudioBitrate() {
362        return mAudioBitrate;
363    }
364
365    /**
366     * @return The number of frames per second
367     */
368    public int getFps() {
369        return mFps;
370    }
371
372    /**
373     * @return The audio codec
374     */
375    public int getAudioType() {
376        return mAudioType;
377    }
378
379    /**
380     * @return The number of audio channels
381     */
382    public int getAudioChannels() {
383        return mAudioChannels;
384    }
385
386    /**
387     * @return The audio sample frequency
388     */
389    public int getAudioSamplingFrequency() {
390        return mAudioSamplingFrequency;
391    }
392}
393