Loading android-exoplayer/build.gradle +2 −2 Changes for android-exoplayer/build.gradle: 2 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -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' Loading android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +51 −27 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java: 51 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading @@ -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; Loading @@ -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; Loading Loading @@ -129,6 +125,8 @@ class ReactExoplayerView extends FrameLayout implements audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); themedReactContext.addLifecycleEventListener(this); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); initializePlayer(); } Loading @@ -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); } Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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 Loading Loading @@ -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 Loading android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java +3 −6 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java: 3 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 Loading
android-exoplayer/build.gradle +2 −2 Changes for android-exoplayer/build.gradle: 2 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -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' Loading
android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +51 −27 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java: 51 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading @@ -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; Loading @@ -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; Loading Loading @@ -129,6 +125,8 @@ class ReactExoplayerView extends FrameLayout implements audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); themedReactContext.addLifecycleEventListener(this); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); initializePlayer(); } Loading @@ -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); } Loading Loading @@ -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; Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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. * Loading Loading @@ -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 Loading Loading @@ -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 Loading
android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java +3 −6 Changes for android-exoplayer/src/main/java/com/brentvatne/exoplayer/VideoEventEmitter.java: 3 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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