VideoEditor.java revision a573b563b3c6a3edc60393543dc9adb7ade4f188
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 17 18package android.media.videoeditor; 19 20import java.io.IOException; 21import java.util.List; 22import java.util.concurrent.CancellationException; 23import android.graphics.Bitmap; 24import android.graphics.Color; 25import android.graphics.Canvas; 26import android.graphics.Paint; 27import android.graphics.Rect; 28import android.view.SurfaceHolder; 29 30/** 31 * This is the interface implemented by classes which provide video editing 32 * functionality. The VideoEditor implementation class manages all input and 33 * output files. Unless specifically mentioned, methods are blocking. A typical 34 * editing session may consist of the following sequence of operations: 35 * 36 * <ul> 37 * <li>Add a set of MediaItems</li> 38 * <li>Apply a set of Transitions between MediaItems</li> 39 * <li>Add Effects and Overlays to media items</li> 40 * <li>Preview the movie at any time</li> 41 * <li>Save the VideoEditor implementation class internal state</li> 42 * <li>Release the VideoEditor implementation class instance by invoking 43 * {@link #release()} 44 * </ul> 45 * The internal VideoEditor state consists of the following elements: 46 * <ul> 47 * <li>Ordered & trimmed MediaItems</li> 48 * <li>Transition video clips</li> 49 * <li>Overlays</li> 50 * <li>Effects</li> 51 * <li>Audio waveform for the background audio and MediaItems</li> 52 * <li>Project thumbnail</li> 53 * <li>Last exported movie.</li> 54 * <li>Other project specific data such as the current aspect ratio.</li> 55 * </ul> 56 * {@hide} 57 */ 58public interface VideoEditor { 59 /** 60 * The file name of the project thumbnail 61 */ 62 public static final String THUMBNAIL_FILENAME = "thumbnail.jpg"; 63 64 /** 65 * Use this value instead of the specific end of the storyboard timeline 66 * value. 67 */ 68 public final static int DURATION_OF_STORYBOARD = -1; 69 70 /** 71 * This listener interface is used by the VideoEditor to emit preview 72 * progress notifications. This callback should be invoked after the number 73 * of frames specified by 74 * {@link #startPreview(SurfaceHolder surfaceHolder, long fromMs, 75 * int callbackAfterFrameCount, PreviewProgressListener listener)} 76 */ 77 public interface PreviewProgressListener { 78 /** 79 * This method notifies the listener of the current time position while 80 * previewing a project. 81 * 82 * @param videoEditor The VideoEditor instance 83 * @param timeMs The current preview position (expressed in milliseconds 84 * since the beginning of the storyboard timeline). 85 * @param overlayData The overlay data (null if the overlay data 86 * is unchanged) 87 */ 88 public void onProgress(VideoEditor videoEditor, long timeMs, 89 OverlayData overlayData); 90 /** 91 * This method notifies the listener when the preview is started 92 * previewing a project. 93 * 94 * @param videoEditor The VideoEditor instance 95 */ 96 public void onStart(VideoEditor videoEditor); 97 98 /** 99 * This method notifies the listener when the preview is stopped 100 * previewing a project. 101 * 102 * @param videoEditor The VideoEditor instance 103 */ 104 public void onStop(VideoEditor videoEditor); 105 } 106 107 /** 108 * This listener interface is used by the VideoEditor to emit export status 109 * notifications. 110 * {@link #export(String filename, ExportProgressListener listener, 111 * int height, int bitrate)} 112 */ 113 public interface ExportProgressListener { 114 /** 115 * This method notifies the listener of the progress status of a export 116 * operation. 117 * 118 * @param videoEditor The VideoEditor instance 119 * @param filename The name of the file which is in the process of being 120 * exported. 121 * @param progress The progress in %. At the beginning of the export, 122 * this value is set to 0; at the end, the value is set to 100. 123 */ 124 public void onProgress(VideoEditor videoEditor, String filename, 125 int progress); 126 } 127 128 public interface MediaProcessingProgressListener { 129 /** 130 * Values used for the action parameter 131 */ 132 public static final int ACTION_ENCODE = 1; 133 public static final int ACTION_DECODE = 2; 134 135 /** 136 * This method notifies the listener of the progress status of 137 * processing a media object such as a Transition, AudioTrack & Kenburns 138 * This method may be called maximum 100 times for one operation. 139 * 140 * @param object The object that is being processed such as a Transition 141 * or AudioTrack 142 * @param action The type of processing being performed 143 * @param progress The progress in %. At the beginning of the operation, 144 * this value is set to 0; at the end, the value is set to 100. 145 */ 146 public void onProgress(Object item, int action, int progress); 147 } 148 149 /** 150 * The overlay data 151 */ 152 public static final class OverlayData { 153 // Instance variables 154 private Bitmap mOverlayBitmap; 155 private int mRenderingMode; 156 private boolean mClear; 157 private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG); 158 159 /** 160 * Default constructor 161 */ 162 public OverlayData() { 163 mOverlayBitmap = null; 164 mRenderingMode = MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS; 165 mClear = false; 166 } 167 168 /** 169 * Releases the bitmap 170 */ 171 public void release() { 172 if (mOverlayBitmap != null) { 173 mOverlayBitmap.recycle(); 174 mOverlayBitmap = null; 175 } 176 } 177 178 /** 179 * Check if the overlay needs to be rendered 180 * 181 * @return true if rendering is needed 182 */ 183 public boolean needsRendering() { 184 return (mClear || mOverlayBitmap != null); 185 } 186 187 /** 188 * Store the overlay data 189 * 190 * @param overlayBitmap The overlay bitmap 191 * @param renderingMode The rendering mode 192 */ 193 void set(Bitmap overlayBitmap, int renderingMode) { 194 mOverlayBitmap = overlayBitmap; 195 mRenderingMode = renderingMode; 196 mClear = false; 197 } 198 199 /** 200 * Clear the overlay 201 */ 202 void setClear() { 203 mClear = true; 204 } 205 206 /** 207 * Render the overlay by either clearing it or by 208 * rendering the overlay bitmap with the specified 209 * rendering mode 210 * 211 * @param destBitmap The destination bitmap 212 */ 213 public void renderOverlay(Bitmap destBitmap) { 214 if (mClear) { 215 destBitmap.eraseColor(Color.TRANSPARENT); 216 } else if (mOverlayBitmap != null) { 217 final Canvas overlayCanvas = new Canvas(destBitmap); 218 final Rect destRect; 219 final Rect srcRect; 220 switch (mRenderingMode) { 221 case MediaArtistNativeHelper.MediaRendering.RESIZING: { 222 destRect = new Rect(0, 0, overlayCanvas.getWidth(), 223 overlayCanvas.getHeight()); 224 srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(), 225 mOverlayBitmap.getHeight()); 226 break; 227 } 228 229 case MediaArtistNativeHelper.MediaRendering.BLACK_BORDERS: { 230 int left, right, top, bottom; 231 float aROverlayImage, aRCanvas; 232 aROverlayImage = (float)(mOverlayBitmap.getWidth()) / 233 (float)(mOverlayBitmap.getHeight()); 234 235 aRCanvas = (float)(overlayCanvas.getWidth()) / 236 (float)(overlayCanvas.getHeight()); 237 238 if (aROverlayImage > aRCanvas) { 239 int newHeight = ((overlayCanvas.getWidth() * mOverlayBitmap.getHeight()) 240 / mOverlayBitmap.getWidth()); 241 left = 0; 242 top = (overlayCanvas.getHeight() - newHeight) / 2; 243 right = overlayCanvas.getWidth(); 244 bottom = top + newHeight; 245 } else { 246 int newWidth = ((overlayCanvas.getHeight() * mOverlayBitmap.getWidth()) 247 / mOverlayBitmap.getHeight()); 248 left = (overlayCanvas.getWidth() - newWidth) / 2; 249 top = 0; 250 right = left + newWidth; 251 bottom = overlayCanvas.getHeight(); 252 } 253 254 destRect = new Rect(left, top, right, bottom); 255 srcRect = new Rect(0, 0, mOverlayBitmap.getWidth(), mOverlayBitmap.getHeight()); 256 break; 257 } 258 259 case MediaArtistNativeHelper.MediaRendering.CROPPING: { 260 // Calculate the source rect 261 int left, right, top, bottom; 262 float aROverlayImage, aRCanvas; 263 aROverlayImage = (float)(mOverlayBitmap.getWidth()) / 264 (float)(mOverlayBitmap.getHeight()); 265 aRCanvas = (float)(overlayCanvas.getWidth()) / 266 (float)(overlayCanvas.getHeight()); 267 if (aROverlayImage < aRCanvas) { 268 int newHeight = ((mOverlayBitmap.getWidth() * overlayCanvas.getHeight()) 269 / overlayCanvas.getWidth()); 270 271 left = 0; 272 top = (mOverlayBitmap.getHeight() - newHeight) / 2; 273 right = mOverlayBitmap.getWidth(); 274 bottom = top + newHeight; 275 } else { 276 int newWidth = ((mOverlayBitmap.getHeight() * overlayCanvas.getWidth()) 277 / overlayCanvas.getHeight()); 278 left = (mOverlayBitmap.getWidth() - newWidth) / 2; 279 top = 0; 280 right = left + newWidth; 281 bottom = mOverlayBitmap.getHeight(); 282 } 283 284 srcRect = new Rect(left, top, right, bottom); 285 destRect = new Rect(0, 0, overlayCanvas.getWidth(), overlayCanvas.getHeight()); 286 break; 287 } 288 289 default: { 290 throw new IllegalStateException("Rendering mode: " + mRenderingMode); 291 } 292 } 293 294 destBitmap.eraseColor(Color.TRANSPARENT); 295 overlayCanvas.drawBitmap(mOverlayBitmap, srcRect, destRect, sResizePaint); 296 297 mOverlayBitmap.recycle(); 298 } 299 } 300 } 301 302 /** 303 * @return The path where the VideoEditor stores all files related to the 304 * project 305 */ 306 public String getPath(); 307 308 /** 309 * This method releases all in-memory resources used by the VideoEditor 310 * instance. All pending operations such as preview, export and extract 311 * audio waveform must be canceled. 312 */ 313 public void release(); 314 315 /** 316 * Persist the current internal state of VideoEditor to the project path. 317 * The VideoEditor state may be restored by invoking the 318 * {@link VideoEditorFactory#load(String)} method. This method does not 319 * release the internal in-memory state of the VideoEditor. To release 320 * the in-memory state of the VideoEditor the {@link #release()} method 321 * must be invoked. 322 * 323 * Pending transition generations must be allowed to complete before the 324 * state is saved. 325 * Pending audio waveform generations must be allowed to complete. 326 * Pending export operations must be allowed to continue. 327 * 328 * @throws IOException if the internal state cannot be saved to project file 329 */ 330 public void save() throws IOException; 331 332 /** 333 * Create the output movie based on all media items added and the applied 334 * storyboard items. This method can take a long time to execute and is 335 * blocking. The application will receive progress notifications via the 336 * ExportProgressListener. Specific implementations may not support multiple 337 * simultaneous export operations. Note that invoking methods which would 338 * change the contents of the output movie throw an IllegalStateException 339 * while an export operation is pending. 340 * 341 * The audio and video codecs are automatically selected by the underlying 342 * implementation. 343 * 344 * @param filename The output file name (including the full path) 345 * @param height The height of the output video file. The supported values 346 * for height are described in the MediaProperties class, for 347 * example: HEIGHT_480. The width will be automatically computed 348 * according to the aspect ratio provided by 349 * {@link #setAspectRatio(int)} 350 * @param bitrate The bitrate of the output video file. This is approximate 351 * value for the output movie. Supported bitrate values are 352 * described in the MediaProperties class for example: BITRATE_384K 353 * @param listener The listener for progress notifications. Use null if 354 * export progress notifications are not needed. 355 * 356 * @throws IllegalArgumentException if height or bitrate are not supported 357 * or if the audio or video codecs are not supported 358 * @throws IOException if output file cannot be created 359 * @throws IllegalStateException if a preview or an export is in progress or 360 * if no MediaItem has been added 361 * @throws CancellationException if export is canceled by calling 362 * {@link #cancelExport()} 363 * @throws UnsupportOperationException if multiple simultaneous export() are 364 * not allowed 365 */ 366 public void export(String filename, int height, int bitrate, 367 ExportProgressListener listener) 368 throws IOException; 369 370 /** 371 * Create the output movie based on all media items added and the applied 372 * storyboard items. This method can take a long time to execute and is 373 * blocking. The application will receive progress notifications via the 374 * ExportProgressListener. Specific implementations may not support multiple 375 * simultaneous export operations. Note that invoking methods which would 376 * change the contents of the output movie throw an IllegalStateException 377 * while an export operation is pending. 378 * 379 * @param filename The output file name (including the full path) 380 * @param height The height of the output video file. The supported values 381 * for height are described in the MediaProperties class, for 382 * example: HEIGHT_480. The width will be automatically computed 383 * according to the aspect ratio provided by 384 * {@link #setAspectRatio(int)} 385 * @param bitrate The bitrate of the output video file. This is approximate 386 * value for the output movie. Supported bitrate values are 387 * described in the MediaProperties class for example: BITRATE_384K 388 * @param audioCodec The audio codec to be used for the export. The audio 389 * codec values are defined in the MediaProperties class (e.g. 390 * ACODEC_AAC_LC). Note that not all audio codec types are 391 * supported for export purposes. 392 * @param videoCodec The video codec to be used for the export. The video 393 * codec values are defined in the MediaProperties class (e.g. 394 * VCODEC_H264BP). Note that not all video codec types are 395 * supported for export purposes. 396 * @param listener The listener for progress notifications. Use null if 397 * export progress notifications are not needed. 398 * 399 * @throws IllegalArgumentException if height or bitrate are not supported 400 * or if the audio or video codecs are not supported 401 * @throws IOException if output file cannot be created 402 * @throws IllegalStateException if a preview or an export is in progress or 403 * if no MediaItem has been added 404 * @throws CancellationException if export is cancelled by calling 405 * {@link #cancelExport()} 406 * @throws UnsupportOperationException if multiple simultaneous export() are 407 * not allowed 408 */ 409 public void export(String filename, int height, int bitrate, int audioCodec, 410 int videoCodec, ExportProgressListener listener) 411 throws IOException; 412 413 /** 414 * Cancel the running export operation. This method blocks until the export 415 * is cancelled and the exported file (if any) is deleted. If the export 416 * completed by the time this method is invoked, the export file will be 417 * deleted. 418 * 419 * @param filename The filename which identifies the export operation to be 420 * canceled. 421 **/ 422 public void cancelExport(String filename); 423 424 /** 425 * Add a media item at the end of the storyboard. 426 * 427 * @param mediaItem The media item object to add 428 * 429 * @throws IllegalStateException if a preview or an export is in progress or 430 * if the media item id is not unique across all the media items 431 * added. 432 */ 433 public void addMediaItem(MediaItem mediaItem); 434 435 /** 436 * Insert a media item after the media item with the specified id. 437 * 438 * @param mediaItem The media item object to insert 439 * @param afterMediaItemId Insert the mediaItem after the media item 440 * identified by this id. If this parameter is null, the media 441 * item is inserted at the beginning of the timeline. 442 * 443 * @throws IllegalStateException if a preview or an export is in progress 444 * @throws IllegalArgumentException if media item with the specified id does 445 * not exist (null is a valid value) or if the media item id is 446 * not unique across all the media items added. 447 */ 448 public void insertMediaItem(MediaItem mediaItem, String afterMediaItemId); 449 450 /** 451 * Move a media item after the media item with the specified id. 452 * 453 * Note: The project thumbnail is regenerated if the media item is or 454 * becomes the first media item in the storyboard timeline. 455 * 456 * @param mediaItemId The id of the media item to move 457 * @param afterMediaItemId Move the media item identified by mediaItemId 458 * after the media item identified by this parameter. If this 459 * parameter is null, the media item is moved at the beginning of 460 * the timeline. 461 * 462 * @throws IllegalStateException if a preview or an export is in progress 463 * @throws IllegalArgumentException if one of media item ids is invalid 464 * (null is a valid value) 465 */ 466 public void moveMediaItem(String mediaItemId, String afterMediaItemId); 467 468 /** 469 * Remove the media item with the specified id. If there are transitions 470 * before or after this media item, then this/these transition(s) are 471 * removed from the storyboard. If the extraction of the audio waveform is 472 * in progress, the extraction is canceled and the file is deleted. 473 * 474 * Effects and overlays associated with the media item will also be removed. 475 * 476 * Note: The project thumbnail is regenerated if the media item which is 477 * removed is the first media item in the storyboard or if the media item is 478 * the only one in the storyboard. If the media item is the only one in the 479 * storyboard, the project thumbnail will be set to a black frame and the 480 * aspect ratio will revert to the default aspect ratio and this method is 481 * equivalent to removeAllMediaItems() in this case. 482 * 483 * @param mediaItemId The unique id of the media item to be removed 484 * 485 * @return The media item that was removed 486 * 487 * @throws IllegalStateException if a preview or an export is in progress 488 * @throws IllegalArgumentException if media item with the specified id does 489 * not exist 490 */ 491 public MediaItem removeMediaItem(String mediaItemId); 492 493 /** 494 * Remove all media items in the storyboard. All effects, overlays and all 495 * transitions are also removed. 496 * 497 * Note: The project thumbnail will be set to a black frame and the aspect 498 * ratio will revert to the default aspect ratio. 499 * 500 * @throws IllegalStateException if a preview or an export is in progress 501 */ 502 public void removeAllMediaItems(); 503 504 /** 505 * Get the list of media items in the order in which it they appear in the 506 * storyboard timeline. 507 * 508 * Note that if any media item source files are no longer 509 * accessible, this method will still provide the full list of media items. 510 * 511 * @return The list of media items. If no media item exist an empty list 512 * will be returned. 513 */ 514 public List<MediaItem> getAllMediaItems(); 515 516 /** 517 * Find the media item with the specified id 518 * 519 * @param mediaItemId The media item id 520 * 521 * @return The media item with the specified id (null if it does not exist) 522 */ 523 public MediaItem getMediaItem(String mediaItemId); 524 525 /** 526 * Add a transition between the media items specified by the transition. 527 * If a transition existed at the same position it is invalidated and then 528 * the transition is replaced. Note that the new transition video clip is 529 * not automatically generated by this method. The 530 * {@link Transition#generate()} method must be invoked to generate 531 * the transition video clip. 532 * 533 * Note that the TransitionAtEnd and TransitionAtStart are special kinds 534 * that can not be applied between two media items. 535 * 536 * A crossfade audio transition will be automatically applied regardless of 537 * the video transition. 538 * 539 * @param transition The transition to apply 540 * 541 * @throws IllegalStateException if a preview or an export is in progress 542 * @throws IllegalArgumentException if the transition duration is larger 543 * than the smallest duration of the two media item files or if 544 * the two media items specified in the transition are not 545 * adjacent 546 */ 547 public void addTransition(Transition transition); 548 549 /** 550 * Remove the transition with the specified id. 551 * 552 * @param transitionId The id of the transition to be removed 553 * 554 * @return The transition that was removed 555 * 556 * @throws IllegalStateException if a preview or an export is in progress 557 * @throws IllegalArgumentException if transition with the specified id does 558 * not exist 559 */ 560 public Transition removeTransition(String transitionId); 561 562 /** 563 * Get the list of transitions 564 * 565 * @return The list of transitions. If no transitions exist an empty list 566 * will be returned. 567 */ 568 public List<Transition> getAllTransitions(); 569 570 /** 571 * Find the transition with the specified transition id. 572 * 573 * @param transitionId The transition id 574 * 575 * @return The transition 576 */ 577 public Transition getTransition(String transitionId); 578 579 /** 580 * Add the specified AudioTrack to the storyboard. Note: Specific 581 * implementations may support a limited number of audio tracks (e.g. only 582 * one audio track) 583 * 584 * @param audioTrack The AudioTrack to add 585 * 586 * @throws UnsupportedOperationException if the implementation supports a 587 * limited number of audio tracks. 588 * @throws IllegalArgumentException if media item is not unique across all 589 * the audio tracks already added. 590 */ 591 public void addAudioTrack(AudioTrack audioTrack); 592 593 /** 594 * Insert an audio track after the audio track with the specified id. Use 595 * addAudioTrack to add an audio track at the end of the storyboard 596 * timeline. 597 * 598 * @param audioTrack The audio track object to insert 599 * @param afterAudioTrackId Insert the audio track after the audio track 600 * identified by this parameter. If this parameter is null the 601 * audio track is added at the beginning of the timeline. 602 * 603 * @throws IllegalStateException if a preview or an export is in progress 604 * @throws IllegalArgumentException if media item with the specified id does 605 * not exist (null is a valid value). if media item is not unique 606 * across all the audio tracks already added. 607 * @throws UnsupportedOperationException if the implementation supports a 608 * limited number of audio tracks 609 */ 610 public void insertAudioTrack(AudioTrack audioTrack, String afterAudioTrackId); 611 612 /** 613 * Move an AudioTrack after the AudioTrack with the specified id. 614 * 615 * @param audioTrackId The id of the AudioTrack to move 616 * @param afterAudioTrackId Move the AudioTrack identified by audioTrackId 617 * after the AudioTrack identified by this parameter. If this 618 * parameter is null the audio track is added at the beginning of 619 * the timeline. 620 * 621 * @throws IllegalStateException if a preview or an export is in progress 622 * @throws IllegalArgumentException if one of media item ids is invalid 623 * (null is a valid value) 624 */ 625 public void moveAudioTrack(String audioTrackId, String afterAudioTrackId); 626 627 /** 628 * Remove the audio track with the specified id. If the extraction of the 629 * audio waveform is in progress, the extraction is canceled and the file is 630 * deleted. 631 * 632 * @param audioTrackId The id of the audio track to be removed 633 * 634 * @return The audio track that was removed 635 * @throws IllegalStateException if a preview or an export is in progress 636 */ 637 public AudioTrack removeAudioTrack(String audioTrackId); 638 639 /** 640 * Get the list of AudioTracks in order in which they appear in the 641 * storyboard. 642 * 643 * Note that if any AudioTrack source files are not accessible anymore, 644 * this method will still provide the full list of audio tracks. 645 * 646 * @return The list of AudioTracks. If no audio tracks exist an empty list 647 * will be returned. 648 */ 649 public List<AudioTrack> getAllAudioTracks(); 650 651 /** 652 * Find the AudioTrack with the specified id 653 * 654 * @param audioTrackId The AudioTrack id 655 * 656 * @return The AudioTrack with the specified id (null if it does not exist) 657 */ 658 public AudioTrack getAudioTrack(String audioTrackId); 659 660 /** 661 * Set the aspect ratio used in the preview and the export movie. 662 * 663 * The default aspect ratio is ASPECTRATIO_16_9 (16:9). 664 * 665 * @param aspectRatio to apply. If aspectRatio is the same as the current 666 * aspect ratio, then this function just returns. The supported 667 * aspect ratio are defined in the MediaProperties class for 668 * example: ASPECTRATIO_16_9 669 * 670 * @throws IllegalStateException if a preview or an export is in progress 671 * @throws IllegalArgumentException if aspect ratio is not supported 672 */ 673 public void setAspectRatio(int aspectRatio); 674 675 /** 676 * Get current aspect ratio. 677 * 678 * @return The aspect ratio as described in MediaProperties 679 */ 680 public int getAspectRatio(); 681 682 /** 683 * Get the preview (and output movie) duration. 684 * 685 * @return The duration of the preview (and output movie) 686 */ 687 public long getDuration(); 688 689 /** 690 * Render a frame according to the preview aspect ratio and activating all 691 * storyboard items relative to the specified time. 692 * 693 * @param surfaceHolder SurfaceHolder used by the application 694 * @param timeMs time corresponding to the frame to display 695 * @param overlayData The overlay data 696 * 697 * @return The accurate time stamp of the frame that is rendered. 698 * 699 * @throws IllegalStateException if a preview or an export is already in 700 * progress 701 * @throws IllegalArgumentException if time is negative or beyond the 702 * preview duration 703 */ 704 public long renderPreviewFrame(SurfaceHolder surfaceHolder, long timeMs, 705 OverlayData overlayData); 706 707 /** 708 * This method must be called after any changes made to the storyboard 709 * and before startPreview is called. Note that this method may block for an 710 * extensive period of time. 711 */ 712 public void generatePreview(MediaProcessingProgressListener listener); 713 714 /** 715 * Start the preview of all the storyboard items applied on all MediaItems 716 * This method does not block (does not wait for the preview to complete). 717 * The PreviewProgressListener allows to track the progress at the time 718 * interval determined by the callbackAfterFrameCount parameter. The 719 * SurfaceHolder has to be created and ready for use before calling this 720 * method. The method is a no-op if there are no MediaItems in the 721 * storyboard. 722 * 723 * @param surfaceHolder SurfaceHolder where the preview is rendered. 724 * @param fromMs The time (relative to the timeline) at which the preview 725 * will start 726 * @param toMs The time (relative to the timeline) at which the preview will 727 * stop. Use -1 to play to the end of the timeline 728 * @param loop true if the preview should be looped once it reaches the end 729 * @param callbackAfterFrameCount The listener interface should be invoked 730 * after the number of frames specified by this parameter. 731 * @param listener The listener which will be notified of the preview 732 * progress 733 * 734 * @throws IllegalArgumentException if fromMs is beyond the preview duration 735 * @throws IllegalStateException if a preview or an export is already in 736 * progress 737 */ 738 public void startPreview(SurfaceHolder surfaceHolder, long fromMs, long toMs, 739 boolean loop,int callbackAfterFrameCount, 740 PreviewProgressListener listener); 741 742 /** 743 * Stop the current preview. This method blocks until ongoing preview is 744 * stopped. Ignored if there is no preview running. 745 * 746 * @return The accurate current time when stop is effective expressed in 747 * milliseconds 748 */ 749 public long stopPreview(); 750 751 /** 752 * Clears the preview surface 753 * 754 * @param surfaceHolder SurfaceHolder where the preview is rendered 755 * and needs to be cleared. 756 */ 757 public void clearSurface(SurfaceHolder surfaceHolder); 758} 759