Merge branch 'master' into master

This commit is contained in:
Hampton Maxwell
2018-05-29 15:08:24 -07:00
committed by GitHub
16 changed files with 278 additions and 92 deletions

View File

@@ -12,9 +12,9 @@ android {
dependencies {
provided 'com.facebook.react:react-native:+'
compile 'com.google.android.exoplayer:exoplayer:r2.4.0'
compile('com.google.android.exoplayer:extension-okhttp:r2.4.0') {
compile 'com.google.android.exoplayer:exoplayer:2.7.3'
compile('com.google.android.exoplayer:extension-okhttp:2.7.3') {
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.4.2'
compile 'com.squareup.okhttp3:okhttp:3.9.1'
}

View File

@@ -27,6 +27,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.SubtitleView;
import java.util.List;
import java.lang.Object;
@TargetApi(16)
public final class ExoPlayerView extends FrameLayout {
@@ -212,12 +213,12 @@ public final class ExoPlayerView extends FrameLayout {
}
@Override
public void onPositionDiscontinuity() {
public void onPositionDiscontinuity(int reason) {
// Do nothing.
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
// Do nothing.
}
@@ -235,6 +236,21 @@ public final class ExoPlayerView extends FrameLayout {
public void onMetadata(Metadata metadata) {
Log.d("onMetadata", "onMetadata");
}
@Override
public void onSeekProcessed() {
// Do nothing.
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
// Do nothing.
}
@Override
public void onRepeatModeChanged(int repeatMode) {
// Do nothing.
}
}
}

View File

@@ -1,6 +1,7 @@
package com.brentvatne.exoplayer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.net.Uri;
@@ -8,6 +9,8 @@ import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import com.brentvatne.react.R;
@@ -23,6 +26,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
@@ -54,6 +58,7 @@ import java.net.CookieManager;
import java.net.CookiePolicy;
import java.lang.Math;
import java.util.Map;
import java.lang.Object;
@SuppressLint("ViewConstructor")
class ReactExoplayerView extends FrameLayout implements
@@ -87,6 +92,7 @@ class ReactExoplayerView extends FrameLayout implements
private int resumeWindow;
private long resumePosition;
private boolean loadVideoStarted;
private boolean isFullscreen;
private boolean isPaused = true;
private boolean isBuffering;
private float rate = 1f;
@@ -116,7 +122,8 @@ class ReactExoplayerView extends FrameLayout implements
&& player.getPlayWhenReady()
) {
long pos = player.getCurrentPosition();
eventEmitter.progressChanged(pos, player.getBufferedPercentage());
long bufferedDuration = player.getBufferedPercentage() * player.getDuration();
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration());
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, Math.round(mProgressUpdateInterval));
}
@@ -333,6 +340,9 @@ class ReactExoplayerView extends FrameLayout implements
}
private void onStopPlayback() {
if (isFullscreen) {
setFullscreen(false);
}
setKeepScreenOn(false);
audioManager.abandonAudioFocus(this);
}
@@ -458,17 +468,38 @@ class ReactExoplayerView extends FrameLayout implements
}
@Override
public void onPositionDiscontinuity() {
public void onPositionDiscontinuity(int reason) {
if (playerNeedsSource) {
// This will only occur if the user has performed a seek whilst in the error state. Update the
// resume position so that if the user then retries, playback will resume from the position to
// which they seeked.
updateResumePosition();
}
// When repeat is turned on, reaching the end of the video will not cause a state change
// so we need to explicitly detect it.
if (reason == ExoPlayer.DISCONTINUITY_REASON_PERIOD_TRANSITION
&& player.getRepeatMode() == Player.REPEAT_MODE_ONE) {
eventEmitter.end();
}
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
// Do nothing.
}
@Override
public void onSeekProcessed() {
// Do nothing.
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
// Do nothing.
}
@Override
public void onRepeatModeChanged(int repeatMode) {
// Do nothing.
}
@@ -485,6 +516,7 @@ class ReactExoplayerView extends FrameLayout implements
@Override
public void onPlayerError(ExoPlaybackException e) {
String errorString = null;
Exception ex = e;
if (e.type == ExoPlaybackException.TYPE_RENDERER) {
Exception cause = e.getRendererException();
if (cause instanceof MediaCodecRenderer.DecoderInitializationException) {
@@ -507,8 +539,12 @@ class ReactExoplayerView extends FrameLayout implements
}
}
}
else if (e.type == ExoPlaybackException.TYPE_SOURCE) {
ex = e.getSourceException();
errorString = getResources().getString(R.string.unrecognized_media_format);
}
if (errorString != null) {
eventEmitter.error(errorString, e);
eventEmitter.error(errorString, ex);
}
playerNeedsSource = true;
if (isBehindLiveWindow(e)) {
@@ -585,6 +621,13 @@ class ReactExoplayerView extends FrameLayout implements
}
public void setRepeatModifier(boolean repeat) {
if (player != null) {
if (repeat) {
player.setRepeatMode(Player.REPEAT_MODE_ONE);
} else {
player.setRepeatMode(Player.REPEAT_MODE_OFF);
}
}
this.repeat = repeat;
}
@@ -636,4 +679,37 @@ class ReactExoplayerView extends FrameLayout implements
public void setDisableFocus(boolean disableFocus) {
this.disableFocus = disableFocus;
}
public void setFullscreen(boolean fullscreen) {
if (fullscreen == isFullscreen) {
return; // Avoid generating events when nothing is changing
}
isFullscreen = fullscreen;
Activity activity = themedReactContext.getCurrentActivity();
if (activity == null) {
return;
}
Window window = activity.getWindow();
View decorView = window.getDecorView();
int uiOptions;
if (isFullscreen) {
if (Util.SDK_INT >= 19) { // 4.4+
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| SYSTEM_UI_FLAG_FULLSCREEN;
} else {
uiOptions = SYSTEM_UI_FLAG_HIDE_NAVIGATION
| SYSTEM_UI_FLAG_FULLSCREEN;
}
eventEmitter.fullscreenWillPresent();
decorView.setSystemUiVisibility(uiOptions);
eventEmitter.fullscreenDidPresent();
} else {
uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
eventEmitter.fullscreenWillDismiss();
decorView.setSystemUiVisibility(uiOptions);
eventEmitter.fullscreenDidDismiss();
}
}
}

