VideoEditor.java revision 289f08990ca1f0de33c9939a00958739969dff7e
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; 20import java.util.List; 21import java.util.concurrent.CancellationException; 22 23import android.view.SurfaceHolder; 24 25/** 26 * This is the interface implemented by classes which provide video editing 27 * functionality. The VideoEditor implementation class manages all input and 28 * output files. Unless specifically mentioned, methods are blocking. A 29 * typical editing session may consist of the following sequence of operations: 30 * 31 * <ul> 32 * <li>Add a set of MediaItems</li> 33 * <li>Apply a set of Transitions between MediaItems</li> 34 * <li>Add Effects and Overlays to media items</li> 35 * <li>Preview the movie at any time</li> 36 * <li>Save the VideoEditor implementation class internal state</li> 37 * <li>Release the VideoEditor implementation class instance by invoking 38 * {@link #release()} 39 * </ul> 40 * The internal VideoEditor state consists of the following elements: 41 * <ul> 42 * <li>Ordered & trimmed MediaItems</li> 43 * <li>Transition video clips</li> 44 * <li>Overlays</li> 45 * <li>Effects</li> 46 * <li>Audio waveform for the background audio and MediaItems</li> 47 * <li>Project thumbnail</li> 48 * <li>Last exported movie.</li> 49 * <li>Other project specific data such as the current aspect ratio.</li> 50 * </ul> 51 * {@hide} 52 */ 53public interface VideoEditor { 54 // The file name of the project thumbnail 55 public static final String THUMBNAIL_FILENAME = "thumbnail.jpg"; 56 57 // Use this value instead of the specific end of the storyboard timeline 58 // value. 59 public final static int DURATION_OF_STORYBOARD = -1; 60 61 /** 62 * This listener interface is used by the VideoEditor to emit preview 63 * progress notifications. This callback should be invoked after the 64 * number of frames specified by 65 * {@link #startPreview(SurfaceHolder surfaceHolder, long fromMs, 66 * int callbackAfterFrameCount, PreviewProgressListener listener)} 67 */ 68 public interface PreviewProgressListener { 69 /** 70 * This method notifies the listener of the current time position while 71 * previewing a project. 72 * 73 * @param videoEditor The VideoEditor instance 74 * @param timeMs The current preview position (expressed in milliseconds 75 * since the beginning of the storyboard timeline). 76 * @param end true if the end of the timeline was reached 77 */ 78 public void onProgress(VideoEditor videoEditor, long timeMs, boolean end); 79 } 80 81 /** 82 * This listener interface is used by the VideoEditor to emit export status 83 * notifications. 84 * {@link #export(String filename, ExportProgressListener listener, int height, int bitrate)} 85 */ 86 public interface ExportProgressListener { 87 /** 88 * This method notifies the listener of the progress status of a export 89 * operation. 90 * 91 * @param videoEditor The VideoEditor instance 92 * @param filename The name of the file which is in the process of being 93 * exported. 94 * @param progress The progress in %. At the beginning of the export, this 95 * value is set to 0; at the end, the value is set to 100. 96 */ 97 public void onProgress(VideoEditor videoEditor, String filename, int progress); 98 } 99 100 /** 101 * @return The path where the VideoEditor stores all files related to the 102 * project 103 */ 104 public String getPath(); 105 106 /** 107 * This method releases all in-memory resources used by the VideoEditor 108 * instance. All pending operations such as preview, export and extract 109 * audio waveform must be canceled. 110 */ 111 public void release(); 112 113 /** 114 * Persist the current internal state of VideoEditor to the project path. 115 * The VideoEditor state may be restored by invoking the 116 * {@link VideoEditorFactory#load(String)} method. This method does not 117 * release the internal in-memory state of the VideoEditor. To release 118 * the in-memory state of the VideoEditor the {@link #release()} method 119 * must be invoked. 120 * 121 * Pending transition generations must be allowed to complete before the 122 * state is saved. 123 * Pending audio waveform generations must be allowed to complete. 124 * Pending export operations must be allowed to continue. 125 */ 126 public void save() throws IOException; 127 128 /** 129 * Create the output movie based on all media items added and the applied 130 * storyboard items. This method can take a long time to execute and is 131 * blocking. The application will receive progress notifications via the 132 * ExportProgressListener. Specific implementations may not support multiple 133 * simultaneous export operations. Note that invoking methods which would 134 * change the contents of the output movie throw an IllegalStateException 135 * while an export operation is pending. 136 * 137 * @param filename The output file name (including the full path) 138 * @param height The height of the output video file. The supported values 139 * for height are described in the MediaProperties class, for 140 * example: HEIGHT_480. The width will be automatically computed 141 * according to the aspect ratio provided by 142 * {@link #setAspectRatio(int)} 143 * @param bitrate The bitrate of the output video file. This is approximate 144 * value for the output movie. Supported bitrate values are 145 * described in the MediaProperties class for example: 146 * BITRATE_384K 147 * @param audioCodec The audio codec to be used for the export. The audio 148 * codec values are defined in the MediaProperties class (e.g. 149 * ACODEC_AAC_LC). Note that not all audio codec types are 150 * supported for export purposes. 151 * @param videoCodec The video codec to be used for the export. The video 152 * codec values are defined in the MediaProperties class (e.g. 153 * VCODEC_H264BP). Note that not all video codec types are 154 * supported for export purposes. 155 * @param listener The listener for progress notifications. Use null if 156 * export progress notifications are not needed. 157 * @throws IllegalArgumentException if height or bitrate are not supported 158 * or if the audio or video codecs are not supported 159 * @throws IOException if output file cannot be created 160 * @throws IllegalStateException if a preview or an export is in progress or 161 * if no MediaItem has been added 162 * @throws CancellationException if export is canceled by calling 163 * {@link #cancelExport()} 164 * @throws UnsupportOperationException if multiple simultaneous export() are 165 * not allowed 166 */ 167 public void export(String filename, int height, int bitrate, int audioCodec, int videoCodec, 168 ExportProgressListener listener) throws IOException; 169 170 /** 171 * Cancel the running export operation. This method blocks until the 172 * export is canceled and the exported file (if any) is deleted. If the 173 * export completed by the time this method is invoked, the export file 174 * will be deleted. 175 * 176 * @param filename The filename which identifies the export operation to be 177 * canceled. 178 **/ 179 public void cancelExport(String filename); 180 181 /** 182 * Add a media item at the end of the storyboard. 183 * 184 * @param mediaItem The media item object to add 185 * @throws IllegalStateException if a preview or an export is in progress or 186 * if the media item id is not unique across all the media items 187 * added. 188 */ 189 public void addMediaItem(MediaItem mediaItem); 190 191 /** 192 * Insert a media item after the media item with the specified id. 193 * 194 * @param mediaItem The media item object to insert 195 * @param afterMediaItemId Insert the mediaItem after the media item 196 * identified by this id. If this parameter is null, the media 197 * item is inserted at the beginning of the timeline. 198 * 199 * @throws IllegalStateException if a preview or an export is in progress 200 * @throws IllegalArgumentException if media item with the specified id does 201 * not exist (null is a valid value) or if the media item id is 202 * not unique across all the media items added. 203 */ 204 public void insertMediaItem(MediaItem mediaItem, String afterMediaItemId); 205 206 /** 207 * Move a media item after the media item with the specified id. 208 * 209 * Note: The project thumbnail is regenerated if the media item is or 210 * becomes the first media item in the storyboard timeline. 211 * 212 * @param mediaItemId The id of the media item to move 213 * @param afterMediaItemId Move the media item identified by mediaItemId after 214 * the media item identified by this parameter. If this parameter 215 * is null, the media item is moved at the beginning of the 216 * timeline. 217 * 218 * @throws IllegalStateException if a preview or an export is in progress 219 * @throws IllegalArgumentException if one of media item ids is invalid 220 * (null is a valid value) 221 */ 222 public void moveMediaItem(String mediaItemId, String afterMediaItemId); 223 224 /** 225 * Remove the media item with the specified id. If there are transitions 226 * before or after this media item, then this/these transition(s) are 227 * removed from the storyboard. If the extraction of the audio waveform is 228 * in progress, the extraction is canceled and the file is deleted. 229 * 230 * Effects and overlays associated with the media item will also be 231 * removed. 232 * 233 * Note: The project thumbnail is regenerated if the media item which 234 * is removed is the first media item in the storyboard or if the 235 * media item is the only one in the storyboard. If the 236 * media item is the only one in the storyboard, the project thumbnail 237 * will be set to a black frame and the aspect ratio will revert to the 238 * default aspect ratio, and this method is equivalent to 239 * removeAllMediaItems() in this case. 240 * 241 * @param mediaItemId The unique id of the media item to be removed 242 * 243 * @return The media item that was removed 244 * 245 * @throws IllegalStateException if a preview or an export is in progress 246 * @throws IllegalArgumentException if media item with the specified id 247 * does not exist 248 */ 249 public MediaItem removeMediaItem(String mediaItemId); 250 251 /** 252 * Remove all media items in the storyboard. All effects, overlays and all 253 * transitions are also removed. 254 * 255 * Note: The project thumbnail will be set to a black frame and the aspect 256 * ratio will revert to the default aspect ratio. 257 * 258 * @throws IllegalStateException if a preview or an export is in progress 259 */ 260 public void removeAllMediaItems(); 261 262 /** 263 * Get the list of media items in the order in which it they appear in the 264 * storyboard timeline. 265 * 266 * Note that if any media item source files are no longer 267 * accessible, this method will still provide the full list of media items. 268 * 269 * @return The list of media items. If no media item exist an empty list 270 * will be returned. 271 */ 272 public List<MediaItem> getAllMediaItems(); 273 274 /** 275 * Find the media item with the specified id 276 * 277 * @param mediaItemId The media item id 278 * 279 * @return The media item with the specified id (null if it does not exist) 280 */ 281 public MediaItem getMediaItem(String mediaItemId); 282 283 /** 284 * Add a transition between the media items specified by the transition. 285 * If a transition existed at the same position it is invalidated and then 286 * the transition is replaced. Note that the new transition video clip is 287 * not automatically generated by this method. The 288 * {@link Transition#generate()} method must be invoked to generate 289 * the transition video clip. 290 * 291 * Note that the TransitionAtEnd and TransitionAtStart are special kinds 292 * that can not be applied between two media items. 293 * 294 * A crossfade audio transition will be automatically applied regardless of 295 * the video transition. 296 * 297 * @param transition The transition to apply 298 * 299 * @throws IllegalStateException if a preview or an export is in progress 300 * @throws IllegalArgumentException if the transition duration is larger 301 * than the smallest duration of the two media item files or 302 * if the two media items specified in the transition are not 303 * adjacent 304 */ 305 public void addTransition(Transition transition); 306 307 /** 308 * Remove the transition with the specified id. 309 * 310 * @param transitionId The id of the transition to be removed 311 * 312 * @return The transition that was removed 313 * @throws IllegalStateException if a preview or an export is in progress 314 * @throws IllegalArgumentException if transition with the specified id does 315 * not exist 316 */ 317 public Transition removeTransition(String transitionId); 318 319 /** 320 * Get the list of transitions 321 * 322 * @return The list of transitions. If no transitions exist an empty list 323 * will be returned. 324 */ 325 public List<Transition> getAllTransitions(); 326 327 /** 328 * Find the transition with the specified transition id. 329 * 330 * @param transitionId The transition id 331 * 332 * @return The transition 333 */ 334 public Transition getTransition(String transitionId); 335 336 /** 337 * Add the specified AudioTrack to the storyboard. Note: Specific 338 * implementations may support a limited number of audio tracks (e.g. only 339 * one audio track) 340 * 341 * @param audioTrack The AudioTrack to add 342 * @throws UnsupportedOperationException if the implementation supports a 343 * limited number of audio tracks. 344 * @throws IllegalArgumentException if media item is not unique across all 345 * the audio tracks already added. 346 */ 347 public void addAudioTrack(AudioTrack audioTrack); 348 349 /** 350 * Insert an audio track after the audio track with the specified id. Use 351 * addAudioTrack to add an audio track at the end of the storyboard 352 * timeline. 353 * 354 * @param audioTrack The audio track object to insert 355 * @param afterAudioTrackId Insert the audio track after the audio track 356 * identified by this parameter. If this parameter is null the 357 * audio track is added at the beginning of the timeline. 358 * @throws IllegalStateException if a preview or an export is in progress 359 * @throws IllegalArgumentException if media item with the specified id does 360 * not exist (null is a valid value). if media item is not 361 * unique across all the audio tracks already added. 362 * @throws UnsupportedOperationException if the implementation supports a 363 * limited number of audio tracks 364 */ 365 public void insertAudioTrack(AudioTrack audioTrack, String afterAudioTrackId); 366 367 /** 368 * Move an AudioTrack after the AudioTrack with the specified id. 369 * 370 * @param audioTrackId The id of the AudioTrack to move 371 * @param afterAudioTrackId Move the AudioTrack identified by audioTrackId 372 * after the AudioTrack identified by this parameter. If this 373 * parameter is null the audio track is added at the beginning of 374 * the timeline. 375 * @throws IllegalStateException if a preview or an export is in progress 376 * @throws IllegalArgumentException if one of media item ids is invalid 377 * (null is a valid value) 378 */ 379 public void moveAudioTrack(String audioTrackId, String afterAudioTrackId); 380 381 /** 382 * Remove the audio track with the specified id. If the extraction of the 383 * audio waveform is in progress, the extraction is canceled and the file is 384 * deleted. 385 * 386 * @param audioTrackId The id of the audio track to be removed 387 * 388 * @return The audio track that was removed 389 * @throws IllegalStateException if a preview or an export is in progress 390 */ 391 public AudioTrack removeAudioTrack(String audioTrackId); 392 393 /** 394 * Get the list of AudioTracks in order in which they appear in the storyboard. 395 * 396 * Note that if any AudioTrack source files are not accessible anymore, 397 * this method will still provide the full list of audio tracks. 398 * 399 * @return The list of AudioTracks. If no audio tracks exist an empty list 400 * will be returned. 401 */ 402 public List<AudioTrack> getAllAudioTracks(); 403 404 /** 405 * Find the AudioTrack with the specified id 406 * 407 * @param audioTrackId The AudioTrack id 408 * 409 * @return The AudioTrack with the specified id (null if it does not exist) 410 */ 411 public AudioTrack getAudioTrack(String audioTrackId); 412 413 /** 414 * Set the aspect ratio used in the preview and the export movie. 415 * 416 * The default aspect ratio is ASPECTRATIO_16_9 (16:9). 417 * 418 * @param aspectRatio to apply. If aspectRatio is the same as the current 419 * aspect ratio, then this function just returns. The supported 420 * aspect ratio are defined in the MediaProperties class for 421 * example: ASPECTRATIO_16_9 422 * 423 * @throws IllegalStateException if a preview or an export is in progress 424 * @throws IllegalArgumentException if aspect ratio is not supported 425 */ 426 public void setAspectRatio(int aspectRatio); 427 428 /** 429 * Get current aspect ratio. 430 * 431 * @return The aspect ratio as described in MediaProperties 432 */ 433 public int getAspectRatio(); 434 435 /** 436 * Get the preview (and output movie) duration. 437 * 438 * @return The duration of the preview (and output movie) 439 */ 440 public long getDuration(); 441 442 /** 443 * Render a frame according to the preview aspect ratio and activating all 444 * storyboard items relative to the specified time. 445 * 446 * @param surfaceHolder SurfaceHolder used by the application 447 * @param timeMs time corresponding to the frame to display 448 * 449 * @return The accurate time stamp of the frame that is rendered 450 * . 451 * @throws IllegalStateException if a preview or an export is already 452 * in progress 453 * @throws IllegalArgumentException if time is negative or beyond the 454 * preview duration 455 */ 456 public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs); 457 458 /** 459 * This method must be called after the aspect ratio of the project changes 460 * and before startPreview is called. Note that this method may block for 461 * an extensive period of time. 462 */ 463 public void generatePreview(); 464 465 /** 466 * Start the preview of all the storyboard items applied on all MediaItems 467 * This method does not block (does not wait for the preview to complete). 468 * The PreviewProgressListener allows to track the progress at the time 469 * interval determined by the callbackAfterFrameCount parameter. The 470 * SurfaceHolder has to be created and ready for use before calling this 471 * method. The method is a no-op if there are no MediaItems in the 472 * storyboard. 473 * 474 * @param surfaceHolder SurfaceHolder where the preview is rendered. 475 * @param fromMs The time (relative to the timeline) at which the preview 476 * will start 477 * @param toMs The time (relative to the timeline) at which the preview will 478 * stop. Use -1 to play to the end of the timeline 479 * @param loop true if the preview should be looped once it reaches the end 480 * @param callbackAfterFrameCount The listener interface should be invoked 481 * after the number of frames specified by this parameter. 482 * @param listener The listener which will be notified of the preview 483 * progress 484 * @throws IllegalArgumentException if fromMs is beyond the preview duration 485 * @throws IllegalStateException if a preview or an export is already in 486 * progress 487 */ 488 public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs, boolean loop, 489 int callbackAfterFrameCount, PreviewProgressListener listener); 490 491 /** 492 * Stop the current preview. This method blocks until ongoing preview is 493 * stopped. Ignored if there is no preview running. 494 * 495 * @return The accurate current time when stop is effective expressed in 496 * milliseconds 497 */ 498 public long stopPreview(); 499} 500