From 048449ebfa3f42e1431338785f225d25125f294e Mon Sep 17 00:00:00 2001 From: Gil Dobjanschi Date: Wed, 29 Sep 2010 16:58:21 -0700 Subject: [PATCH] Added ability to instantiate various implementations of the VideoEditor Change-Id: I5b09afafff1c009bada4f49a5568286fe3cd9aef --- .../media/videoeditor/EffectKenBurns.java | 9 +- .../media/videoeditor/OverlayFrame.java | 8 +- .../media/videoeditor/VideoEditorFactory.java | 27 ++++- .../videoeditor/VideoEditorTestImpl.java | 110 +++++++++++++++++- 4 files changed, 141 insertions(+), 13 deletions(-) diff --git a/media/java/android/media/videoeditor/EffectKenBurns.java b/media/java/android/media/videoeditor/EffectKenBurns.java index fd2da5cac7b0c..ae2e70d7bc718 100755 --- a/media/java/android/media/videoeditor/EffectKenBurns.java +++ b/media/java/android/media/videoeditor/EffectKenBurns.java @@ -16,8 +16,6 @@ package android.media.videoeditor; -import java.io.IOException; - import android.graphics.Rect; /** @@ -34,7 +32,7 @@ public class EffectKenBurns extends Effect { * constructor */ @SuppressWarnings("unused") - private EffectKenBurns() throws IOException { + private EffectKenBurns() { this(null, null, null, null, 0, 0); } @@ -49,9 +47,8 @@ public class EffectKenBurns extends Effect { * @param durationMs The duration of the Ken Burns effect in milliseconds */ public EffectKenBurns(MediaItem mediaItem, String effectId, Rect startRect, Rect endRect, - long startTime, long durationMs) - throws IOException { - super(mediaItem, effectId, startTime, durationMs); + long startTimeMs, long durationMs) { + super(mediaItem, effectId, startTimeMs, durationMs); mStartRect = startRect; mEndRect = endRect; diff --git a/media/java/android/media/videoeditor/OverlayFrame.java b/media/java/android/media/videoeditor/OverlayFrame.java index c7dfc391800df..dcac4ba983508 100755 --- a/media/java/android/media/videoeditor/OverlayFrame.java +++ b/media/java/android/media/videoeditor/OverlayFrame.java @@ -118,18 +118,18 @@ public class OverlayFrame extends Overlay { /** * Save the overlay to the project folder * - * @param editor The video editor + * @param path The path where the overlay will be saved * - * @return + * @return The filename * @throws FileNotFoundException if the bitmap cannot be saved * @throws IOException if the bitmap file cannot be saved */ - String save(VideoEditor editor) throws FileNotFoundException, IOException { + String save(String path) throws FileNotFoundException, IOException { if (mFilename != null) { return mFilename; } - mFilename = editor.getPath() + "/" + getId() + ".png"; + mFilename = path + "/" + getId() + ".png"; // Save the image to a local file final FileOutputStream out = new FileOutputStream(mFilename); mBitmap.compress(CompressFormat.PNG, 100, out); diff --git a/media/java/android/media/videoeditor/VideoEditorFactory.java b/media/java/android/media/videoeditor/VideoEditorFactory.java index 2c56fc215d243..8081d7658924c 100755 --- a/media/java/android/media/videoeditor/VideoEditorFactory.java +++ b/media/java/android/media/videoeditor/VideoEditorFactory.java @@ -19,6 +19,8 @@ package android.media.videoeditor; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; /** @@ -28,12 +30,19 @@ import java.io.IOException; * {@hide} */ public class VideoEditorFactory { + // VideoEditor implementation classes + public static final String TEST_CLASS_IMPLEMENTATION + = "android.media.videoeditor.VideoEditorTestImpl"; + public static final String DEFAULT_CLASS_IMPLEMENTATION + = "android.media.videoeditor.VideoEditorImpl"; + /** * This is the factory method for creating a new VideoEditor instance. * * @param projectPath The path where all VideoEditor internal * files are stored. When a project is deleted the application is * responsible for deleting the path and its contents. + * @param className The implementation class name * * @return The VideoEditor instance * @@ -41,8 +50,14 @@ public class VideoEditorFactory { * not be accessed in read/write mode * @throws IllegalStateException if a previous VideoEditor instance has not * been released + * @throws ClassNotFoundException, NoSuchMethodException, + * InvocationTargetException, IllegalAccessException, + * InstantiationException if the implementation class cannot + * be instantiated. */ - public static VideoEditor create(String projectPath) throws IOException { + public static VideoEditor create(String projectPath, String className) throws IOException, + ClassNotFoundException, NoSuchMethodException, InvocationTargetException, + IllegalAccessException, InstantiationException { // If the project path does not exist create it final File dir = new File(projectPath); if (!dir.exists()) { @@ -50,7 +65,15 @@ public class VideoEditorFactory { throw new FileNotFoundException("Cannot create project path: " + projectPath); } } - return new VideoEditorTestImpl(projectPath); + + Class cls = Class.forName(className); + Class partypes[] = new Class[1]; + partypes[0] = String.class; + Constructor ct = cls.getConstructor(partypes); + Object arglist[] = new Object[1]; + arglist[0] = projectPath; + + return (VideoEditor)ct.newInstance(arglist); } /** diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java index 5df4ea55d34f2..16f9495b2701c 100644 --- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java @@ -31,6 +31,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.graphics.Rect; import android.util.Log; import android.util.Xml; import android.view.SurfaceHolder; @@ -54,6 +55,8 @@ public class VideoEditorTestImpl implements VideoEditor { private static final String TAG_OVERLAYS = "overlays"; private static final String TAG_OVERLAY = "overlay"; private static final String TAG_OVERLAY_USER_ATTRIBUTES = "overlay_user_attributes"; + private static final String TAG_EFFECTS = "effects"; + private static final String TAG_EFFECT = "effect"; private static final String ATTR_ID = "id"; private static final String ATTR_FILENAME = "filename"; @@ -72,6 +75,16 @@ public class VideoEditorTestImpl implements VideoEditor { private static final String ATTR_MASK = "mask"; private static final String ATTR_BEFORE_MEDIA_ITEM_ID = "before_media_item"; private static final String ATTR_AFTER_MEDIA_ITEM_ID = "after_media_item"; + private static final String ATTR_COLOR_EFFECT_TYPE = "color_type"; + private static final String ATTR_COLOR_EFFECT_VALUE = "color_value"; + private static final String ATTR_START_RECT_L = "start_l"; + private static final String ATTR_START_RECT_T = "start_t"; + private static final String ATTR_START_RECT_R = "start_r"; + private static final String ATTR_START_RECT_B = "start_b"; + private static final String ATTR_END_RECT_L = "end_l"; + private static final String ATTR_END_RECT_T = "end_t"; + private static final String ATTR_END_RECT_R = "end_r"; + private static final String ATTR_END_RECT_B = "end_b"; // Instance variables private long mDurationMs; @@ -589,7 +602,7 @@ public class VideoEditorTestImpl implements VideoEditor { serializer.attribute("", ATTR_DURATION, Long.toString(overlay.getDuration())); if (overlay instanceof OverlayFrame) { final OverlayFrame overlayFrame = (OverlayFrame)overlay; - overlayFrame.save(this); + overlayFrame.save(getPath()); if (overlayFrame.getFilename() != null) { serializer.attribute("", ATTR_FILENAME, overlayFrame.getFilename()); } @@ -611,6 +624,48 @@ public class VideoEditorTestImpl implements VideoEditor { serializer.endTag("", TAG_OVERLAYS); } + final List effects = mediaItem.getAllEffects(); + if (effects.size() > 0) { + serializer.startTag("", TAG_EFFECTS); + for (Effect effect : effects) { + serializer.startTag("", TAG_EFFECT); + serializer.attribute("", ATTR_ID, effect.getId()); + serializer.attribute("", ATTR_TYPE, effect.getClass().getSimpleName()); + serializer.attribute("", ATTR_BEGIN_TIME, + Long.toString(effect.getStartTime())); + serializer.attribute("", ATTR_DURATION, Long.toString(effect.getDuration())); + if (effect instanceof EffectColor) { + final EffectColor colorEffect = (EffectColor)effect; + serializer.attribute("", ATTR_COLOR_EFFECT_TYPE, + Integer.toString(colorEffect.getType())); + if (colorEffect.getType() == EffectColor.TYPE_COLOR) { + serializer.attribute("", ATTR_COLOR_EFFECT_VALUE, + Integer.toString(colorEffect.getParam())); + } + } else if (effect instanceof EffectKenBurns) { + final Rect startRect = ((EffectKenBurns)effect).getStartRect(); + serializer.attribute("", ATTR_START_RECT_L, + Integer.toString(startRect.left)); + serializer.attribute("", ATTR_START_RECT_T, + Integer.toString(startRect.top)); + serializer.attribute("", ATTR_START_RECT_R, + Integer.toString(startRect.right)); + serializer.attribute("", ATTR_START_RECT_B, + Integer.toString(startRect.bottom)); + + final Rect endRect = ((EffectKenBurns)effect).getEndRect(); + serializer.attribute("", ATTR_END_RECT_L, Integer.toString(endRect.left)); + serializer.attribute("", ATTR_END_RECT_T, Integer.toString(endRect.top)); + serializer.attribute("", ATTR_END_RECT_R, Integer.toString(endRect.right)); + serializer.attribute("", ATTR_END_RECT_B, + Integer.toString(endRect.bottom)); + } + + serializer.endTag("", TAG_EFFECT); + } + serializer.endTag("", TAG_EFFECTS); + } + serializer.endTag("", TAG_MEDIA_ITEM); } serializer.endTag("", TAG_MEDIA_ITEMS); @@ -733,6 +788,13 @@ public class VideoEditorTestImpl implements VideoEditor { parser.getAttributeValue(i)); } } + } else if (TAG_EFFECT.equals(name)) { + if (currentMediaItem != null) { + final Effect effect = parseEffect(parser, currentMediaItem); + if (effect != null) { + currentMediaItem.addEffect(effect); + } + } } break; } @@ -854,6 +916,52 @@ public class VideoEditorTestImpl implements VideoEditor { return overlay; } + /** + * Parse the effect + * + * @param parser The parser + * @param mediaItem The media item owner + * + * @return The effect + */ + private Effect parseEffect(XmlPullParser parser, MediaItem mediaItem) { + final String effectId = parser.getAttributeValue("", ATTR_ID); + final String type = parser.getAttributeValue("", ATTR_TYPE); + final long durationMs = Long.parseLong(parser.getAttributeValue("", ATTR_DURATION)); + final long startTimeMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME)); + + final Effect effect; + if (EffectColor.class.getSimpleName().equals(type)) { + final int colorEffectType = + Integer.parseInt(parser.getAttributeValue("", ATTR_COLOR_EFFECT_TYPE)); + final int color; + if (colorEffectType == EffectColor.TYPE_COLOR) { + color = Integer.parseInt(parser.getAttributeValue("", ATTR_COLOR_EFFECT_VALUE)); + } else { + color = 0; + } + effect = new EffectColor(mediaItem, effectId, startTimeMs, durationMs, + colorEffectType, color); + } else if (EffectKenBurns.class.getSimpleName().equals(type)) { + final Rect startRect = new Rect( + Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_L)), + Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_T)), + Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_R)), + Integer.parseInt(parser.getAttributeValue("", ATTR_START_RECT_B))); + final Rect endRect = new Rect( + Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_L)), + Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_T)), + Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_R)), + Integer.parseInt(parser.getAttributeValue("", ATTR_END_RECT_B))); + effect = new EffectKenBurns(mediaItem, effectId, startRect, endRect, startTimeMs, + durationMs); + } else { + effect = null; + } + + return effect; + } + public void cancelExport(String filename) { }