View File

@@ -34,6 +34,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_RATE = "rate";
private static final String PROP_PLAY_IN_BACKGROUND = "playInBackground";
private static final String PROP_DISABLE_FOCUS = "disableFocus";
private static final String PROP_FULLSCREEN = "fullscreen";
@Override
public String getName() {
@@ -159,6 +160,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
videoView.setDisableFocus(disableFocus);
}
@ReactProp(name = PROP_FULLSCREEN, defaultBoolean = false)
public void setFullscreen(final ReactExoplayerView videoView, final boolean fullscreen) {
videoView.setFullscreen(fullscreen);
}
private boolean startsWithValidScheme(String uriString) {
return uriString.startsWith("http://")
|| uriString.startsWith("https://")

View File

@@ -31,6 +31,11 @@ class VideoEventEmitter {
private static final String EVENT_PROGRESS = "onVideoProgress";
private static final String EVENT_SEEK = "onVideoSeek";
private static final String EVENT_END = "onVideoEnd";
private static final String EVENT_FULLSCREEN_WILL_PRESENT = "onVideoFullscreenPlayerWillPresent";
private static final String EVENT_FULLSCREEN_DID_PRESENT = "onVideoFullscreenPlayerDidPresent";
private static final String EVENT_FULLSCREEN_WILL_DISMISS = "onVideoFullscreenPlayerWillDismiss";
private static final String EVENT_FULLSCREEN_DID_DISMISS = "onVideoFullscreenPlayerDidDismiss";
private static final String EVENT_STALLED = "onPlaybackStalled";
private static final String EVENT_RESUME = "onPlaybackResume";
private static final String EVENT_READY = "onReadyForDisplay";
@@ -48,6 +53,10 @@ class VideoEventEmitter {
EVENT_PROGRESS,
EVENT_SEEK,
EVENT_END,
EVENT_FULLSCREEN_WILL_PRESENT,
EVENT_FULLSCREEN_DID_PRESENT,
EVENT_FULLSCREEN_WILL_DISMISS,
EVENT_FULLSCREEN_DID_DISMISS,
EVENT_STALLED,
EVENT_RESUME,
EVENT_READY,
@@ -67,6 +76,10 @@ class VideoEventEmitter {
EVENT_PROGRESS,
EVENT_SEEK,
EVENT_END,
EVENT_FULLSCREEN_WILL_PRESENT,
EVENT_FULLSCREEN_DID_PRESENT,
EVENT_FULLSCREEN_WILL_DISMISS,
EVENT_FULLSCREEN_DID_DISMISS,
EVENT_STALLED,
EVENT_RESUME,
EVENT_READY,
@@ -89,6 +102,7 @@ class VideoEventEmitter {
private static final String EVENT_PROP_DURATION = "duration";
private static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration";
private static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration";
private static final String EVENT_PROP_CURRENT_TIME = "currentTime";
private static final String EVENT_PROP_SEEK_TIME = "seekTime";
private static final String EVENT_PROP_NATURAL_SIZE = "naturalSize";
@@ -141,10 +155,11 @@ class VideoEventEmitter {
receiveEvent(EVENT_LOAD, event);
}
void progressChanged(double currentPosition, double bufferedDuration) {
void progressChanged(double currentPosition, double bufferedDuration, double seekableDuration) {
WritableMap event = Arguments.createMap();
event.putDouble(EVENT_PROP_CURRENT_TIME, currentPosition / 1000D);
event.putDouble(EVENT_PROP_PLAYABLE_DURATION, bufferedDuration / 1000D);
event.putDouble(EVENT_PROP_SEEKABLE_DURATION, seekableDuration / 1000D);
receiveEvent(EVENT_PROGRESS, event);
}
@@ -173,6 +188,22 @@ class VideoEventEmitter {
receiveEvent(EVENT_END, null);
}
void fullscreenWillPresent() {
receiveEvent(EVENT_FULLSCREEN_WILL_PRESENT, null);
}
void fullscreenDidPresent() {
receiveEvent(EVENT_FULLSCREEN_DID_PRESENT, null);
}
void fullscreenWillDismiss() {
receiveEvent(EVENT_FULLSCREEN_WILL_DISMISS, null);
}
void fullscreenDidDismiss() {
receiveEvent(EVENT_FULLSCREEN_DID_DISMISS, null);
}
void error(String errorString, Exception exception) {
WritableMap error = Arguments.createMap();
error.putString(EVENT_PROP_ERROR_STRING, errorString);

View File

@@ -9,4 +9,6 @@
<string name="error_instantiating_decoder">Unable to instantiate decoder <xliff:g id="decoder_name">%1$s</xliff:g></string>
<string name="unrecognized_media_format">Unrecognized media format</string>
</resources>