1 /* 2 * Copyright (C) 2011 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.mediaframeworktest; 18 19 import java.io.File; 20 import java.io.FileInputStream; 21 import java.io.IOException; 22 import java.text.SimpleDateFormat; 23 import java.util.Date; 24 import java.util.Random; 25 26 import junit.framework.Assert; 27 import android.graphics.Bitmap; 28 import android.graphics.BitmapFactory; 29 import android.media.videoeditor.AudioTrack; 30 import android.media.videoeditor.EffectColor; 31 import android.media.videoeditor.MediaImageItem; 32 import android.media.videoeditor.MediaItem; 33 import android.media.videoeditor.MediaVideoItem; 34 import android.media.videoeditor.OverlayFrame; 35 import android.media.videoeditor.TransitionAlpha; 36 import android.media.videoeditor.TransitionCrossfade; 37 import android.media.videoeditor.TransitionFadeBlack; 38 import android.media.videoeditor.TransitionSliding; 39 import android.media.videoeditor.VideoEditor; 40 import android.media.videoeditor.VideoEditorFactory; 41 import android.util.Log; 42 import android.os.Environment; 43 44 /** 45 * This class has the names of the all the activity name and variables in the 46 * instrumentation test. 47 */ 48 public class VideoEditorHelper extends Assert { 49 50 private final String TAG = "VideoEditorMediaNames"; 51 52 public VideoEditorHelper() { 53 54 } 55 56 public static final String PROJECT_LOCATION_COMMON = 57 Environment.getExternalStorageDirectory().toString() + "/"; 58 59 public static final String INPUT_FILE_PATH_COMMON = PROJECT_LOCATION_COMMON + 60 "media_api/videoeditor/"; 61 62 // ----------------------------------------------------------------- 63 // HELPER METHODS 64 // ----------------------------------------------------------------- 65 66 /** 67 * This method creates an object of VideoEditor 68 * 69 * @param projectPath the directory where all files related to project will 70 * be stored 71 * @param className The class which implements the VideoEditor Class 72 * @return the object of VideoEditor 73 */ 74 public VideoEditor createVideoEditor(String projectPath) { 75 VideoEditor mVideoEditor = null; 76 try { 77 mVideoEditor = VideoEditorFactory.create(projectPath); 78 assertNotNull("VideoEditor", mVideoEditor); 79 } catch (Exception e) { 80 fail("Unable to create Video Editor"); 81 } 82 return mVideoEditor; 83 } 84 85 /** 86 *This method deletes the VideoEditor object created using 87 * createVideoEditor method 88 * 89 * @param videoEditor the VideoEditor object which needs to be cleaned up 90 */ 91 public void destroyVideoEditor(VideoEditor videoEditor) { 92 // Release VideoEditor 93 if (videoEditor != null) { 94 try { 95 videoEditor.release(); 96 } catch (Exception e) { 97 fail("Unable to destory Video Editor"); 98 } 99 } 100 } 101 102 /** 103 *This Method checks the Range in "RangePercent" (say 10) 104 * 105 * @param int Expected data 106 * @param actual data 107 * @return boolean flag which confirms the range matching 108 */ 109 public boolean checkRange(long expected, long actual, long rangePercent) { 110 long range = 0; 111 range = (100 * actual) / expected; 112 113 Log.i("checkRange", "Range = " + range); 114 if ((range > (100 - rangePercent)) && (range < (100 + rangePercent))) { 115 return true; 116 } else { 117 return false; 118 } 119 } 120 121 /** 122 *This Method Creates a Bitmap with the given input file 123 * 124 * @param file the Input whose Bitmap has top be extracted 125 * @return an Object of EffectColor 126 */ 127 public Bitmap getBitmap(String file, int width, int height) throws IOException { 128 assertNotNull("Bitmap File is Null", file); 129 FileInputStream inputStream = null; 130 Bitmap overlayBmp = null; 131 if (!new File(file).exists()) 132 throw new IOException("File not Found " + file); 133 try { 134 final BitmapFactory.Options dbo = new BitmapFactory.Options(); 135 dbo.inJustDecodeBounds = true; 136 dbo.outWidth = width; 137 dbo.outHeight = height; 138 File flPtr = new File(file); 139 inputStream = new FileInputStream(flPtr); 140 final Bitmap srcBitmap = BitmapFactory.decodeStream(inputStream); 141 overlayBmp = Bitmap.createBitmap(srcBitmap); 142 assertNotNull("Bitmap 1", srcBitmap); 143 assertNotNull("Bitmap 2", overlayBmp); 144 inputStream.close(); 145 } catch (IOException e) { 146 e.printStackTrace(); 147 } 148 return overlayBmp; 149 } 150 151 /** 152 *This Method Create a Media Video Item with the specified params 153 * 154 * @return an Object of MediaVideoItem 155 */ 156 public MediaVideoItem createMediaItem(VideoEditor videoEditor, 157 String MediaId, String filename, int renderingMode) { 158 MediaVideoItem mvi = null; 159 try { 160 mvi = new MediaVideoItem(videoEditor, MediaId, filename, 161 renderingMode); 162 assertNotNull("Can not create an object of MediaVideoItem", mvi); 163 } catch (IllegalArgumentException e) { 164 throw new IllegalArgumentException 165 ("Can not create an object of Media Video Item with file name = " 166 + filename + " Issue = " + e.toString()); 167 } catch (IOException e) { 168 assertTrue 169 ("Can not create an object of Media Video Item with file name = " 170 + filename + " Issue = " + e.toString(), false); 171 } 172 return mvi; 173 } 174 175 /** 176 *This Method Create a Media Image Item with the specified params 177 * 178 * @return an Object of MediaImageItem 179 */ 180 public MediaImageItem createMediaItem(VideoEditor videoEditor, 181 String MediaId, String filename, long duration, int renderingMode) { 182 MediaImageItem mii = null; 183 try { 184 mii = new MediaImageItem(videoEditor, MediaId, filename, duration, 185 renderingMode); 186 assertNotNull("Can not create an object of MediaImageItem", mii); 187 188 } catch (IllegalArgumentException e) { 189 assertTrue("Can not create an object of Media Image with file name = " 190 + filename + " Issue = " + e.toString(), false); 191 } catch (IOException e) { 192 assertTrue("Can not create an object of Media Image with file name = " 193 + filename + " Issue = " + e.toString(), false); 194 } 195 return mii; 196 } 197 198 /** 199 *This Method Create a Effect with the specified params 200 * 201 * @return an Object of EffectColor 202 */ 203 public EffectColor createEffectItem(MediaItem mediaItem, String effectId, 204 long startTime, long duration, int effectType, int colorType) { 205 EffectColor effectonMVI = null; 206 effectonMVI = new EffectColor(mediaItem, effectId, startTime, 207 duration, effectType, colorType); 208 return effectonMVI; 209 } 210 211 /** 212 *This Method creates object of Type Transition Cross fade 213 * 214 * @return TransitionCrossfade object 215 */ 216 public TransitionCrossfade createTCrossFade(String transitionId, 217 MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs, 218 int behavior) { 219 Log.i("TransitionCrossfade Details === ", "Transid ID = " + transitionId + 220 " Duration= " + durationMs + " Behaviour " + behavior); 221 222 TransitionCrossfade transitionCF = null; 223 transitionCF = new TransitionCrossfade(transitionId, afterMediaItem, 224 beforeMediaItem, durationMs, behavior); 225 return transitionCF; 226 } 227 228 /** 229 *This Method creates object of Type TransitionFadeBlack 230 * 231 * @return TransitionFadeBlack object 232 */ 233 public TransitionFadeBlack createTFadeBlack(String transitionId, 234 MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs, 235 int behavior) { 236 TransitionFadeBlack transitionFB = null; 237 238 transitionFB = new TransitionFadeBlack(transitionId, afterMediaItem, 239 beforeMediaItem, durationMs, behavior); 240 return transitionFB; 241 } 242 243 /** 244 *This Method creates object of Type TransitionSliding 245 * 246 * @return TransitionSliding object 247 */ 248 public TransitionSliding createTSliding(String transitionId, 249 MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs, 250 int behavior, int direction) { 251 TransitionSliding transSlide = null; 252 transSlide = new TransitionSliding(transitionId, afterMediaItem, 253 beforeMediaItem, durationMs, behavior, direction); 254 return transSlide; 255 } 256 257 /** 258 *This Method creates object of Type TranistionAlpha 259 * 260 * @return TranistionAlpha object 261 */ 262 263 public TransitionAlpha createTAlpha(String transitionId, 264 MediaItem afterMediaItem, MediaItem beforeMediaItem, long durationMs, 265 int behavior, String maskFilename, int blendingPercent, boolean invert) { 266 TransitionAlpha transA = null; 267 transA = new TransitionAlpha(transitionId, afterMediaItem, 268 beforeMediaItem, durationMs, behavior, maskFilename, 269 blendingPercent, invert); 270 return transA; 271 } 272 273 /** 274 *This Method creates object of Type OverlayFrame 275 * 276 * @return OverlayFrame object 277 */ 278 279 public OverlayFrame createOverlay(MediaItem mediaItem, String overlayId, 280 Bitmap bitmap, long startTimeMs, long durationMs) { 281 OverlayFrame overLayFrame = null; 282 overLayFrame = new OverlayFrame(mediaItem, overlayId, bitmap, 283 startTimeMs, durationMs); 284 return overLayFrame; 285 } 286 287 /** 288 *This Method creates object of Type AudioTrack 289 * 290 * @return OverlayFrame object 291 */ 292 public AudioTrack createAudio(VideoEditor videoEditor, String audioTrackId, 293 String filename) { 294 AudioTrack audio = null; 295 try { 296 audio = new AudioTrack(videoEditor, audioTrackId, filename); 297 assertNotNull("Cant not create an object of an AudioTrack " + 298 audioTrackId, audio); 299 } catch (IllegalArgumentException e) { 300 assertTrue("Can not create object of an AudioTrack " + 301 audioTrackId + " Issue = " + e.toString(), false); 302 } catch (IOException e) { 303 assertTrue("Can not create object of an AudioTrack " + 304 audioTrackId + " Issue = " + e.toString(), false); 305 } 306 return audio; 307 } 308 309 /** 310 *This Method validates the Exported Movie,as per the specified params 311 * during Export 312 */ 313 314 public void validateExport(VideoEditor videoEditor, String fileName, 315 int export_height, int startTime, long endTime, int vCodec, int aCodec) { 316 File tempFile = new File(fileName); 317 assertEquals("Exported FileName", tempFile.exists(), true); 318 final MediaVideoItem mvi = createMediaItem(videoEditor, "m1", fileName, 319 MediaItem.RENDERING_MODE_BLACK_BORDER); 320 321 Log.i(TAG, "VideoCodec for file = " + fileName + 322 "\tExpected Video Codec = " + vCodec + "\tActual Video Codec = " + 323 mvi.getVideoType()); 324 assertEquals("Export: Video Codec Mismatch for file = " + fileName + 325 "\t<expected> " + vCodec + "\t<actual> " + mvi.getVideoType(), 326 vCodec, mvi.getVideoType()); 327 328 Log.i(TAG, "Height for file = " + fileName + "\tExpected Height = " + 329 export_height + "\tActual VideoHeight = " + mvi.getHeight()); 330 assertEquals("Export height Mismatch for file " + fileName + 331 "\t<expected> " + export_height + "\t<actual> " + mvi.getHeight(), 332 export_height, mvi.getHeight()); 333 if (startTime == 0) { 334 if (endTime != 0) { 335 Log.i(TAG, "TimeLine Expected = " + (startTime + endTime) + 336 "\t VideoTime= " + mvi.getTimelineDuration()); 337 assertTrue("Timeline Duration Mismatch for file " + fileName + 338 "<expected> " + (startTime + endTime) + "\t<actual> " + 339 mvi.getTimelineDuration(), checkRange((startTime + 340 endTime), mvi.getTimelineDuration(), 10)); 341 } 342 } else { 343 Log.i(TAG, "TimeLine Expected = " + (endTime - startTime) + 344 "\t VideoTime= " + mvi.getTimelineDuration()); 345 assertTrue("Timeline Duration Mismatch for file " + fileName + 346 "<expected> " + (endTime - startTime) + "\t<actual> " + 347 mvi.getTimelineDuration(), checkRange((endTime - 348 startTime), (int)mvi.getTimelineDuration(), 10)); 349 } 350 } 351 352 /** 353 * @param videoEditor 354 * @param fileName 355 * @param export_bitrate 356 * @param export_height 357 * @param startTime 358 * @param endTime 359 * @param vCodec 360 * @param aCodec 361 */ 362 public void validateExport(VideoEditor videoEditor, String fileName, 363 int export_height, int startTime, int endTime, int vCodec, int aCodec) { 364 File tempFile = new File(fileName); 365 assertEquals("Exported FileName", tempFile.exists(), true); 366 final MediaVideoItem mvi = createMediaItem(videoEditor, "m1", fileName, 367 MediaItem.RENDERING_MODE_BLACK_BORDER); 368 Log.i(TAG, "VideoCodec for file = " + fileName + 369 "\tExpected Video Codec = " + vCodec + "\tActual Video Codec = " + 370 mvi.getVideoType()); 371 assertEquals("Export: Video Codec Mismatch for file = " + fileName + 372 "\t<expected> " + vCodec + "\t<actual> " + mvi.getVideoType(), 373 vCodec, mvi.getVideoType()); 374 375 Log.i(TAG, "AudioCodec for file = " + fileName + 376 "\tExpected Audio Codec = " + aCodec + "\tActual Audio Codec = " + 377 mvi.getAudioType()); 378 assertEquals("Export: Audio Codec Mismatch for file = " + fileName + 379 "\t<expected> " + aCodec + "\t<actual> " + mvi.getAudioType(), 380 aCodec, mvi.getAudioType()); 381 382 Log.i(TAG, "Height for file = " + fileName + "\tExpected Height = " + 383 export_height + "\tActual VideoHeight = " + mvi.getHeight()); 384 assertEquals("Export: height Mismatch for file " + fileName + 385 "\t<expected> " + export_height + "\t<actual> " + mvi.getHeight(), 386 export_height, mvi.getHeight()); 387 if (startTime == 0) { 388 if (endTime != 0) { 389 Log.i(TAG, "TimeLine Expected = " + (startTime + endTime) + 390 "\t VideoTime= " + mvi.getTimelineDuration()); 391 assertTrue("Export :Timeline Duration Mismatch for file " + 392 fileName + "<expected> " + (startTime + endTime) + 393 "\t<actual> " + mvi.getTimelineDuration(), 394 checkRange((startTime + endTime), mvi.getTimelineDuration(), 10)); 395 } 396 } else { 397 Log.i(TAG, "TimeLine Expected = " + (endTime-startTime) + 398 "\t VideoTime= " + mvi.getTimelineDuration()); 399 assertTrue("Timeline Duration Mismatch for file " + fileName + 400 "<expected> " + (endTime - startTime) + "\t<actual> " + 401 mvi.getTimelineDuration(), checkRange((endTime - 402 startTime), mvi.getTimelineDuration(), 10)); 403 } 404 } 405 406 /** 407 * Check file and deletes it. 408 * 409 * @param filename 410 */ 411 public void checkDeleteExistingFile(String filename) { 412 Log.i(TAG, ">>>>>>>>>>>>>>>>>>checkDeleteExistingFile = " + filename); 413 if (filename != null) { 414 File temp = new File(filename); 415 if (temp != null && temp.exists()) { 416 temp.delete(); 417 } 418 } 419 } 420 421 /** 422 * This method creates a Directory and filename 423 * 424 * @param location This is path where the file is to be created 425 * "/sdcard/Output/" 426 * @return Path in form of /sdcard/Output/200910100000 427 */ 428 public String createRandomFile(String location) { 429 Random randomGenerator = new Random(); 430 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssS"); 431 Date date = new Date(); 432 final String filePath = location + dateFormat.format(date) + 433 randomGenerator.nextInt(10); 434 Log.i(TAG, ">>>>>>>>>>>>>>>>createRandomFile Location= " + location + 435 "\t FilePath = " + filePath); 436 return filePath; 437 } 438 439 /** 440 * This method recursively deletes all the file and directory 441 * 442 * @param directory where the files are located Example = "/sdcard/Input" 443 * @return boolean True if deletion is successful else False 444 */ 445 public boolean deleteProject(File directory) { 446 Log.i(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>deleteProject directory= " + 447 directory.toString()); 448 if (directory.isDirectory()) { 449 String[] filesInDirecory = directory.list(); 450 for (int i = 0; i < filesInDirecory.length; i++) { 451 boolean success = deleteProject(new File(directory, 452 filesInDirecory[i])); 453 if (!success) { 454 return false; 455 } 456 } 457 } 458 return directory.delete(); 459 } 460 461 /** 462 * This method compares the array of Integer from 0 - 100 463 * 464 * @param data set of integer values received as progress 465 * @return true if sucess else false 466 */ 467 public boolean checkProgressCBValues(int[] data) { 468 boolean retFlag = false; 469 for (int i = 0; i < 100; i++) { 470 if (data[i] == 100) { 471 retFlag = true; 472 break; 473 } else { 474 retFlag = false; 475 } 476 } 477 return retFlag; 478 } 479 } 480