[Android] Fix MediaPlayer issues

This commit is contained in:
Baris Sencan 2015-11-13 16:06:42 -08:00
parent 6ddd157f58
commit 9f73f22c62

View File

@ -34,18 +34,31 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
} }
} }
public static final String EVENT_PROP_DURATION = "duration";
public static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
public static final String EVENT_PROP_CURRENT_TIME = "currentTime";
public static final String EVENT_PROP_SEEK_TIME = "seekTime";
public static final String EVENT_PROP_ERROR = "error";
public static final String EVENT_PROP_WHAT = "what";
public static final String EVENT_PROP_EXTRA = "extra";
private ThemedReactContext mThemedReactContext; private ThemedReactContext mThemedReactContext;
private RCTEventEmitter mEventEmitter; private RCTEventEmitter mEventEmitter;
private Handler mProgressUpdateHandler = new Handler(); private Handler mProgressUpdateHandler = new Handler();
private Runnable mProgressUpdateRunnable = null; private Runnable mProgressUpdateRunnable = null;
private String mUriString = null;
private boolean mIsNetwork = false;
private ScalableType mResizeMode = ScalableType.LEFT_TOP; 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 boolean mMuted = false;
private float mVolume = 1; private float mVolume = 1;
private boolean mMediaPlayerValid = false; // True if mMediaPlayer is in prepared, started, or paused state.
private int mVideoDuration = 0;
public ReactVideoView(ThemedReactContext themedReactContext) { public ReactVideoView(ThemedReactContext themedReactContext) {
super(themedReactContext); super(themedReactContext);
@ -55,22 +68,22 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
initializeMediaPlayerIfNeeded(); initializeMediaPlayerIfNeeded();
setSurfaceTextureListener(this); setSurfaceTextureListener(this);
final MediaPlayer mediaPlayer = mMediaPlayer;
mProgressUpdateRunnable = new Runnable() { mProgressUpdateRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (mMediaPlayerValid) {
try { try {
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
// TODO: Other event properties. // TODO: Other event properties.
event.putDouble("currentTime", (double) mediaPlayer.getCurrentPosition() / (double) 1000); event.putDouble(EVENT_PROP_CURRENT_TIME, mMediaPlayer.getCurrentPosition() / 1000.0);
event.putDouble("duration", (double) mediaPlayer.getDuration() / (double) 1000); event.putDouble(EVENT_PROP_DURATION, mVideoDuration / 1000.0);
event.putDouble("playableDuration", (double) mediaPlayer.getDuration() / (double) 1000); event.putDouble(EVENT_PROP_PLAYABLE_DURATION, mVideoDuration/ 1000.0);
mEventEmitter.receiveEvent(getId(), Events.EVENT_PROGRESS.toString(), event); mEventEmitter.receiveEvent(getId(), Events.EVENT_PROGRESS.toString(), event);
} catch (Exception e) { } catch (Exception e) {
// Do nothing. // Do nothing.
} }
}
mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250); mProgressUpdateHandler.postDelayed(mProgressUpdateRunnable, 250);
} }
}; };
@ -79,6 +92,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
private void initializeMediaPlayerIfNeeded() { private void initializeMediaPlayerIfNeeded() {
if (mMediaPlayer == null) { if (mMediaPlayer == null) {
mMediaPlayerValid = false;
mMediaPlayer = new MediaPlayer(); mMediaPlayer = new MediaPlayer();
mMediaPlayer.setScreenOnWhilePlaying(true); mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this);
@ -89,6 +103,13 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
} }
public void setSrc(final String uriString, final boolean isNetwork) throws IOException { public void setSrc(final String uriString, final boolean isNetwork) throws IOException {
mUriString = uriString;
mIsNetwork = isNetwork;
mMediaPlayerValid = false;
mVideoDuration = 0;
initializeMediaPlayerIfNeeded();
mMediaPlayer.reset(); mMediaPlayer.reset();
if (isNetwork) { if (isNetwork) {
@ -106,37 +127,45 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
public void setResizeModeModifier(final ScalableType resizeMode) { public void setResizeModeModifier(final ScalableType resizeMode) {
mResizeMode = resizeMode; mResizeMode = resizeMode;
initializeMediaPlayerIfNeeded();
if (mMediaPlayerValid) {
setScalableType(resizeMode); setScalableType(resizeMode);
invalidate(); invalidate();
} }
}
public void setRepeatModifier(final boolean repeat) { public void setRepeatModifier(final boolean repeat) {
mRepeat = repeat; mRepeat = repeat;
initializeMediaPlayerIfNeeded();
if (mMediaPlayerValid) {
setLooping(repeat); setLooping(repeat);
} }
}
public void setPausedModifier(final boolean paused) { public void setPausedModifier(final boolean paused) {
mPaused = paused; mPaused = paused;
try { if (!mMediaPlayerValid) {
initializeMediaPlayerIfNeeded(); return;
}
if (!mPaused) { if (mPaused) {
start(); if (mMediaPlayer.isPlaying()) {
} else {
pause(); pause();
} }
} catch (Exception e) { } else {
e.printStackTrace(); if (!mMediaPlayer.isPlaying()) {
start();
}
} }
} }
public void setMutedModifier(final boolean muted) { public void setMutedModifier(final boolean muted) {
mMuted = muted; mMuted = muted;
initializeMediaPlayerIfNeeded(); if (!mMediaPlayerValid) {
return;
}
if (mMuted) { if (mMuted) {
setVolume(0, 0); setVolume(0, 0);
@ -147,7 +176,6 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
public void setVolumeModifier(final float volume) { public void setVolumeModifier(final float volume) {
mVolume = volume; mVolume = volume;
initializeMediaPlayerIfNeeded();
setMutedModifier(mMuted); setMutedModifier(mMuted);
} }
@ -155,14 +183,17 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
setResizeModeModifier(mResizeMode); setResizeModeModifier(mResizeMode);
setRepeatModifier(mRepeat); setRepeatModifier(mRepeat);
setPausedModifier(mPaused); setPausedModifier(mPaused);
setVolumeModifier(mVolume); setMutedModifier(mMuted);
} }
@Override @Override
public void onPrepared(MediaPlayer mp) { public void onPrepared(MediaPlayer mp) {
mMediaPlayerValid = true;
mVideoDuration = mp.getDuration();
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putDouble("duration", (double) mp.getDuration() / (double) 1000); event.putDouble(EVENT_PROP_DURATION, mVideoDuration / 1000.0);
event.putDouble("currentTime", (double) mp.getCurrentPosition() / (double) 1000); event.putDouble(EVENT_PROP_CURRENT_TIME, mp.getCurrentPosition() / 1000.0);
// TODO: Add canX properties. // TODO: Add canX properties.
mEventEmitter.receiveEvent(getId(), Events.EVENT_LOAD.toString(), event); mEventEmitter.receiveEvent(getId(), Events.EVENT_LOAD.toString(), event);
@ -172,10 +203,10 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
@Override @Override
public boolean onError(MediaPlayer mp, int what, int extra) { public boolean onError(MediaPlayer mp, int what, int extra) {
WritableMap error = Arguments.createMap(); WritableMap error = Arguments.createMap();
error.putInt("what", what); error.putInt(EVENT_PROP_WHAT, what);
error.putInt("extra", extra); error.putInt(EVENT_PROP_EXTRA, extra);
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putMap("error", error); event.putMap(EVENT_PROP_ERROR, error);
mEventEmitter.receiveEvent(getId(), Events.EVENT_ERROR.toString(), event); mEventEmitter.receiveEvent(getId(), Events.EVENT_ERROR.toString(), event);
return true; return true;
} }
@ -183,8 +214,8 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
@Override @Override
public void seekTo(int msec) { public void seekTo(int msec) {
WritableMap event = Arguments.createMap(); WritableMap event = Arguments.createMap();
event.putDouble("currentTime", (double) getCurrentPosition() / (double) 1000); event.putDouble(EVENT_PROP_CURRENT_TIME, getCurrentPosition() / 1000.0);
event.putDouble("seekTime", (double) msec / (double) 1000); event.putDouble(EVENT_PROP_SEEK_TIME, msec / 1000.0);
mEventEmitter.receiveEvent(getId(), Events.EVENT_SEEK.toString(), event); mEventEmitter.receiveEvent(getId(), Events.EVENT_SEEK.toString(), event);
super.seekTo(msec); super.seekTo(msec);
@ -192,6 +223,24 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP
@Override @Override
public void onCompletion(MediaPlayer mp) { public void onCompletion(MediaPlayer mp) {
mMediaPlayerValid = false;
mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null); mEventEmitter.receiveEvent(getId(), Events.EVENT_END.toString(), null);
} }
@Override
protected void onDetachedFromWindow() {
mMediaPlayerValid = false;
super.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
try {
setSrc(mUriString, mIsNetwork);
} catch (Exception e) {
e.printStackTrace();
}
}
} }