[Android] repeat, muted, volume properties fully working
This commit is contained in:
parent
4362e596a8
commit
c03c45a362
9
Video.js
9
Video.js
@ -4,6 +4,7 @@ const {
|
|||||||
StyleSheet,
|
StyleSheet,
|
||||||
requireNativeComponent,
|
requireNativeComponent,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
|
NativeModules,
|
||||||
} = React;
|
} = React;
|
||||||
|
|
||||||
const VideoResizeMode = require('./VideoResizeMode');
|
const VideoResizeMode = require('./VideoResizeMode');
|
||||||
@ -49,13 +50,13 @@ class Video extends Component {
|
|||||||
|
|
||||||
let nativeResizeMode;
|
let nativeResizeMode;
|
||||||
if (resizeMode === VideoResizeMode.stretch) {
|
if (resizeMode === VideoResizeMode.stretch) {
|
||||||
nativeResizeMode = RCTVideo.ScaleToFill;
|
nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleToFill;
|
||||||
} else if (resizeMode === VideoResizeMode.contain) {
|
} else if (resizeMode === VideoResizeMode.contain) {
|
||||||
nativeResizeMode = RCTVideo.ScaleAspectFit;
|
nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleAspectFit;
|
||||||
} else if (resizeMode === VideoResizeMode.cover) {
|
} else if (resizeMode === VideoResizeMode.cover) {
|
||||||
nativeResizeMode = RCTVideo.ScaleAspectFill;
|
nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleAspectFill;
|
||||||
} else {
|
} else {
|
||||||
nativeResizeMode = RCTVideo.ScaleNone;
|
nativeResizeMode = NativeModules.UIManager.RCTVideo.Constants.ScaleNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nativeProps = Object.assign({}, this.props);
|
const nativeProps = Object.assign({}, this.props);
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
||||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
|
<afterSyncTasks>
|
||||||
|
<task>generateDebugAndroidTestSources</task>
|
||||||
|
<task>generateDebugSources</task>
|
||||||
|
</afterSyncTasks>
|
||||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||||
@ -24,7 +27,7 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
|
||||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
@ -86,22 +89,23 @@
|
|||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" exported="" name="fbcore-0.6.1" level="project" />
|
<orderEntry type="library" exported="" name="okhttp-ws-2.4.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="okio-1.5.0" level="project" />
|
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="drawee-0.6.1" level="project" />
|
<orderEntry type="library" exported="" name="okhttp-2.4.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
|
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
|
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
|
||||||
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
|
<orderEntry type="library" exported="" name="fbcore-0.6.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="okhttp-2.4.0" level="project" />
|
<orderEntry type="library" exported="" name="android-scalablevideoview-1.0.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="react-native-0.13.0" level="project" />
|
<orderEntry type="library" exported="" name="react-native-0.13.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="imagepipeline-0.6.1" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="android-jsc-r174650" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.6.1" level="project" />
|
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.6.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="okhttp-ws-2.4.0" level="project" />
|
<orderEntry type="library" exported="" name="android-jsc-r174650" level="project" />
|
||||||
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
|
<orderEntry type="library" exported="" name="imagepipeline-0.6.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="fresco-0.6.1" level="project" />
|
<orderEntry type="library" exported="" name="fresco-0.6.1" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="okio-1.5.0" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="drawee-0.6.1" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -17,4 +17,5 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.facebook.react:react-native:0.13.+'
|
compile 'com.facebook.react:react-native:0.13.+'
|
||||||
|
compile 'com.yqritc:android-scalablevideoview:1.0.1'
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package com.brentvatne.react;
|
package com.brentvatne.react;
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.content.Context;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.widget.MediaController;
|
import android.view.Gravity;
|
||||||
import android.net.Uri;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.VideoView;
|
import android.support.annotation.Nullable;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.facebook.react.common.MapBuilder;
|
import com.facebook.react.common.MapBuilder;
|
||||||
import com.facebook.react.uimanager.ReactProp;
|
import com.facebook.react.uimanager.ReactProp;
|
||||||
import com.facebook.react.uimanager.SimpleViewManager;
|
import com.facebook.react.uimanager.SimpleViewManager;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
|
import com.yqritc.scalablevideoview.ScalableType;
|
||||||
|
import com.yqritc.scalablevideoview.ScalableVideoView;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -24,13 +24,16 @@ public class ReactVideoViewManager extends SimpleViewManager<FrameLayout> {
|
|||||||
private static final String PROP_RESIZE_MODE = "resizeMode";
|
private static final String PROP_RESIZE_MODE = "resizeMode";
|
||||||
private static final String PROP_REPEAT = "repeat";
|
private static final String PROP_REPEAT = "repeat";
|
||||||
private static final String PROP_PAUSED = "paused";
|
private static final String PROP_PAUSED = "paused";
|
||||||
|
private static final String PROP_MUTED = "muted";
|
||||||
|
private static final String PROP_VOLUME = "volume";
|
||||||
|
|
||||||
private enum ResizeMode {
|
private boolean mPrepared = false;
|
||||||
SCALE_NONE, SCALE_TO_FILL, SCALE_ASPECT_FIT, SCALE_ASPECT_FILL
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private ScalableType mResizeMode = ScalableType.LEFT_TOP;
|
||||||
private boolean mRepeat = false;
|
private boolean mRepeat = false;
|
||||||
private boolean mPaused = false;
|
private boolean mPaused = false;
|
||||||
|
private boolean mMuted = false;
|
||||||
|
private float mVolume = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -40,93 +43,74 @@ public class ReactVideoViewManager extends SimpleViewManager<FrameLayout> {
|
|||||||
@Override
|
@Override
|
||||||
protected FrameLayout createViewInstance(ThemedReactContext themedReactContext) {
|
protected FrameLayout createViewInstance(ThemedReactContext themedReactContext) {
|
||||||
final FrameLayout container = new FrameLayout(themedReactContext);
|
final FrameLayout container = new FrameLayout(themedReactContext);
|
||||||
final VideoView videoView = new VideoView(themedReactContext);
|
final ScalableVideoView videoView = new ScalableVideoView(themedReactContext);
|
||||||
|
|
||||||
MediaController mediaController = new MediaController(themedReactContext);
|
final FrameLayout.LayoutParams videoLayout = new FrameLayout.LayoutParams(
|
||||||
mediaController.setAnchorView(videoView);
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
mediaController.setVisibility(VideoView.GONE);
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||||
videoView.setMediaController(mediaController);
|
);
|
||||||
videoView.setLayoutParams(new FrameLayout.LayoutParams(
|
videoLayout.gravity = Gravity.CENTER;
|
||||||
|
videoView.setLayoutParams(videoLayout);
|
||||||
|
|
||||||
|
container.setLayoutParams(new FrameLayout.LayoutParams(
|
||||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
FrameLayout.LayoutParams.MATCH_PARENT));
|
FrameLayout.LayoutParams.MATCH_PARENT
|
||||||
|
));
|
||||||
container.addView(videoView);
|
container.addView(videoView);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
|
||||||
@Nullable
|
@Nullable
|
||||||
Map getExportedViewConstants() {
|
public Map getExportedViewConstants() {
|
||||||
return MapBuilder.of(
|
return MapBuilder.of(
|
||||||
"ScaleNone", ResizeMode.SCALE_NONE.ordinal(),
|
"ScaleNone", ScalableType.LEFT_TOP.ordinal(),
|
||||||
"ScaleToFill", ResizeMode.SCALE_TO_FILL.ordinal(),
|
"ScaleToFill", ScalableType.FIT_XY.ordinal(),
|
||||||
"ScaleAspectFit", ResizeMode.SCALE_ASPECT_FIT.ordinal(),
|
"ScaleAspectFit", ScalableType.FIT_CENTER.ordinal(),
|
||||||
"ScaleAspectFill", ResizeMode.SCALE_ASPECT_FILL.ordinal());
|
"ScaleAspectFill", ScalableType.CENTER_CROP.ordinal()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_SRC)
|
@ReactProp(name = PROP_SRC)
|
||||||
public void setSrc(final FrameLayout container, @Nullable ReadableMap 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 {
|
try {
|
||||||
final String uriString = src.getString("uri");
|
final String uriString = src.getString("uri");
|
||||||
final boolean isNetwork = src.getBoolean("isNetwork");
|
final boolean isNetwork = src.getBoolean("isNetwork");
|
||||||
|
|
||||||
videoView.stopPlayback();
|
if (mPrepared) {
|
||||||
|
videoView.stop();
|
||||||
|
mPrepared = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isNetwork) {
|
if (isNetwork) {
|
||||||
videoView.setVideoPath(uriString);
|
videoView.setDataSource(uriString);
|
||||||
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
|
||||||
@Override
|
|
||||||
public void onPrepared(MediaPlayer mp) {
|
|
||||||
applyModifiers(container);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
videoView.setVideoURI(Uri.parse("android.resource://" + videoView.getContext().getPackageName() +
|
Context context = videoView.getContext();
|
||||||
"/raw/" + uriString));
|
videoView.setRawData(context.getResources().getIdentifier(uriString, "raw", context.getPackageName()));
|
||||||
applyModifiers(container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
videoView.prepare(new MediaPlayer.OnPreparedListener() {
|
||||||
|
@Override
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
mPrepared = true;
|
||||||
|
applyModifiers(container);
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue("failed to set video source", false);
|
assertTrue("failed to set video source", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_RESIZE_MODE)
|
@ReactProp(name = PROP_RESIZE_MODE)
|
||||||
public void setResizeMode(final FrameLayout container, int resizeModeOrdinal) {
|
public void setResizeMode(final FrameLayout container, final int resizeModeOrdinal) {
|
||||||
final VideoView videoView = (VideoView) container.getChildAt(0);
|
mResizeMode = ScalableType.values()[resizeModeOrdinal];
|
||||||
|
|
||||||
try {
|
if (mPrepared) {
|
||||||
final ResizeMode resizeMode = ResizeMode.values()[resizeModeOrdinal];
|
final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
|
||||||
|
videoView.setScalableType(mResizeMode);
|
||||||
FrameLayout.LayoutParams layoutParams = null;
|
videoView.invalidate();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,35 +118,56 @@ public class ReactVideoViewManager extends SimpleViewManager<FrameLayout> {
|
|||||||
public void setRepeat(final FrameLayout container, final boolean repeat) {
|
public void setRepeat(final FrameLayout container, final boolean repeat) {
|
||||||
mRepeat = repeat;
|
mRepeat = repeat;
|
||||||
|
|
||||||
if (!mRepeat) { return; }
|
if (mPrepared) {
|
||||||
|
final ScalableVideoView videoView = (ScalableVideoView) container.getChildAt(0);
|
||||||
final VideoView videoView = (VideoView) container.getChildAt(0);
|
videoView.setLooping(mRepeat);
|
||||||
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
}
|
||||||
@Override
|
|
||||||
public void onCompletion(MediaPlayer mp) {
|
|
||||||
|
|
||||||
if (mRepeat) {
|
|
||||||
mp.seekTo(0);
|
|
||||||
setPaused(container, mPaused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_PAUSED)
|
@ReactProp(name = PROP_PAUSED)
|
||||||
public void setPaused(final FrameLayout container, final boolean 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;
|
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) {
|
private void applyModifiers(final FrameLayout container) {
|
||||||
|
setResizeMode(container, mResizeMode.ordinal());
|
||||||
setRepeat(container, mRepeat);
|
setRepeat(container, mRepeat);
|
||||||
setPaused(container, mPaused);
|
setPaused(container, mPaused);
|
||||||
|
setMuted(container, mMuted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user