handle racing conditions when props are setted on exoplayer

This commit is contained in:
Daniel Mariño 2019-07-07 10:21:23 +02:00
parent 3a7be63de3
commit 466c004837
2 changed files with 56 additions and 44 deletions

View File

@ -1,5 +1,8 @@
## Changelog ## Changelog
### next
* Handle racing conditions when props are setted on exoplayer
### Version 4.4.2 ### Version 4.4.2
* Change compileOnly to implementation on gradle (for newer gradle versions and react-native 0.59 support) [#1592](https://github.com/react-native-community/react-native-video/pull/1592) * Change compileOnly to implementation on gradle (for newer gradle versions and react-native 0.59 support) [#1592](https://github.com/react-native-community/react-native-video/pull/1592)
* Replaced RCTBubblingEventBlock events by RCTDirectEventBlock to avoid event name collisions [#1625](https://github.com/react-native-community/react-native-video/pull/1625) * Replaced RCTBubblingEventBlock events by RCTDirectEventBlock to avoid event name collisions [#1625](https://github.com/react-native-community/react-native-video/pull/1625)

View File

@ -333,53 +333,60 @@ class ReactExoplayerView extends FrameLayout implements
} }
private void initializePlayer() { private void initializePlayer() {
if (player == null) { ReactExoplayerView self = this;
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); new Handler().postDelayed(new Runnable() {
trackSelector.setParameters(trackSelector.buildUponParameters() @Override
public void run() {
if (player == null) {
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelector.setParameters(trackSelector.buildUponParameters()
.setMaxVideoBitrate(maxBitRate == 0 ? Integer.MAX_VALUE : maxBitRate)); .setMaxVideoBitrate(maxBitRate == 0 ? Integer.MAX_VALUE : maxBitRate));
DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE); DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);
DefaultLoadControl defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true); DefaultLoadControl defaultLoadControl = new DefaultLoadControl(allocator, minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, -1, true);
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl); player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, defaultLoadControl);
player.addListener(this); player.addListener(self);
player.setMetadataOutput(this); player.setMetadataOutput(self);
exoPlayerView.setPlayer(player); exoPlayerView.setPlayer(player);
audioBecomingNoisyReceiver.setListener(this); audioBecomingNoisyReceiver.setListener(self);
BANDWIDTH_METER.addEventListener(new Handler(), this); BANDWIDTH_METER.addEventListener(new Handler(), self);
setPlayWhenReady(!isPaused); setPlayWhenReady(!isPaused);
playerNeedsSource = true; playerNeedsSource = true;
PlaybackParameters params = new PlaybackParameters(rate, 1f); PlaybackParameters params = new PlaybackParameters(rate, 1f);
player.setPlaybackParameters(params); player.setPlaybackParameters(params);
} }
if (playerNeedsSource && srcUri != null) { if (playerNeedsSource && srcUri != null) {
ArrayList<MediaSource> mediaSourceList = buildTextSources(); ArrayList<MediaSource> mediaSourceList = buildTextSources();
MediaSource videoSource = buildMediaSource(srcUri, extension); MediaSource videoSource = buildMediaSource(srcUri, extension);
MediaSource mediaSource; MediaSource mediaSource;
if (mediaSourceList.size() == 0) { if (mediaSourceList.size() == 0) {
mediaSource = videoSource; mediaSource = videoSource;
} else { } else {
mediaSourceList.add(0, videoSource); mediaSourceList.add(0, videoSource);
MediaSource[] textSourceArray = mediaSourceList.toArray( MediaSource[] textSourceArray = mediaSourceList.toArray(
new MediaSource[mediaSourceList.size()] new MediaSource[mediaSourceList.size()]
); );
mediaSource = new MergingMediaSource(textSourceArray); mediaSource = new MergingMediaSource(textSourceArray);
}
boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
if (haveResumePosition) {
player.seekTo(resumeWindow, resumePosition);
}
player.prepare(mediaSource, !haveResumePosition, false);
playerNeedsSource = false;
eventEmitter.loadStart();
loadVideoStarted = true;
}
// Initializing the playerControlView
initializePlayerControl();
} }
}, 1);
boolean haveResumePosition = resumeWindow != C.INDEX_UNSET;
if (haveResumePosition) {
player.seekTo(resumeWindow, resumePosition);
}
player.prepare(mediaSource, !haveResumePosition, false);
playerNeedsSource = false;
eventEmitter.loadStart();
loadVideoStarted = true;
}
// Initializing the playerControlView
initializePlayerControl();
} }
private MediaSource buildMediaSource(Uri uri, String overrideExtension) { private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
@ -439,8 +446,9 @@ class ReactExoplayerView extends FrameLayout implements
updateResumePosition(); updateResumePosition();
player.release(); player.release();
player.setMetadataOutput(null); player.setMetadataOutput(null);
player = null;
trackSelector = null; trackSelector = null;
player = null;
} }
progressHandler.removeMessages(SHOW_PROGRESS); progressHandler.removeMessages(SHOW_PROGRESS);
themedReactContext.removeLifecycleEventListener(this); themedReactContext.removeLifecycleEventListener(this);
@ -906,6 +914,7 @@ class ReactExoplayerView extends FrameLayout implements
} }
public void setSelectedTrack(int trackType, String type, Dynamic value) { public void setSelectedTrack(int trackType, String type, Dynamic value) {
if (player == null) return;
int rendererIndex = getTrackRendererIndex(trackType); int rendererIndex = getTrackRendererIndex(trackType);
if (rendererIndex == C.INDEX_UNSET) { if (rendererIndex == C.INDEX_UNSET) {
return; return;