[Android] Move events inside RCTVideoView

This commit is contained in:
Baris Sencan 2015-11-11 13:37:35 -08:00
parent 125b99deba
commit 9e9e45c1a5
2 changed files with 95 additions and 54 deletions

View File

@ -1,6 +1,5 @@
package com.brentvatne.react; package com.brentvatne.react;
import android.content.Context;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.os.Handler; import android.os.Handler;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
@ -10,9 +9,31 @@ import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.yqritc.scalablevideoview.ScalableType; import com.yqritc.scalablevideoview.ScalableType;
import com.yqritc.scalablevideoview.ScalableVideoView; import com.yqritc.scalablevideoview.ScalableVideoView;
public class ReactVideoView extends ScalableVideoView { public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnPreparedListener, MediaPlayer
.OnErrorListener, MediaPlayer.OnCompletionListener {
public enum Events {
EVENT_LOAD_START("onVideoLoadStart"),
EVENT_LOAD("onVideoLoad"),
EVENT_ERROR("onVideoError"),
EVENT_PROGRESS("onVideoProgress"),
EVENT_SEEK("onVideoSeek"),
EVENT_END("onVideoEnd");
private final String mName;
Events(final String name) {
mName = name;
}
@Override
public String toString() {
return mName;
}
}
private ThemedReactContext mThemedReactContext; private ThemedReactContext mThemedReactContext;
private RCTEventEmitter mEventEmitter;
private Handler mProgressUpdateHandler = new Handler(); private Handler mProgressUpdateHandler = new Handler();
private Runnable mProgressUpdateRunnable = null; private Runnable mProgressUpdateRunnable = null;
@ -27,22 +48,26 @@ public class ReactVideoView extends ScalableVideoView {
super(themedReactContext); super(themedReactContext);
mThemedReactContext = themedReactContext; mThemedReactContext = themedReactContext;
mEventEmitter = themedReactContext.getJSModule(RCTEventEmitter.class);
mMediaPlayer = new MediaPlayer(); initializeMediaPlayerIfNeeded();
mMediaPlayer.setOnVideoSizeChangedListener(this);
setSurfaceTextureListener(this); setSurfaceTextureListener(this);
final MediaPlayer mediaPlayer = mMediaPlayer;
mProgressUpdateRunnable = new Runnable() { mProgressUpdateRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
final RCTEventEmitter eventEmitter = getEventEmitter();
if (mMediaPlayer.isPlaying()) { try {
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
// TODO: Other event properties. // TODO: Other event properties.
event.putDouble("currentTime", (double) mMediaPlayer.getCurrentPosition() / (double) 1000); event.putDouble("currentTime", (double) mediaPlayer.getCurrentPosition() / (double) 1000);
event.putDouble("duration", (double) mMediaPlayer.getDuration() / (double) 1000); event.putDouble("duration", (double) mediaPlayer.getDuration() / (double) 1000);
eventEmitter.receiveEvent(getId(), ReactVideoViewManager.EVENT_PROGRESS, event); event.putDouble("playableDuration", (double) mediaPlayer.getDuration() / (double) 1000);
mEventEmitter.receiveEvent(getId(), Events.EVENT_PROGRESS.toString(), event);
} catch (Exception e) {
// Do nothing.
} }
mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250); mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250);
} }
@ -50,8 +75,14 @@ public class ReactVideoView extends ScalableVideoView {
mProgressUpdateHandler.post(mProgressUpdateRunnable); mProgressUpdateHandler.post(mProgressUpdateRunnable);
} }
private RCTEventEmitter getEventEmitter() { private void initializeMediaPlayerIfNeeded() {
return mThemedReactContext.getJSModule(RCTEventEmitter.class); if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnPreparedListener(this);
}
} }
public void reset() { public void reset() {
@ -60,12 +91,14 @@ public class ReactVideoView extends ScalableVideoView {
public void setResizeModeModifier(final ScalableType resizeMode) { public void setResizeModeModifier(final ScalableType resizeMode) {
mResizeMode = resizeMode; mResizeMode = resizeMode;
initializeMediaPlayerIfNeeded();
setScalableType(resizeMode); setScalableType(resizeMode);
invalidate(); invalidate();
} }
public void setRepeatModifier(final boolean repeat) { public void setRepeatModifier(final boolean repeat) {
mRepeat = repeat; mRepeat = repeat;
initializeMediaPlayerIfNeeded();
setLooping(repeat); setLooping(repeat);
} }
@ -73,6 +106,8 @@ public class ReactVideoView extends ScalableVideoView {
mPaused = paused; mPaused = paused;
try { try {
initializeMediaPlayerIfNeeded();
if (!mPaused) { if (!mPaused) {
start(); start();
} else { } else {
@ -86,6 +121,8 @@ public class ReactVideoView extends ScalableVideoView {
public void setMutedModifier(final boolean muted) { public void setMutedModifier(final boolean muted) {
mMuted = muted; mMuted = muted;
initializeMediaPlayerIfNeeded();
if (mMuted) { if (mMuted) {
setVolume(0, 0); setVolume(0, 0);
} else { } else {
@ -95,6 +132,7 @@ public class ReactVideoView extends ScalableVideoView {
public void setVolumeModifier(final float volume) { public void setVolumeModifier(final float volume) {
mVolume = volume; mVolume = volume;
initializeMediaPlayerIfNeeded();
setMutedModifier(mMuted); setMutedModifier(mMuted);
} }
@ -104,4 +142,41 @@ public class ReactVideoView extends ScalableVideoView {
setPausedModifier(mPaused); setPausedModifier(mPaused);
setVolumeModifier(mVolume); setVolumeModifier(mVolume);
} }
@Override
public void onPrepared(MediaPlayer mp) {
WritableMap event = Arguments.createMap();
event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
// TODO: Add canX properties.
mEventEmitter.receiveEvent(getId(), Events.EVENT_LOAD.toString(), event);
applyModifiers();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
WritableMap error = Arguments.createMap();
error.putInt("what", what);
error.putInt("extra", extra);
WritableMap event = Arguments.createMap();
event.putMap("error", error);
mEventEmitter.receiveEvent(getId(), Events.EVENT_ERROR.toString(), event);
return true;
}
@Override
public void seekTo(int msec) {
WritableMap event = Arguments.createMap();
event.putDouble("currentTime", (double) getCurrentPosition() / (double) 1000);
event.putDouble("seekTime", (double) msec / (double) 1000);
mEventEmitter.receiveEvent(getId(), Events.EVENT_SEEK.toString(), event);
super.seekTo(msec);
}
@Override
public void onCompletion(MediaPlayer mp) {
mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null);
}
} }

View File

@ -1,7 +1,7 @@
package com.brentvatne.react; package com.brentvatne.react;
import android.content.Context; import android.content.Context;
import android.media.MediaPlayer; import com.brentvatne.react.ReactVideoView.Events;
import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
@ -29,11 +29,6 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
public static final String PROP_MUTED = "muted"; public static final String PROP_MUTED = "muted";
public static final String PROP_VOLUME = "volume"; public static final String PROP_VOLUME = "volume";
public static final String EVENT_LOAD_START = "onVideoLoadStart";
public static final String EVENT_LOAD = "onVideoLoad";
public static final String EVENT_PROGRESS = "onVideoProgress";
public static final String EVENT_END = "onVideoEnd";
@Override @Override
public String getName() { public String getName() {
return REACT_CLASS; return REACT_CLASS;
@ -47,12 +42,11 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
@Override @Override
@Nullable @Nullable
public Map getExportedCustomDirectEventTypeConstants() { public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.builder() MapBuilder.Builder builder = MapBuilder.builder();
.put(EVENT_LOAD_START, MapBuilder.of("registrationName", EVENT_LOAD_START)) for (Events event : Events.values()) {
.put(EVENT_LOAD, MapBuilder.of("registrationName", EVENT_LOAD)) builder.put(event.toString(), MapBuilder.of("registrationName", event.toString()));
.put(EVENT_PROGRESS, MapBuilder.of("registrationName", EVENT_PROGRESS)) }
.put(EVENT_END, MapBuilder.of("registrationName", EVENT_END)) return builder.build();
.build();
} }
@Override @Override
@ -91,39 +85,11 @@ public class ReactVideoViewManager extends SimpleViewManager<ReactVideoView> {
writableSrc.putBoolean(PROP_SRC_IS_NETWORK, isNetwork); writableSrc.putBoolean(PROP_SRC_IS_NETWORK, isNetwork);
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putMap(PROP_SRC, writableSrc); event.putMap(PROP_SRC, writableSrc);
eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD_START, event); eventEmitter.receiveEvent(videoView.getId(), Events.EVENT_LOAD_START.toString(), event);
videoView.prepare(new MediaPlayer.OnPreparedListener() { videoView.prepare();
@Override
public void onPrepared(final MediaPlayer mp) {
mp.setScreenOnWhilePlaying(true);
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO: onVideoError
return false;
}
});
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
eventEmitter.receiveEvent(videoView.getId(), EVENT_END, null);
}
});
WritableMap event = Arguments.createMap();
event.putDouble("duration", (double) mp.getDuration() / (double) 1000);
event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000);
// TODO: Add canX properties.
eventEmitter.receiveEvent(videoView.getId(), EVENT_LOAD, event);
videoView.applyModifiers();
}
});
} catch (Exception e) { } catch (Exception e) {
// TODO: onVideoError e.printStackTrace();
} }
} }