bugreport.txt
So in my application, user can select different languages. Based on user preference I use different audio files to be merged with video files. Now, once the playlist starts playing the merged tracks, it randomly stops playing if the seekbar stops "buffering". I then have to manually touch the seekbar so it starts playing again. Note that this doesn't happen if I only use the video files without merging them. My files are all local (mp4 videos and mp3 audios) and stored on the device. The duration of the files are the same but I'm not sure if this has to be accurate to milliseconds.
This is how I setup the player:
// 1. Create a default TrackSelector
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
// 3. Create the player
mPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
// 4. Bind the player to View
mExoPlayerView.setPlayer(mPlayer);
// 5. Prepare the player
mDataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "My APP"), null);
mExtractorsFactory = new DefaultExtractorsFactory();
Here's the code for starting the player:
ArrayList<MediaSource> mediaSources = generateListVideos();
ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource(mediaSources.toArray(new MediaSource[mediaSources.size()]));
mPlayer.addListener(this);
mPlayer.prepare(concatenatedSource, true, true);
mPlayer.setPlayWhenReady(true);
I'm not if the problem is my media files or it's the use of MergingMediaSource that causes this issue. Any help would be appreciated.
I am using version 2.1.1 and I have seen the same issues on a Galaxy note 3 (4.3) and a LG G5 (7.0).
The most important piece of information we need here is exactly how you're building the MediaSource from the 9 files you provided via email (there's no MergingMediaSource anywhere in the sample code provided above). Can you please provide exact code for constructing a MediaSource out of the 9 files provided that will reproduce the issue?
Yeah sorry about that. You're absolutely right. here's the method that builds the MergingMediaSource:
private MediaSource getMergedMediaSource(String fileName, String language) {
Uri videoUri = getMediaUri(fileName, MP4_EXTENSION);
Uri audioUri = getMediaUri(fileName, MP3_EXTENSION, language);
MediaSource videoSource = new ExtractorMediaSource(videoUri, mDataSourceFactory, mExtractorsFactory, null, null);
MediaSource audioSource = new ExtractorMediaSource(audioUri, mDataSourceFactory, mExtractorsFactory, null, null);
return new MergingMediaSource(audioSource, videoSource);
}
Hope it helps
I think this is an issue with MergingMediaSource/MergingMediaPeriod, where the following sequence happens:
Step (1) and (2) is (sort of) working as intended. The biggest issue is that (3) should trigger a new onContinueLoadingRequested call to trigger Child A, but this doesn't happen. This results in the stuck buffering state. A secondary issue is that (2) doesn't do a good job of allowing parallel loading of the two children in the case that they're ExtractorMediaPeriod's.
An easy way to fix this is to modify the ExtractorMediaPeriod.onLoadCompleted method here to be:
@Override
public void onLoadCompleted(ExtractingLoadable loadable, long elapsedRealtimeMs,
long loadDurationMs) {
copyLengthFromLoader(loadable);
loadingFinished = true;
if (durationUs == C.TIME_UNSET) {
long largestQueuedTimestampUs = getLargestQueuedTimestampUs();
durationUs = largestQueuedTimestampUs == Long.MIN_VALUE ? 0
: largestQueuedTimestampUs + DEFAULT_LAST_SAMPLE_DURATION_US;
sourceListener.onSourceInfoRefreshed(
new SinglePeriodTimeline(durationUs, seekMap.isSeekable()), null);
}
callback.onContinueLoadingRequested(this);
}
Which is just adding the last line to the end of the method.
While I am trying to wrap my head around your previous comment, I tried your solution and it worked perfectly.
Most helpful comment
An easy way to fix this is to modify the ExtractorMediaPeriod.onLoadCompleted method here to be:
Which is just adding the last line to the end of the method.