diff --git a/Video.js b/Video.js
index 86a7c48d..423f3e77 100644
--- a/Video.js
+++ b/Video.js
@@ -4,6 +4,7 @@ const {
StyleSheet,
requireNativeComponent,
PropTypes,
+ NativeModules,
} = React;
const VideoResizeMode = require('./VideoResizeMode');
@@ -49,13 +50,13 @@ class Video extends Component {
let nativeResizeMode;
if (resizeMode === VideoResizeMode.stretch) {
- nativeResizeMode = RCTVideo.ScaleToFill;
+ nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleToFill;
} else if (resizeMode === VideoResizeMode.contain) {
- nativeResizeMode = RCTVideo.ScaleAspectFit;
+ nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleAspectFit;
} else if (resizeMode === VideoResizeMode.cover) {
- nativeResizeMode = RCTVideo.ScaleAspectFill;
+ nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleAspectFill;
} else {
- nativeResizeMode = RCTVideo.ScaleNone;
+ nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleNone;
}
const nativeProps = Object.assign({}, this.props);
diff --git a/android/RCTVideo.iml b/android/RCTVideo.iml
index 000f380b..389b183f 100644
--- a/android/RCTVideo.iml
+++ b/android/RCTVideo.iml
@@ -13,8 +13,11 @@
-
-
+
+
+ generateDebugAndroidTestSources
+ generateDebugSources
+
@@ -24,7 +27,7 @@
-
+
@@ -86,22 +89,23 @@
-
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index 45a3bd42..955ad774 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -17,4 +17,5 @@ android {
dependencies {
compile 'com.facebook.react:react-native:0.13.+'
+ compile 'com.yqritc:android-scalablevideoview:1.0.1'
}
diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java b/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java
index a834ceff..2e930622 100644
--- a/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java
+++ b/android/src/main/java/com/brentvatne/react/ReactVideoViewManager.java
@@ -1,17 +1,17 @@
package com.brentvatne.react;
-import android.graphics.Color;
+import android.content.Context;
import android.media.MediaPlayer;
-import android.widget.MediaController;
-import android.net.Uri;
-import android.support.annotation.Nullable;
+import android.view.Gravity;
import android.widget.FrameLayout;
-import android.widget.VideoView;
+import android.support.annotation.Nullable;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
+import com.yqritc.scalablevideoview.ScalableType;
+import com.yqritc.scalablevideoview.ScalableVideoView;
import java.util.Map;
@@ -24,13 +24,16 @@ public class ReactVideoViewManager extends SimpleViewManager {
private static final String PROP_RESIZE_MODE = "resizeMode";
private static final String PROP_REPEAT = "repeat";
private static final String PROP_PAUSED = "paused";
+ private static final String PROP_MUTED = "muted";
+ private static final String PROP_VOLUME = "volume";
- private enum ResizeMode {
- SCALE_NONE, SCALE_TO_FILL, SCALE_ASPECT_FIT, SCALE_ASPECT_FILL
- }
+ private boolean mPrepared = false;
+ private ScalableType mResizeMode = ScalableType.LEFT_TOP;
private boolean mRepeat = false;
private boolean mPaused = false;
+ private boolean mMuted = false;
+ private float mVolume = 1;
@Override
public String getName() {
@@ -40,93 +43,74 @@ public class ReactVideoViewManager extends SimpleViewManager {
@Override
protected FrameLayout createViewInstance(ThemedReactContext themedReactContext) {
final FrameLayout container = new FrameLayout(themedReactContext);
- final VideoView videoView = new VideoView(themedReactContext);
+ final ScalableVideoView videoView = new ScalableVideoView(themedReactContext);
- MediaController mediaController = new MediaController(themedReactContext);
- mediaController.setAnchorView(videoView);
- mediaController.setVisibility(VideoView.GONE);
- videoView.setMediaController(mediaController);
- videoView.setLayoutParams(new FrameLayout.LayoutParams(
+ final FrameLayout.LayoutParams videoLayout = new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT
+ );
+ videoLayout.gravity = Gravity.CENTER;
+ videoView.setLayoutParams(videoLayout);
+
+ container.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT));
+ FrameLayout.LayoutParams.MATCH_PARENT
+ ));
container.addView(videoView);
-
return container;
}
@Override
- public
@Nullable
- Map getExportedViewConstants() {
+ public Map getExportedViewConstants() {
return MapBuilder.of(
- "ScaleNone", ResizeMode.SCALE_NONE.ordinal(),
- "ScaleToFill", ResizeMode.SCALE_TO_FILL.ordinal(),
- "ScaleAspectFit", ResizeMode.SCALE_ASPECT_FIT.ordinal(),
- "ScaleAspectFill", ResizeMode.SCALE_ASPECT_FILL.ordinal());
+ "ScaleNone", ScalableType.LEFT_TOP.ordinal(),
+ "ScaleToFill", ScalableType.FIT_XY.ordinal(),
+ "ScaleAspectFit", ScalableType.FIT_CENTER.ordinal(),
+ "ScaleAspectFill", ScalableType.CENTER_CROP.ordinal()
+ );
}
@ReactProp(name = PROP_SRC)
public void setSrc(final FrameLayout container, @Nullable ReadableMap src) {
- final VideoView videoView = (VideoView) container.getChildAt(0);
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
try {
final String uriString = src.getString("uri");
final boolean isNetwork = src.getBoolean("isNetwork");
- videoView.stopPlayback();
+ if (mPrepared) {
+ videoView.stop();
+ mPrepared = false;
+ }
if (isNetwork) {
- videoView.setVideoPath(uriString);
- videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mp) {
- applyModifiers(container);
- }
- });
+ videoView.setDataSource(uriString);
} else {
- videoView.setVideoURI(Uri.parse("android.resource://" + videoView.getContext().getPackageName() +
- "/raw/" + uriString));
- applyModifiers(container);
+ Context context = videoView.getContext();
+ videoView.setRawData(context.getResources().getIdentifier(uriString, "raw", context.getPackageName()));
}
+
+ videoView.prepare(new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ mPrepared = true;
+ applyModifiers(container);
+ }
+ });
} catch (Exception e) {
assertTrue("failed to set video source", false);
}
}
@ReactProp(name = PROP_RESIZE_MODE)
- public void setResizeMode(final FrameLayout container, int resizeModeOrdinal) {
- final VideoView videoView = (VideoView) container.getChildAt(0);
+ public void setResizeMode(final FrameLayout container, final int resizeModeOrdinal) {
+ mResizeMode = ScalableType.values()[resizeModeOrdinal];
- try {
- final ResizeMode resizeMode = ResizeMode.values()[resizeModeOrdinal];
-
- FrameLayout.LayoutParams layoutParams = null;
- switch (resizeMode) {
- case SCALE_NONE:
- layoutParams = new FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.WRAP_CONTENT,
- FrameLayout.LayoutParams.WRAP_CONTENT);
- break;
-
- case SCALE_TO_FILL:
- layoutParams = new FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT);
- break;
-
- case SCALE_ASPECT_FIT:
- break;
-
- case SCALE_ASPECT_FILL:
- break;
- }
-
- if (layoutParams != null) {
- videoView.setLayoutParams(layoutParams);
- container.updateViewLayout(videoView, layoutParams);
- }
- } catch (Exception e) {
- assertTrue("failed to set video resize mode", false);
+ if (mPrepared) {
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
+ videoView.setScalableType(mResizeMode);
+ videoView.invalidate();
}
}
@@ -134,35 +118,56 @@ public class ReactVideoViewManager extends SimpleViewManager {
public void setRepeat(final FrameLayout container, final boolean repeat) {
mRepeat = repeat;
- if (!mRepeat) { return; }
-
- final VideoView videoView = (VideoView) container.getChildAt(0);
- videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
-
- if (mRepeat) {
- mp.seekTo(0);
- setPaused(container, mPaused);
- }
- }
- });
+ if (mPrepared) {
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
+ videoView.setLooping(mRepeat);
+ }
}
@ReactProp(name = PROP_PAUSED)
public void setPaused(final FrameLayout container, final boolean paused) {
- final VideoView videoView = (VideoView) container.getChildAt(0);
- videoView.requestFocus();
- if (!paused) {
- videoView.start();
- } else {
- videoView.pause();
- }
mPaused = paused;
+
+ if (mPrepared) {
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
+ videoView.requestFocus();
+ if (!mPaused) {
+ videoView.start();
+ } else {
+ videoView.pause();
+ }
+ }
+ }
+
+ @ReactProp(name = PROP_MUTED)
+ public void setMuted(final FrameLayout container, final boolean muted) {
+ mMuted = muted;
+
+ if (mPrepared) {
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
+
+ if (mMuted) {
+ videoView.setVolume(0, 0);
+ } else {
+ videoView.setVolume(mVolume, mVolume);
+ }
+ }
+ }
+
+ @ReactProp(name = PROP_VOLUME)
+ public void setVolume(final FrameLayout container, final float volume) {
+ mVolume = volume;
+
+ if (mPrepared) {
+ final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
+ videoView.setVolume(mVolume, mVolume);
+ }
}
private void applyModifiers(final FrameLayout container) {
+ setResizeMode(container, mResizeMode.ordinal());
setRepeat(container, mRepeat);
setPaused(container, mPaused);
+ setMuted(container, mMuted);
}
}