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