MediaVideoItem.java revision 6ea92ecabbb53a2997eb5835c11945fecc177b91
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.media.videoeditor; 18 19import java.io.IOException; 20 21import android.graphics.Bitmap; 22import android.view.SurfaceHolder; 23 24/** 25 * This class represents a video clip item on the storyboard 26 * {@hide} 27 */ 28public class MediaVideoItem extends MediaItem { 29 // Instance variables 30 private final int mWidth; 31 private final int mHeight; 32 private final int mAspectRatio; 33 private final int mFileType; 34 private final int mVideoType; 35 private final int mVideoProfile; 36 private final int mVideoBitrate; 37 private final long mDurationMs; 38 private final int mAudioBitrate; 39 private final int mFps; 40 private final int mAudioType; 41 private final int mAudioChannels; 42 private final int mAudioSamplingFrequency; 43 44 private long mBeginBoundaryTimeMs; 45 private long mEndBoundaryTimeMs; 46 private int mVolumePercentage; 47 private boolean mMuted; 48 private String mAudioWaveformFilename; 49 // The audio waveform data 50 private WaveformData mWaveformData; 51 52 /** 53 * An object of this type cannot be instantiated with a default constructor 54 */ 55 @SuppressWarnings("unused") 56 private MediaVideoItem() throws IOException { 57 this(null, null, null, RENDERING_MODE_BLACK_BORDER); 58 } 59 60 /** 61 * Constructor 62 * 63 * @param editor The video editor reference 64 * @param mediaItemId The MediaItem id 65 * @param filename The image file name 66 * @param renderingMode The rendering mode 67 * 68 * @throws IOException if the file cannot be opened for reading 69 */ 70 public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename, 71 int renderingMode) 72 throws IOException { 73 this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null); 74 } 75 76 /** 77 * Constructor 78 * 79 * @param editor The video editor reference 80 * @param mediaItemId The MediaItem id 81 * @param filename The image file name 82 * @param renderingMode The rendering mode 83 * @param beginMs Start time in milliseconds. Set to 0 to extract from the 84 * beginning 85 * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to 86 * extract until the end 87 * @param volumePercent in %/. 100% means no change; 50% means half value, 200% 88 * means double, 0% means silent. 89 * @param muted true if the audio is muted 90 * @param audioWaveformFilename The name of the audio waveform file 91 * 92 * @throws IOException if the file cannot be opened for reading 93 */ 94 MediaVideoItem(VideoEditor editor, String mediaItemId, String filename, int renderingMode, 95 long beginMs, long endMs, int volumePercent, boolean muted, 96 String audioWaveformFilename) throws IOException { 97 super(editor, mediaItemId, filename, renderingMode); 98 // TODO: Set these variables correctly 99 mWidth = 1080; 100 mHeight = 720; 101 mAspectRatio = MediaProperties.ASPECT_RATIO_3_2; 102 mFileType = MediaProperties.FILE_MP4; 103 mVideoType = MediaProperties.VCODEC_H264BP; 104 // Do we have predefined values for this variable? 105 mVideoProfile = 0; 106 // Can video and audio duration be different? 107 mDurationMs = 10000; 108 mVideoBitrate = 800000; 109 mAudioBitrate = 30000; 110 mFps = 30; 111 mAudioType = MediaProperties.ACODEC_AAC_LC; 112 mAudioChannels = 2; 113 mAudioSamplingFrequency = 16000; 114 115 mBeginBoundaryTimeMs = beginMs; 116 mEndBoundaryTimeMs = endMs == END_OF_FILE ? mDurationMs : endMs; 117 mVolumePercentage = volumePercent; 118 mMuted = muted; 119 mAudioWaveformFilename = audioWaveformFilename; 120 if (audioWaveformFilename != null) { 121 mWaveformData = new WaveformData(audioWaveformFilename); 122 } else { 123 mWaveformData = null; 124 } 125 } 126 127 /** 128 * Sets the start and end marks for trimming a video media item. 129 * This method will adjust the duration of bounding transitions, effects 130 * and overlays if the current duration of the transactions become greater 131 * than the maximum allowable duration. 132 * 133 * @param beginMs Start time in milliseconds. Set to 0 to extract from the 134 * beginning 135 * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to 136 * extract until the end 137 * 138 * @throws IllegalArgumentException if the start time is greater or equal than 139 * end time, the end time is beyond the file duration, the start time 140 * is negative 141 */ 142 public void setExtractBoundaries(long beginMs, long endMs) { 143 if (beginMs > mDurationMs) { 144 throw new IllegalArgumentException("Invalid start time"); 145 } 146 if (endMs > mDurationMs) { 147 throw new IllegalArgumentException("Invalid end time"); 148 } 149 150 if (beginMs != mBeginBoundaryTimeMs) { 151 if (mBeginTransition != null) { 152 mBeginTransition.invalidate(); 153 } 154 } 155 156 if (endMs != mEndBoundaryTimeMs) { 157 if (mEndTransition != null) { 158 mEndTransition.invalidate(); 159 } 160 } 161 162 mBeginBoundaryTimeMs = beginMs; 163 mEndBoundaryTimeMs = endMs; 164 165 adjustTransitions(); 166 167 // Note that the start and duration of any effects and overlays are 168 // not adjusted nor are they automatically removed if they fall 169 // outside the new boundaries. 170 } 171 172 /** 173 * @return The boundary begin time 174 */ 175 public long getBoundaryBeginTime() { 176 return mBeginBoundaryTimeMs; 177 } 178 179 /** 180 * @return The boundary end time 181 */ 182 public long getBoundaryEndTime() { 183 return mEndBoundaryTimeMs; 184 } 185 186 /* 187 * {@inheritDoc} 188 */ 189 @Override 190 public void addEffect(Effect effect) { 191 if (effect instanceof EffectKenBurns) { 192 throw new IllegalArgumentException("Ken Burns effects cannot be applied to MediaVideoItem"); 193 } 194 super.addEffect(effect); 195 } 196 197 /* 198 * {@inheritDoc} 199 */ 200 @Override 201 public Bitmap getThumbnail(int width, int height, long timeMs) { 202 return null; 203 } 204 205 /* 206 * {@inheritDoc} 207 */ 208 @Override 209 public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs, 210 int thumbnailCount) throws IOException { 211 return null; 212 } 213 214 /* 215 * {@inheritDoc} 216 */ 217 @Override 218 public int getAspectRatio() { 219 return mAspectRatio; 220 } 221 222 /* 223 * {@inheritDoc} 224 */ 225 @Override 226 public int getFileType() { 227 return mFileType; 228 } 229 230 /* 231 * {@inheritDoc} 232 */ 233 @Override 234 public int getWidth() { 235 return mWidth; 236 } 237 238 /* 239 * {@inheritDoc} 240 */ 241 @Override 242 public int getHeight() { 243 return mHeight; 244 } 245 246 /* 247 * {@inheritDoc} 248 */ 249 @Override 250 public long getDuration() { 251 return mDurationMs; 252 } 253 254 /* 255 * {@inheritDoc} 256 */ 257 @Override 258 public long getTimelineDuration() { 259 return mEndBoundaryTimeMs - mBeginBoundaryTimeMs; 260 } 261 262 /** 263 * Render a frame according to the playback (in the native aspect ratio) for 264 * the specified media item. All effects and overlays applied to the media 265 * item are ignored. The extract boundaries are also ignored. This method 266 * can be used to playback frames when implementing trimming functionality. 267 * 268 * @param surfaceHolder SurfaceHolder used by the application 269 * @param timeMs time corresponding to the frame to display (relative to the 270 * the beginning of the media item). 271 * @return The accurate time stamp of the frame that is rendered . 272 * @throws IllegalStateException if a playback, preview or an export is 273 * already in progress 274 * @throws IllegalArgumentException if time is negative or greater than the 275 * media item duration 276 */ 277 public long renderFrame(SurfaceHolder surfaceHolder, long timeMs) { 278 return timeMs; 279 } 280 281 /** 282 * This API allows to generate a file containing the sample volume levels of 283 * the Audio track of this media item. This function may take significant 284 * time and is blocking. The file can be retrieved using 285 * getAudioWaveformFilename(). 286 * 287 * @param listener The progress listener 288 * 289 * @throws IOException if the output file cannot be created 290 * @throws IllegalArgumentException if the mediaItem does not have a valid 291 * Audio track 292 */ 293 public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener) 294 throws IOException { 295 // TODO: Set mAudioWaveformFilename at the end once the export is complete 296 mWaveformData = new WaveformData(mAudioWaveformFilename); 297 } 298 299 /** 300 * Get the audio waveform file name if {@link #extractAudioWaveform()} was 301 * successful. The file format is as following: 302 * <ul> 303 * <li>first 4 bytes provide the number of samples for each value, as big-endian signed</li> 304 * <li>4 following bytes is the total number of values in the file, as big-endian signed</li> 305 * <li>all values follow as bytes Name is unique.</li> 306 *</ul> 307 * @return the name of the file, null if the file has not been computed or 308 * if there is no Audio track in the mediaItem 309 */ 310 String getAudioWaveformFilename() { 311 return mAudioWaveformFilename; 312 } 313 314 /** 315 * @return The waveform data 316 */ 317 public WaveformData getWaveformData() { 318 return mWaveformData; 319 } 320 321 /** 322 * Set volume of the Audio track of this mediaItem 323 * 324 * @param volumePercent in %/. 100% means no change; 50% means half value, 200% 325 * means double, 0% means silent. 326 * @throws UsupportedOperationException if volume value is not supported 327 */ 328 public void setVolume(int volumePercent) { 329 mVolumePercentage = volumePercent; 330 } 331 332 /** 333 * Get the volume value of the audio track as percentage. Call of this 334 * method before calling setVolume will always return 100% 335 * 336 * @return the volume in percentage 337 */ 338 public int getVolume() { 339 return mVolumePercentage; 340 } 341 342 /** 343 * @param muted true to mute the media item 344 */ 345 public void setMute(boolean muted) { 346 mMuted = muted; 347 } 348 349 /** 350 * @return true if the media item is muted 351 */ 352 public boolean isMuted() { 353 return mMuted; 354 } 355 356 /** 357 * @return The video type 358 */ 359 public int getVideoType() { 360 return mVideoType; 361 } 362 363 /** 364 * @return The video profile 365 */ 366 public int getVideoProfile() { 367 return mVideoProfile; 368 } 369 370 /** 371 * @return The video bitrate 372 */ 373 public int getVideoBitrate() { 374 return mVideoBitrate; 375 } 376 377 /** 378 * @return The audio bitrate 379 */ 380 public int getAudioBitrate() { 381 return mAudioBitrate; 382 } 383 384 /** 385 * @return The number of frames per second 386 */ 387 public int getFps() { 388 return mFps; 389 } 390 391 /** 392 * @return The audio codec 393 */ 394 public int getAudioType() { 395 return mAudioType; 396 } 397 398 /** 399 * @return The number of audio channels 400 */ 401 public int getAudioChannels() { 402 return mAudioChannels; 403 } 404 405 /** 406 * @return The audio sample frequency 407 */ 408 public int getAudioSamplingFrequency() { 409 return mAudioSamplingFrequency; 410 } 411} 412