[Android] Better code structure
This commit is contained in:
parent
86790349e3
commit
d174b1a465
107
android/src/main/java/com/brentvatne/react/ReactVideoView.java
Normal file
107
android/src/main/java/com/brentvatne/react/ReactVideoView.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package com.brentvatne.react;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.os.Handler;
|
||||||
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||||
|
import com.yqritc.scalablevideoview.ScalableType;
|
||||||
|
import com.yqritc.scalablevideoview.ScalableVideoView;
|
||||||
|
|
||||||
|
public class ReactVideoView extends ScalableVideoView {
|
||||||
|
|
||||||
|
private ThemedReactContext mThemedReactContext;
|
||||||
|
|
||||||
|
private Handler mProgressUpdateHandler = new Handler();
|
||||||
|
private Runnable mProgressUpdateRunnable = null;
|
||||||
|
|
||||||
|
private ScalableType mResizeMode = ScalableType.LEFT_TOP;
|
||||||
|
private boolean mRepeat = false;
|
||||||
|
private boolean mPaused = false;
|
||||||
|
private boolean mMuted = false;
|
||||||
|
private float mVolume = 1;
|
||||||
|
|
||||||
|
public ReactVideoView(ThemedReactContext themedReactContext) {
|
||||||
|
super(themedReactContext);
|
||||||
|
|
||||||
|
mThemedReactContext = themedReactContext;
|
||||||
|
|
||||||
|
mMediaPlayer = new MediaPlayer();
|
||||||
|
mMediaPlayer.setOnVideoSizeChangedListener(this);
|
||||||
|
setSurfaceTextureListener(this);
|
||||||
|
|
||||||
|
mProgressUpdateRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final RCTEventEmitter eventEmitter = getEventEmitter();
|
||||||
|
|
||||||
|
if (mMediaPlayer.isPlaying()) {
|
||||||
|
WritableMap event = Arguments.createMap();
|
||||||
|
// TODO: Other event properties.
|
||||||
|
event.putDouble("currentTime", (double) mMediaPlayer.getCurrentPosition() / (double) 1000);
|
||||||
|
event.putDouble("duration", (double) mMediaPlayer.getDuration() / (double) 1000);
|
||||||
|
eventEmitter.receiveEvent(getId(), ReactVideoViewManager.EVENT_PROGRESS, event);
|
||||||
|
}
|
||||||
|
mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mProgressUpdateHandler.post(mProgressUpdateRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RCTEventEmitter getEventEmitter() {
|
||||||
|
return mThemedReactContext.getJSModule(RCTEventEmitter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
mMediaPlayer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResizeModeModifier(final ScalableType resizeMode) {
|
||||||
|
mResizeMode = resizeMode;
|
||||||
|
setScalableType(resizeMode);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepeatModifier(final boolean repeat) {
|
||||||
|
mRepeat = repeat;
|
||||||
|
setLooping(repeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPausedModifier(final boolean paused) {
|
||||||
|
mPaused = paused;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!mPaused) {
|
||||||
|
start();
|
||||||
|
} else {
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMutedModifier(final boolean muted) {
|
||||||
|
mMuted = muted;
|
||||||
|
|
||||||
|
if (mMuted) {
|
||||||
|
setVolume(0, 0);
|
||||||
|
} else {
|
||||||
|
setVolume(mVolume, mVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolumeModifier(final float volume) {
|
||||||
|
mVolume = volume;
|
||||||
|
setMutedModifier(mMuted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyModifiers() {
|
||||||
|
setResizeModeModifier(mResizeMode);
|
||||||
|
setRepeatModifier(mRepeat);
|
||||||
|
setPausedModifier(mPaused);
|
||||||
|
setVolumeModifier(mVolume);
|
||||||
|
}
|
||||||
|
}
|
@ -11,30 +11,28 @@ import com.facebook.react.uimanager.SimpleViewManager;
|
|||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||||
import com.yqritc.scalablevideoview.ScalableType;
|
import com.yqritc.scalablevideoview.ScalableType;
|
||||||
import com.yqritc.scalablevideoview.ScalableVideoView;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertTrue;
|
public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
|
||||||
|
|
||||||
public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView> {
|
|
||||||
|
|
||||||
public static final String REACT_CLASS = "RCTVideo";
|
public static final String REACT_CLASS = "RCTVideo";
|
||||||
private static final String PROP_SRC = "src";
|
|
||||||
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 boolean mPrepared = false;
|
public static final String PROP_SRC = "src";
|
||||||
|
public static final String PROP_SRC_URI = "uri";
|
||||||
|
public static final String PROP_SRC_TYPE = "type";
|
||||||
|
public static final String PROP_SRC_IS_NETWORK = "isNetwork";
|
||||||
|
public static final String PROP_RESIZE_MODE = "resizeMode";
|
||||||
|
public static final String PROP_REPEAT = "repeat";
|
||||||
|
public static final String PROP_PAUSED = "paused";
|
||||||
|
public static final String PROP_MUTED = "muted";
|
||||||
|
public static final String PROP_VOLUME = "volume";
|
||||||
|
|
||||||
private ScalableType mResizeMode = ScalableType.LEFT_TOP;
|
public static final String EVENT_LOAD_START = "onVideoLoadStart";
|
||||||
private boolean mRepeat = false;
|
public static final String EVENT_LOAD = "onVideoLoad";
|
||||||
private boolean mPaused = false;
|
public static final String EVENT_PROGRESS = "onVideoProgress";
|
||||||
private boolean mMuted = false;
|
public static final String EVENT_END = "onVideoEnd";
|
||||||
private float mVolume = 1;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -42,17 +40,18 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ScalableVideoView createViewInstance(ThemedReactContext themedReactContext) {
|
protected ReactVideoView createViewInstance(ThemedReactContext themedReactContext) {
|
||||||
return new ScalableVideoView(themedReactContext);
|
return new ReactVideoView(themedReactContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Map getExportedCustomDirectEventTypeConstants() {
|
public Map getExportedCustomDirectEventTypeConstants() {
|
||||||
return MapBuilder.builder()
|
return MapBuilder.builder()
|
||||||
.put("onVideoLoadStart", MapBuilder.of("registrationName", "onVideoLoadStart"))
|
.put(EVENT_LOAD_START, MapBuilder.of("registrationName", EVENT_LOAD_START))
|
||||||
.put("onVideoLoad", MapBuilder.of("registrationName", "onVideoLoad"))
|
.put(EVENT_LOAD, MapBuilder.of("registrationName", EVENT_LOAD))
|
||||||
.put("onVideoEnd", MapBuilder.of("registrationName", "onVideoEnd"))
|
.put(EVENT_PROGRESS, MapBuilder.of("registrationName", EVENT_PROGRESS))
|
||||||
|
.put(EVENT_END, MapBuilder.of("registrationName", EVENT_END))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,27 +59,24 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
@Nullable
|
@Nullable
|
||||||
public Map getExportedViewConstants() {
|
public Map getExportedViewConstants() {
|
||||||
return MapBuilder.of(
|
return MapBuilder.of(
|
||||||
"ScaleNone", ScalableType.LEFT_TOP.ordinal(),
|
"ScaleNone", Integer.toString(ScalableType.LEFT_TOP.ordinal()),
|
||||||
"ScaleToFill", ScalableType.FIT_XY.ordinal(),
|
"ScaleToFill", Integer.toString(ScalableType.FIT_XY.ordinal()),
|
||||||
"ScaleAspectFit", ScalableType.FIT_CENTER.ordinal(),
|
"ScaleAspectFit", Integer.toString(ScalableType.FIT_CENTER.ordinal()),
|
||||||
"ScaleAspectFill", ScalableType.CENTER_CROP.ordinal()
|
"ScaleAspectFill", Integer.toString(ScalableType.CENTER_CROP.ordinal())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_SRC)
|
@ReactProp(name = PROP_SRC)
|
||||||
public void setSrc(final ScalableVideoView videoView, @Nullable ReadableMap src) {
|
public void setSrc(final ReactVideoView videoView, @Nullable ReadableMap src) {
|
||||||
final ThemedReactContext themedReactContext = (ThemedReactContext) videoView.getContext();
|
final ThemedReactContext themedReactContext = (ThemedReactContext) videoView.getContext();
|
||||||
final RCTEventEmitter eventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class);
|
final RCTEventEmitter eventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String uriString = src.getString("uri");
|
final String uriString = src.getString(PROP_SRC_URI);
|
||||||
final String type = src.getString("type");
|
final String type = src.getString(PROP_SRC_TYPE);
|
||||||
final boolean isNetwork = src.getBoolean("isNetwork");
|
final boolean isNetwork = src.getBoolean(PROP_SRC_IS_NETWORK);
|
||||||
|
|
||||||
if (mPrepared) {
|
videoView.reset();
|
||||||
videoView.stop();
|
|
||||||
mPrepared = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNetwork) {
|
if (isNetwork) {
|
||||||
videoView.setDataSource(uriString);
|
videoView.setDataSource(uriString);
|
||||||
@ -90,17 +86,17 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
}
|
}
|
||||||
|
|
||||||
WritableMap writableSrc = Arguments.createMap();
|
WritableMap writableSrc = Arguments.createMap();
|
||||||
writableSrc.putString("uri", uriString);
|
writableSrc.putString(PROP_SRC_URI, uriString);
|
||||||
writableSrc.putString("type", type);
|
writableSrc.putString(PROP_SRC_TYPE, type);
|
||||||
writableSrc.putBoolean("isNetwork", isNetwork);
|
writableSrc.putBoolean(PROP_SRC_IS_NETWORK, isNetwork);
|
||||||
WritableMap event = Arguments.createMap();
|
WritableMap event = Arguments.createMap();
|
||||||
event.putMap("src", writableSrc);
|
event.putMap(PROP_SRC, writableSrc);
|
||||||
eventEmitter.receiveEvent(videoView.getId(), "onVideoLoadStart", event);
|
eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD_START, event);
|
||||||
|
|
||||||
videoView.prepare(new MediaPlayer.OnPreparedListener() {
|
videoView.prepare(new MediaPlayer.OnPreparedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPrepared(MediaPlayer mp) {
|
public void onPrepared(final MediaPlayer mp) {
|
||||||
mPrepared = true;
|
mp.setScreenOnWhilePlaying(true);
|
||||||
|
|
||||||
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
|
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -113,7 +109,7 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCompletion(MediaPlayer mp) {
|
public void onCompletion(MediaPlayer mp) {
|
||||||
eventEmitter.receiveEvent(videoView.getId(), "onVideoEnd", null);
|
eventEmitter.receiveEvent(videoView.getId(), EVENT_END, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -121,9 +117,9 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
|
event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
|
||||||
event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
|
event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
|
||||||
// TODO: Add canX properties.
|
// TODO: Add canX properties.
|
||||||
eventEmitter.receiveEvent(videoView.getId(), "onVideoLoad", event);
|
eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD, event);
|
||||||
|
|
||||||
applyModifiers(videoView);
|
videoView.applyModifiers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -132,63 +128,27 @@ public class ReactVideoViewManager extends SimpleViewManager<ScalableVideoView>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_RESIZE_MODE)
|
@ReactProp(name = PROP_RESIZE_MODE)
|
||||||
public void setResizeMode(final ScalableVideoView videoView, final int resizeModeOrdinal) {
|
public void setResizeMode(final ReactVideoView videoView, final String resizeModeOrdinalString) {
|
||||||
mResizeMode = ScalableType.values()[resizeModeOrdinal];
|
videoView.setResizeModeModifier(ScalableType.values()[Integer.parseInt(resizeModeOrdinalString)]);
|
||||||
|
|
||||||
if (mPrepared) {
|
|
||||||
videoView.setScalableType(mResizeMode);
|
|
||||||
videoView.invalidate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_REPEAT)
|
@ReactProp(name = PROP_REPEAT)
|
||||||
public void setRepeat(final ScalableVideoView videoView, final boolean repeat) {
|
public void setRepeat(final ReactVideoView videoView, final boolean repeat) {
|
||||||
mRepeat = repeat;
|
videoView.setRepeatModifier(repeat);
|
||||||
|
|
||||||
if (mPrepared) {
|
|
||||||
videoView.setLooping(mRepeat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_PAUSED)
|
@ReactProp(name = PROP_PAUSED)
|
||||||
public void setPaused(final ScalableVideoView videoView, final boolean paused) {
|
public void setPaused(final ReactVideoView videoView, final boolean paused) {
|
||||||
mPaused = paused;
|
videoView.setPausedModifier(paused);
|
||||||
|
|
||||||
if (mPrepared) {
|
|
||||||
if (!mPaused) {
|
|
||||||
videoView.start();
|
|
||||||
} else {
|
|
||||||
videoView.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_MUTED)
|
@ReactProp(name = PROP_MUTED)
|
||||||
public void setMuted(final ScalableVideoView videoView, final boolean muted) {
|
public void setMuted(final ReactVideoView videoView, final boolean muted) {
|
||||||
mMuted = muted;
|
videoView.setMutedModifier(muted);
|
||||||
|
|
||||||
if (mPrepared) {
|
|
||||||
if (mMuted) {
|
|
||||||
videoView.setVolume(0, 0);
|
|
||||||
} else {
|
|
||||||
videoView.setVolume(mVolume, mVolume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactProp(name = PROP_VOLUME)
|
@ReactProp(name = PROP_VOLUME)
|
||||||
public void setVolume(final ScalableVideoView videoView, final float volume) {
|
public void setVolume(final ReactVideoView videoView, final float volume) {
|
||||||
mVolume = volume;
|
videoView.setVolumeModifier(volume);
|
||||||
|
|
||||||
if (mPrepared) {
|
|
||||||
videoView.setVolume(mVolume, mVolume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyModifiers(final ScalableVideoView videoView) {
|
|
||||||
setResizeMode(videoView, mResizeMode.ordinal());
|
|
||||||
setRepeat(videoView, mRepeat);
|
|
||||||
setPaused(videoView, mPaused);
|
|
||||||
setMuted(videoView, mMuted);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user