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