Update ExoPlayer to r2.2.0 (#505)
This commit is contained in:
parent
5a4730cb8c
commit
e76936b4fc
@ -12,8 +12,8 @@ android {
|
||||
|
||||
dependencies {
|
||||
provided 'com.facebook.react:react-native:+'
|
||||
compile 'com.google.android.exoplayer:exoplayer:r2.1.1'
|
||||
compile('com.google.android.exoplayer:extension-okhttp:r2.1.1') {
|
||||
compile 'com.google.android.exoplayer:exoplayer:r2.2.0'
|
||||
compile('com.google.android.exoplayer:extension-okhttp:r2.2.0') {
|
||||
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
|
||||
}
|
||||
compile 'com.squareup.okhttp3:okhttp:3.4.2'
|
||||
|
@ -28,6 +28,7 @@ import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer;
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataRenderer;
|
||||
import com.google.android.exoplayer2.source.BehindLiveWindowException;
|
||||
import com.google.android.exoplayer2.source.ExtractorMediaSource;
|
||||
import com.google.android.exoplayer2.source.LoopingMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
@ -51,14 +52,12 @@ import java.net.CookieManager;
|
||||
import java.net.CookiePolicy;
|
||||
|
||||
@SuppressLint("ViewConstructor")
|
||||
|
||||
class ReactExoplayerView extends FrameLayout implements
|
||||
LifecycleEventListener,
|
||||
ExoPlayer.EventListener,
|
||||
BecomingNoisyListener,
|
||||
AudioManager.OnAudioFocusChangeListener,
|
||||
MetadataRenderer.Output
|
||||
{
|
||||
MetadataRenderer.Output {
|
||||
|
||||
private static final String TAG = "ReactExoplayerView";
|
||||
|
||||
@ -74,7 +73,6 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
private final VideoEventEmitter eventEmitter;
|
||||
|
||||
private Handler mainHandler;
|
||||
private Timeline.Window window;
|
||||
private ExoPlayerView exoPlayerView;
|
||||
|
||||
private DataSource.Factory mediaDataSourceFactory;
|
||||
@ -82,13 +80,11 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
private MappingTrackSelector trackSelector;
|
||||
private boolean playerNeedsSource;
|
||||
|
||||
private boolean shouldRestorePosition;
|
||||
private int playerWindow;
|
||||
private long playerPosition;
|
||||
private int resumeWindow;
|
||||
private long resumePosition;
|
||||
private boolean loadVideoStarted;
|
||||
private boolean isPaused = true;
|
||||
private boolean isBuffering;
|
||||
private boolean isTimelineStatic;
|
||||
|
||||
// Props from React
|
||||
private Uri srcUri;
|
||||
@ -129,6 +125,8 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
themedReactContext.addLifecycleEventListener(this);
|
||||
audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext);
|
||||
|
||||
initializePlayer();
|
||||
}
|
||||
|
||||
|
||||
@ -139,9 +137,9 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
}
|
||||
|
||||
private void createViews() {
|
||||
clearResumePosition();
|
||||
mediaDataSourceFactory = buildDataSourceFactory(true);
|
||||
mainHandler = new Handler();
|
||||
window = new Timeline.Window();
|
||||
if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
|
||||
CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
|
||||
}
|
||||
@ -199,13 +197,6 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
player.addListener(this);
|
||||
player.setMetadataOutput(this);
|
||||
exoPlayerView.setPlayer(player);
|
||||
if (isTimelineStatic) {
|
||||
if (playerPosition == C.TIME_UNSET) {
|
||||
player.seekToDefaultPosition(playerWindow);
|
||||
} else {
|
||||
player.seekTo(playerWindow, playerPosition);
|
||||
}
|
||||
}
|
||||
audioBecomingNoisyReceiver.setListener(this);
|
||||
setPlayWhenReady(!isPaused);
|
||||
playerNeedsSource = true;
|
||||
@ -213,7 +204,11 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
if (playerNeedsSource && srcUri != null) {
|
||||
MediaSource mediaSource = buildMediaSource(srcUri, extension);
|
||||
mediaSource = repeat ? new LoopingMediaSource(mediaSource) : mediaSource;
|
||||
player.prepare(mediaSource, !shouldRestorePosition, true);
|
||||
boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
|
||||
if (haveResumePosition) {
|
||||
player.seekTo(resumeWindow, resumePosition);
|
||||
}
|
||||
player.prepare(mediaSource, !haveResumePosition, false);
|
||||
playerNeedsSource = false;
|
||||
|
||||
eventEmitter.loadStart();
|
||||
@ -245,13 +240,7 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
private void releasePlayer() {
|
||||
if (player != null) {
|
||||
isPaused = player.getPlayWhenReady();
|
||||
shouldRestorePosition = false;
|
||||
playerWindow = player.getCurrentWindowIndex();
|
||||
playerPosition = C.TIME_UNSET;
|
||||
Timeline timeline = player.getCurrentTimeline();
|
||||
if (!timeline.isEmpty() && timeline.getWindow(playerWindow, window).isSeekable) {
|
||||
playerPosition = player.getCurrentPosition();
|
||||
}
|
||||
updateResumePosition();
|
||||
player.release();
|
||||
player.setMetadataOutput(null);
|
||||
player = null;
|
||||
@ -331,6 +320,17 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
audioManager.abandonAudioFocus(this);
|
||||
}
|
||||
|
||||
private void updateResumePosition() {
|
||||
resumeWindow = player.getCurrentWindowIndex();
|
||||
resumePosition = player.isCurrentWindowSeekable() ? Math.max(0, player.getCurrentPosition())
|
||||
: C.TIME_UNSET;
|
||||
}
|
||||
|
||||
private void clearResumePosition() {
|
||||
resumeWindow = C.INDEX_UNSET;
|
||||
resumePosition = C.TIME_UNSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new DataSource factory.
|
||||
*
|
||||
@ -442,13 +442,17 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {
|
||||
// Do nothing.
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
isTimelineStatic = !timeline.isEmpty()
|
||||
&& !timeline.getWindow(timeline.getWindowCount() - 1, window).isDynamic;
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -485,6 +489,26 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
eventEmitter.error(errorString, e);
|
||||
}
|
||||
playerNeedsSource = true;
|
||||
if (isBehindLiveWindow(e)) {
|
||||
clearResumePosition();
|
||||
initializePlayer();
|
||||
} else {
|
||||
updateResumePosition();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBehindLiveWindow(ExoPlaybackException e) {
|
||||
if (e.type != ExoPlaybackException.TYPE_SOURCE) {
|
||||
return false;
|
||||
}
|
||||
Throwable cause = e.getSourceException();
|
||||
while (cause != null) {
|
||||
if (cause instanceof BehindLiveWindowException) {
|
||||
return true;
|
||||
}
|
||||
cause = cause.getCause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,14 +9,11 @@ import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.BinaryFrame;
|
||||
import com.google.android.exoplayer2.metadata.id3.Id3Frame;
|
||||
import com.google.android.exoplayer2.metadata.id3.TxxxFrame;
|
||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class VideoEventEmitter {
|
||||
|
||||
@ -191,8 +188,8 @@ class VideoEventEmitter {
|
||||
|
||||
String value = "";
|
||||
|
||||
if (frame instanceof TxxxFrame) {
|
||||
TxxxFrame txxxFrame = (TxxxFrame) frame;
|
||||
if (frame instanceof TextInformationFrame) {
|
||||
TextInformationFrame txxxFrame = (TextInformationFrame) frame;
|
||||
value = txxxFrame.value;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user