VideoEditor.java revision c006e8ef64bbfd47a9ecd4cfd708362e40b0d337
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 * The audio and video codecs are automatically selected by the underlying 138 * implementation. 139 * 140 * @param filename The output file name (including the full path) 141 * @param height The height of the output video file. The supported values 142 * for height are described in the MediaProperties class, for 143 * example: HEIGHT_480. The width will be automatically computed 144 * according to the aspect ratio provided by 145 * {@link #setAspectRatio(int)} 146 * @param bitrate The bitrate of the output video file. This is approximate 147 * value for the output movie. Supported bitrate values are 148 * described in the MediaProperties class for example: 149 * BITRATE_384K 150 * @param listener The listener for progress notifications. Use null if 151 * export progress notifications are not needed. 152 * @throws IllegalArgumentException if height or bitrate are not supported 153 * or if the audio or video codecs are not supported 154 * @throws IOException if output file cannot be created 155 * @throws IllegalStateException if a preview or an export is in progress or 156 * if no MediaItem has been added 157 * @throws CancellationException if export is canceled by calling 158 * {@link #cancelExport()} 159 * @throws UnsupportOperationException if multiple simultaneous export() are 160 * not allowed 161 */ 162 public void export(String filename, int height, int bitrate, ExportProgressListener listener) 163 throws IOException; 164 165 /** 166 * Create the output movie based on all media items added and the applied 167 * storyboard items. This method can take a long time to execute and is 168 * blocking. The application will receive progress notifications via the 169 * ExportProgressListener. Specific implementations may not support multiple 170 * simultaneous export operations. Note that invoking methods which would 171 * change the contents of the output movie throw an IllegalStateException 172 * while an export operation is pending. 173 * 174 * @param filename The output file name (including the full path) 175 * @param height The height of the output video file. The supported values 176 * for height are described in the MediaProperties class, for 177 * example: HEIGHT_480. The width will be automatically computed 178 * according to the aspect ratio provided by 179 * {@link #setAspectRatio(int)} 180 * @param bitrate The bitrate of the output video file. This is approximate 181 * value for the output movie. Supported bitrate values are 182 * described in the MediaProperties class for example: 183 * BITRATE_384K 184 * @param audioCodec The audio codec to be used for the export. The audio 185 * codec values are defined in the MediaProperties class (e.g. 186 * ACODEC_AAC_LC). Note that not all audio codec types are 187 * supported for export purposes. 188 * @param videoCodec The video codec to be used for the export. The video 189 * codec values are defined in the MediaProperties class (e.g. 190 * VCODEC_H264BP). Note that not all video codec types are 191 * supported for export purposes. 192 * @param listener The listener for progress notifications. Use null if 193 * export progress notifications are not needed. 194 * @throws IllegalArgumentException if height or bitrate are not supported 195 * or if the audio or video codecs are not supported 196 * @throws IOException if output file cannot be created 197 * @throws IllegalStateException if a preview or an export is in progress or 198 * if no MediaItem has been added 199 * @throws CancellationException if export is canceled by calling 200 * {@link #cancelExport()} 201 * @throws UnsupportOperationException if multiple simultaneous export() are 202 * not allowed 203 */ 204 public void export(String filename, int height, int bitrate, int audioCodec, int videoCodec, 205 ExportProgressListener listener) throws IOException; 206 207 /** 208 * Cancel the running export operation. This method blocks until the 209 * export is canceled and the exported file (if any) is deleted. If the 210 * export completed by the time this method is invoked, the export file 211 * will be deleted. 212 * 213 * @param filename The filename which identifies the export operation to be 214 * canceled. 215 **/ 216 public void cancelExport(String filename); 217 218 /** 219 * Add a media item at the end of the storyboard. 220 * 221 * @param mediaItem The media item object to add 222 * @throws IllegalStateException if a preview or an export is in progress or 223 * if the media item id is not unique across all the media items 224 * added. 225 */ 226 public void addMediaItem(MediaItem mediaItem); 227 228 /** 229 * Insert a media item after the media item with the specified id. 230 * 231 * @param mediaItem The media item object to insert 232 * @param afterMediaItemId Insert the mediaItem after the media item 233 * identified by this id. If this parameter is null, the media 234 * item is inserted at the beginning of the timeline. 235 * 236 * @throws IllegalStateException if a preview or an export is in progress 237 * @throws IllegalArgumentException if media item with the specified id does 238 * not exist (null is a valid value) or if the media item id is 239 * not unique across all the media items added. 240 */ 241 public void insertMediaItem(MediaItem mediaItem, String afterMediaItemId); 242 243 /** 244 * Move a media item after the media item with the specified id. 245 * 246 * Note: The project thumbnail is regenerated if the media item is or 247 * becomes the first media item in the storyboard timeline. 248 * 249 * @param mediaItemId The id of the media item to move 250 * @param afterMediaItemId Move the media item identified by mediaItemId after 251 * the media item identified by this parameter. If this parameter 252 * is null, the media item is moved at the beginning of the 253 * timeline. 254 * 255 * @throws IllegalStateException if a preview or an export is in progress 256 * @throws IllegalArgumentException if one of media item ids is invalid 257 * (null is a valid value) 258 */ 259 public void moveMediaItem(String mediaItemId, String afterMediaItemId); 260 261 /** 262 * Remove the media item with the specified id. If there are transitions 263 * before or after this media item, then this/these transition(s) are 264 * removed from the storyboard. If the extraction of the audio waveform is 265 * in progress, the extraction is canceled and the file is deleted. 266 * 267 * Effects and overlays associated with the media item will also be 268 * removed. 269 * 270 * Note: The project thumbnail is regenerated if the media item which 271 * is removed is the first media item in the storyboard or if the 272 * media item is the only one in the storyboard. If the 273 * media item is the only one in the storyboard, the project thumbnail 274 * will be set to a black frame and the aspect ratio will revert to the 275 * default aspect ratio, and this method is equivalent to 276 * removeAllMediaItems() in this case. 277 * 278 * @param mediaItemId The unique id of the media item to be removed 279 * 280 * @return The media item that was removed 281 * 282 * @throws IllegalStateException if a preview or an export is in progress 283 * @throws IllegalArgumentException if media item with the specified id 284 * does not exist 285 */ 286 public MediaItem removeMediaItem(String mediaItemId); 287 288 /** 289 * Remove all media items in the storyboard. All effects, overlays and all 290 * transitions are also removed. 291 * 292 * Note: The project thumbnail will be set to a black frame and the aspect 293 * ratio will revert to the default aspect ratio. 294 * 295 * @throws IllegalStateException if a preview or an export is in progress 296 */ 297 public void removeAllMediaItems(); 298 299 /** 300 * Get the list of media items in the order in which it they appear in the 301 * storyboard timeline. 302 * 303 * Note that if any media item source files are no longer 304 * accessible, this method will still provide the full list of media items. 305 * 306 * @return The list of media items. If no media item exist an empty list 307 * will be returned. 308 */ 309 public List<MediaItem> getAllMediaItems(); 310 311 /** 312 * Find the media item with the specified id 313 * 314 * @param mediaItemId The media item id 315 * 316 * @return The media item with the specified id (null if it does not exist) 317 */ 318 public MediaItem getMediaItem(String mediaItemId); 319 320 /** 321 * Add a transition between the media items specified by the transition. 322 * If a transition existed at the same position it is invalidated and then 323 * the transition is replaced. Note that the new transition video clip is 324 * not automatically generated by this method. The 325 * {@link Transition#generate()} method must be invoked to generate 326 * the transition video clip. 327 * 328 * Note that the TransitionAtEnd and TransitionAtStart are special kinds 329 * that can not be applied between two media items. 330 * 331 * A crossfade audio transition will be automatically applied regardless of 332 * the video transition. 333 * 334 * @param transition The transition to apply 335 * 336 * @throws IllegalStateException if a preview or an export is in progress 337 * @throws IllegalArgumentException if the transition duration is larger 338 * than the smallest duration of the two media item files or 339 * if the two media items specified in the transition are not 340 * adjacent 341 */ 342 public void addTransition(Transition transition); 343 344 /** 345 * Remove the transition with the specified id. 346 * 347 * @param transitionId The id of the transition to be removed 348 * 349 * @return The transition that was removed 350 * @throws IllegalStateException if a preview or an export is in progress 351 * @throws IllegalArgumentException if transition with the specified id does 352 * not exist 353 */ 354 public Transition removeTransition(String transitionId); 355 356 /** 357 * Get the list of transitions 358 * 359 * @return The list of transitions. If no transitions exist an empty list 360 * will be returned. 361 */ 362 public List<Transition> getAllTransitions(); 363 364 /** 365 * Find the transition with the specified transition id. 366 * 367 * @param transitionId The transition id 368 * 369 * @return The transition 370 */ 371 public Transition getTransition(String transitionId); 372 373 /** 374 * Add the specified AudioTrack to the storyboard. Note: Specific 375 * implementations may support a limited number of audio tracks (e.g. only 376 * one audio track) 377 * 378 * @param audioTrack The AudioTrack to add 379 * @throws UnsupportedOperationException if the implementation supports a 380 * limited number of audio tracks. 381 * @throws IllegalArgumentException if media item is not unique across all 382 * the audio tracks already added. 383 */ 384 public void addAudioTrack(AudioTrack audioTrack); 385 386 /** 387 * Insert an audio track after the audio track with the specified id. Use 388 * addAudioTrack to add an audio track at the end of the storyboard 389 * timeline. 390 * 391 * @param audioTrack The audio track object to insert 392 * @param afterAudioTrackId Insert the audio track after the audio track 393 * identified by this parameter. If this parameter is null the 394 * audio track is added at the beginning of the timeline. 395 * @throws IllegalStateException if a preview or an export is in progress 396 * @throws IllegalArgumentException if media item with the specified id does 397 * not exist (null is a valid value). if media item is not 398 * unique across all the audio tracks already added. 399 * @throws UnsupportedOperationException if the implementation supports a 400 * limited number of audio tracks 401 */ 402 public void insertAudioTrack(AudioTrack audioTrack, String afterAudioTrackId); 403 404 /** 405 * Move an AudioTrack after the AudioTrack with the specified id. 406 * 407 * @param audioTrackId The id of the AudioTrack to move 408 * @param afterAudioTrackId Move the AudioTrack identified by audioTrackId 409 * after the AudioTrack identified by this parameter. If this 410 * parameter is null the audio track is added at the beginning of 411 * the timeline. 412 * @throws IllegalStateException if a preview or an export is in progress 413 * @throws IllegalArgumentException if one of media item ids is invalid 414 * (null is a valid value) 415 */ 416 public void moveAudioTrack(String audioTrackId, String afterAudioTrackId); 417 418 /** 419 * Remove the audio track with the specified id. If the extraction of the 420 * audio waveform is in progress, the extraction is canceled and the file is 421 * deleted. 422 * 423 * @param audioTrackId The id of the audio track to be removed 424 * 425 * @return The audio track that was removed 426 * @throws IllegalStateException if a preview or an export is in progress 427 */ 428 public AudioTrack removeAudioTrack(String audioTrackId); 429 430 /** 431 * Get the list of AudioTracks in order in which they appear in the storyboard. 432 * 433 * Note that if any AudioTrack source files are not accessible anymore, 434 * this method will still provide the full list of audio tracks. 435 * 436 * @return The list of AudioTracks. If no audio tracks exist an empty list 437 * will be returned. 438 */ 439 public List<AudioTrack> getAllAudioTracks(); 440 441 /** 442 * Find the AudioTrack with the specified id 443 * 444 * @param audioTrackId The AudioTrack id 445 * 446 * @return The AudioTrack with the specified id (null if it does not exist) 447 */ 448 public AudioTrack getAudioTrack(String audioTrackId); 449 450 /** 451 * Set the aspect ratio used in the preview and the export movie. 452 * 453 * The default aspect ratio is ASPECTRATIO_16_9 (16:9). 454 * 455 * @param aspectRatio to apply. If aspectRatio is the same as the current 456 * aspect ratio, then this function just returns. The supported 457 * aspect ratio are defined in the MediaProperties class for 458 * example: ASPECTRATIO_16_9 459 * 460 * @throws IllegalStateException if a preview or an export is in progress 461 * @throws IllegalArgumentException if aspect ratio is not supported 462 */ 463 public void setAspectRatio(int aspectRatio); 464 465 /** 466 * Get current aspect ratio. 467 * 468 * @return The aspect ratio as described in MediaProperties 469 */ 470 public int getAspectRatio(); 471 472 /** 473 * Get the preview (and output movie) duration. 474 * 475 * @return The duration of the preview (and output movie) 476 */ 477 public long getDuration(); 478 479 /** 480 * Render a frame according to the preview aspect ratio and activating all 481 * storyboard items relative to the specified time. 482 * 483 * @param surfaceHolder SurfaceHolder used by the application 484 * @param timeMs time corresponding to the frame to display 485 * 486 * @return The accurate time stamp of the frame that is rendered 487 * . 488 * @throws IllegalStateException if a preview or an export is already 489 * in progress 490 * @throws IllegalArgumentException if time is negative or beyond the 491 * preview duration 492 */ 493 public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs); 494 495 /** 496 * This method must be called after the aspect ratio of the project changes 497 * and before startPreview is called. Note that this method may block for 498 * an extensive period of time. 499 */ 500 public void generatePreview(); 501 502 /** 503 * Start the preview of all the storyboard items applied on all MediaItems 504 * This method does not block (does not wait for the preview to complete). 505 * The PreviewProgressListener allows to track the progress at the time 506 * interval determined by the callbackAfterFrameCount parameter. The 507 * SurfaceHolder has to be created and ready for use before calling this 508 * method. The method is a no-op if there are no MediaItems in the 509 * storyboard. 510 * 511 * @param surfaceHolder SurfaceHolder where the preview is rendered. 512 * @param fromMs The time (relative to the timeline) at which the preview 513 * will start 514 * @param toMs The time (relative to the timeline) at which the preview will 515 * stop. Use -1 to play to the end of the timeline 516 * @param loop true if the preview should be looped once it reaches the end 517 * @param callbackAfterFrameCount The listener interface should be invoked 518 * after the number of frames specified by this parameter. 519 * @param listener The listener which will be notified of the preview 520 * progress 521 * @throws IllegalArgumentException if fromMs is beyond the preview duration 522 * @throws IllegalStateException if a preview or an export is already in 523 * progress 524 */ 525 public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs, boolean loop, 526 int callbackAfterFrameCount, PreviewProgressListener listener); 527 528 /** 529 * Stop the current preview. This method blocks until ongoing preview is 530 * stopped. Ignored if there is no preview running. 531 * 532 * @return The accurate current time when stop is effective expressed in 533 * milliseconds 534 */ 535 public long stopPreview(); 536} 537