Home | History | Annotate | Download | only in service
      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 package com.android.videoeditor.service;
     18 
     19 import java.util.List;
     20 
     21 import android.media.videoeditor.Effect;
     22 import android.media.videoeditor.MediaImageItem;
     23 import android.media.videoeditor.MediaItem;
     24 import android.media.videoeditor.MediaVideoItem;
     25 import android.media.videoeditor.Overlay;
     26 import android.media.videoeditor.WaveformData;
     27 
     28 
     29 /**
     30  * This class represents a media item
     31  */
     32 public class MovieMediaItem {
     33     // The unique id of the media item
     34     private final String mUniqueId;
     35 
     36     // The transition type
     37     private final Class<?> mType;
     38 
     39     // The name of the file associated with the media item
     40     private final String mFilename;
     41 
     42     // The width and height
     43     private final int mWidth;
     44     private final int mHeight;
     45 
     46     // The aspect ratio
     47     private final int mAspectRatio;
     48 
     49     // The duration of the entire media item (ignore trim boundaries)
     50     private final long mDurationMs;
     51 
     52     // Trimming boundaries
     53     private final long mBeginBoundaryTimeMs;
     54     private final long mEndBoundaryTimeMs;
     55 
     56     // The rendering mode
     57     private int mRenderingMode;
     58 
     59     // The overlay applied to the media item
     60     private MovieOverlay mOverlay;
     61 
     62     // The effect applied to the media item
     63     private MovieEffect mEffect;
     64 
     65     // Begin and end transitions
     66     private MovieTransition mBeginTransition;
     67     private MovieTransition mEndTransition;
     68 
     69     // The audio waveform data
     70     private WaveformData mWaveformData;
     71 
     72     // Sound control
     73     private int mVolumePercent;
     74     private boolean mMuted;
     75 
     76     // Application values
     77     private long mAppBeginBoundaryTimeMs, mAppEndBoundaryTimeMs;
     78     private int mAppRenderingMode;
     79     private int mAppVolumePercent;
     80     private boolean mAppMuted;
     81 
     82     /**
     83      * Constructor
     84      *
     85      * @param mediaItem The media item
     86      */
     87     MovieMediaItem(MediaItem mediaItem) {
     88         this(mediaItem, mediaItem.getBeginTransition() != null ? new MovieTransition(
     89                 mediaItem.getBeginTransition()) : null);
     90     }
     91 
     92     /**
     93      * Constructor
     94      *
     95      * @param mediaItem The media item
     96      * @param beginTransition The transition of the previous media item
     97      */
     98     MovieMediaItem(MediaItem mediaItem, MovieTransition beginTransition) {
     99         mType = mediaItem.getClass();
    100         mUniqueId = mediaItem.getId();
    101         mFilename = mediaItem.getFilename();
    102         mAppRenderingMode = mRenderingMode = mediaItem.getRenderingMode();
    103         mAspectRatio = mediaItem.getAspectRatio();
    104         mWidth = mediaItem.getWidth();
    105         mHeight = mediaItem.getHeight();
    106 
    107         mDurationMs = mediaItem.getDuration();
    108         if (mediaItem instanceof MediaVideoItem) {
    109             final MediaVideoItem videoMediaItem = ((MediaVideoItem)mediaItem);
    110             mAppBeginBoundaryTimeMs = mBeginBoundaryTimeMs = videoMediaItem.getBoundaryBeginTime();
    111             mAppEndBoundaryTimeMs = mEndBoundaryTimeMs = videoMediaItem.getBoundaryEndTime();
    112             try {
    113                 mWaveformData = videoMediaItem.getWaveformData();
    114             } catch (Exception ex) {
    115                 mWaveformData = null;
    116             }
    117             mAppVolumePercent = mVolumePercent = videoMediaItem.getVolume();
    118             mAppMuted = mMuted = videoMediaItem.isMuted();
    119         } else {
    120             mAppBeginBoundaryTimeMs = mBeginBoundaryTimeMs = 0;
    121             mAppEndBoundaryTimeMs = mEndBoundaryTimeMs = mediaItem.getTimelineDuration();
    122             mWaveformData = null;
    123             mAppVolumePercent = mVolumePercent = 0;
    124             mAppMuted = mMuted = false;
    125         }
    126 
    127         final List<Overlay> overlays = mediaItem.getAllOverlays();
    128         for (Overlay overlay : overlays) {
    129             addOverlay(new MovieOverlay(overlay));
    130         }
    131 
    132         final List<Effect> effects = mediaItem.getAllEffects();
    133         for (Effect effect : effects) {
    134             addEffect(new MovieEffect(effect));
    135         }
    136 
    137         setBeginTransition(beginTransition);
    138 
    139         if (mediaItem.getEndTransition() != null) {
    140             setEndTransition(new MovieTransition(mediaItem.getEndTransition()));
    141         }
    142     }
    143 
    144     /**
    145      * @return true if this is an image media item
    146      */
    147     public boolean isImage() {
    148         return MediaImageItem.class.equals(mType);
    149     }
    150 
    151     /**
    152      * @return true if this is an image video clip item
    153      */
    154     public boolean isVideoClip() {
    155         return MediaVideoItem.class.equals(mType);
    156     }
    157 
    158     /**
    159      * @return The id of the media item
    160      */
    161     public String getId() {
    162         return mUniqueId;
    163     }
    164 
    165     /**
    166      * @return The media source file name
    167      */
    168     public String getFilename() {
    169         return mFilename;
    170     }
    171 
    172     /**
    173      * If aspect ratio of the MediaItem is different from the aspect ratio of
    174      * the editor then this API controls the rendering mode.
    175      *
    176      * @param renderingMode rendering mode. It is one of:
    177      *            {@link #RENDERING_MODE_BLACK_BORDER},
    178      *            {@link #RENDERING_MODE_STRETCH}
    179      */
    180     void setRenderingMode(int renderingMode) {
    181         mRenderingMode = renderingMode;
    182     }
    183 
    184     /**
    185      * @return The rendering mode
    186      */
    187     int getRenderingMode() {
    188         return mRenderingMode;
    189     }
    190 
    191     /**
    192      * If aspect ratio of the MediaItem is different from the aspect ratio of
    193      * the editor then this API controls the rendering mode.
    194      *
    195      * @param renderingMode rendering mode.
    196      */
    197     public void setAppRenderingMode(int renderingMode) {
    198         mAppRenderingMode = renderingMode;
    199     }
    200 
    201     /**
    202      * @return The rendering mode
    203      */
    204     public int getAppRenderingMode() {
    205         return mAppRenderingMode;
    206     }
    207 
    208     /**
    209      * Set the volume of this audio track as percentage of the volume in the
    210      * original audio source file.
    211      *
    212      * @param volumePercent Percentage of the volume to apply. If it is set to
    213      *            0, then volume becomes mute. It it is set to 100, then volume
    214      *            is same as original volume. It it is set to 200, then volume
    215      *            is doubled (provided that volume amplification is supported)
    216      *
    217      * @throws UnsupportedOperationException if volume amplification is
    218      *             requested and is not supported.
    219      */
    220     void setVolume(int volumePercent) {
    221         mVolumePercent = volumePercent;
    222     }
    223 
    224     /**
    225      * Get the volume of the audio track as percentage of the volume in the
    226      * original audio source file.
    227      *
    228      * @return The volume in percentage
    229      */
    230     int getVolume() {
    231         return mVolumePercent;
    232     }
    233 
    234     /**
    235      * Set the volume of this audio track as percentage of the volume in the
    236      * original audio source file.
    237      *
    238      * @param volumePercent Percentage of the volume to apply. If it is set to
    239      *            0, then volume becomes mute. It it is set to 100, then volume
    240      *            is same as original volume. It it is set to 200, then volume
    241      *            is doubled (provided that volume amplification is supported)
    242      *
    243      * @throws UnsupportedOperationException if volume amplification is
    244      *             requested and is not supported.
    245      */
    246     public void setAppVolume(int volumePercent) {
    247         mAppVolumePercent = volumePercent;
    248     }
    249 
    250     /**
    251      * Get the volume of the audio track as percentage of the volume in the
    252      * original audio source file.
    253      *
    254      * @return The volume in percentage
    255      */
    256     public int getAppVolume() {
    257         return mAppVolumePercent;
    258     }
    259 
    260     /**
    261      * @param muted true to mute the media item
    262      */
    263     void setMute(boolean muted) {
    264         mMuted = muted;
    265     }
    266 
    267     /**
    268      * @return true if the media item is muted
    269      */
    270     boolean isMuted() {
    271         return mMuted;
    272     }
    273 
    274     /**
    275      * @param muted true to mute the media item
    276      */
    277     public void setAppMute(boolean muted) {
    278         mAppMuted = muted;
    279     }
    280 
    281     /**
    282      * @return true if the media item is muted
    283      */
    284     public boolean isAppMuted() {
    285         return mAppMuted;
    286     }
    287 
    288     /**
    289      * @return The boundary begin time
    290      */
    291     long getBoundaryBeginTime() {
    292         return mBeginBoundaryTimeMs;
    293     }
    294 
    295     /**
    296      * @return The boundary end time
    297      */
    298     long getBoundaryEndTime() {
    299         return mEndBoundaryTimeMs;
    300     }
    301 
    302     /**
    303      * Sets the start and end marks for trimming a video media item.
    304      *
    305      * @param beginMs Start time in milliseconds. Set to 0 to extract from the
    306      *            beginning
    307      * @param endMs End time in milliseconds.
    308      */
    309     public void setAppExtractBoundaries(long beginMs, long endMs) {
    310         mAppBeginBoundaryTimeMs = beginMs;
    311         mAppEndBoundaryTimeMs = endMs;
    312     }
    313 
    314     /**
    315      * @return The boundary begin time
    316      */
    317     public long getAppBoundaryBeginTime() {
    318         return mAppBeginBoundaryTimeMs;
    319     }
    320 
    321     /**
    322      * @return The boundary end time
    323      */
    324     public long getAppBoundaryEndTime() {
    325         return mAppEndBoundaryTimeMs;
    326     }
    327 
    328     /**
    329      * @return The timeline duration. This is the actual duration in the
    330      *         timeline (trimmed duration)
    331      */
    332     public long getAppTimelineDuration() {
    333         return mAppEndBoundaryTimeMs - mAppBeginBoundaryTimeMs;
    334     }
    335 
    336     /**
    337      * @return The duration of the entire media item (ignore trim)
    338      */
    339     public long getDuration() {
    340         return mDurationMs;
    341     }
    342 
    343     /**
    344      * @return Get the width of the media item
    345      */
    346     public int getWidth() {
    347         return mWidth;
    348     }
    349 
    350     /**
    351      * @return Get the height of the media item
    352      */
    353     public int getHeight() {
    354         return mHeight;
    355     }
    356 
    357     /**
    358      * Get aspect ratio of the source media item.
    359      *
    360      * @return the aspect ratio as described in MediaProperties.
    361      *         MediaProperties.ASPECT_RATIO_UNDEFINED if aspect ratio is not
    362      *         supported as in MediaProperties
    363      */
    364     public int getAspectRatio() {
    365         return mAspectRatio;
    366     }
    367 
    368     /**
    369      * @param beginTransition Begin transition
    370      */
    371     void setBeginTransition(MovieTransition beginTransition) {
    372         mBeginTransition = beginTransition;
    373     }
    374 
    375     /**
    376      * @return The begin transition
    377      */
    378     public MovieTransition getBeginTransition() {
    379         return mBeginTransition;
    380     }
    381 
    382     /**
    383      * @param endTransition end transition
    384      */
    385     void setEndTransition(MovieTransition endTransition) {
    386         mEndTransition = endTransition;
    387     }
    388 
    389     /**
    390      * @return The end transition
    391      */
    392     public MovieTransition getEndTransition() {
    393         return mEndTransition;
    394     }
    395 
    396     /**
    397      * @return The overlay
    398      */
    399     public MovieOverlay getOverlay() {
    400         return mOverlay;
    401     }
    402 
    403     /**
    404      * Only one overlay is supported at this time
    405      *
    406      * @param overlay The overlay
    407      */
    408     void addOverlay(MovieOverlay overlay) {
    409         if (mOverlay != null) {
    410             throw new IllegalStateException("Overlay already set for media item: " + mUniqueId);
    411         }
    412         mOverlay = overlay;
    413     }
    414 
    415     /**
    416      * @param overlayId The overlay id
    417      */
    418     void removeOverlay(String overlayId) {
    419         if (mOverlay != null) {
    420             if (!mOverlay.getId().equals(overlayId)) {
    421                 throw new IllegalStateException("Overlay does not match: " + mOverlay.getId() + " "
    422                         + overlayId);
    423             }
    424             mOverlay = null;
    425         }
    426     }
    427 
    428     /**
    429      * @return The effect
    430      */
    431     public MovieEffect getEffect() {
    432         return mEffect;
    433     }
    434 
    435     /**
    436      * Only one effect is supported at this time
    437      *
    438      * @param effect The effect
    439      */
    440     void addEffect(MovieEffect effect) {
    441         if (mEffect != null) {
    442             throw new IllegalStateException("Effect already set for media item: " + mUniqueId);
    443         }
    444         mEffect = effect;
    445     }
    446 
    447     /**
    448      * @param effectId The effect id
    449      */
    450     void removeEffect(String effectId) {
    451         if (mEffect != null) {
    452             if (!mEffect.getId().equals(effectId)) {
    453                 throw new IllegalStateException("Effect does not match: " + mEffect.getId() + " "
    454                         + effectId);
    455             }
    456 
    457             mEffect = null;
    458         }
    459     }
    460 
    461     /**
    462      * @return waveform data
    463      */
    464     public WaveformData getWaveformData() {
    465         return mWaveformData;
    466     }
    467 
    468     /**
    469      * @param waveformData The waveform data
    470      */
    471     void setWaveformData(WaveformData waveformData) {
    472         mWaveformData = waveformData;
    473     }
    474 
    475     /*
    476      * {@inheritDoc}
    477      */
    478     @Override
    479     public boolean equals(Object object) {
    480         if (!(object instanceof MovieMediaItem)) {
    481             return false;
    482         }
    483         return mUniqueId.equals(((MovieMediaItem)object).mUniqueId);
    484     }
    485 
    486     /*
    487      * {@inheritDoc}
    488      */
    489     @Override
    490     public int hashCode() {
    491         return mUniqueId.hashCode();
    492     }
    493 }
    494