Open RamilGabdrakhmanov opened 4 years ago
Just an update.
I can repro the behavior using the button you added, and also by seeking through the progress bar. Sometimes it takes more than 2 seeks to raise the error, but the error is likely to be reproduced with a 3rd or 4th seek while paused.
In all cases, there's an exception thrown from ExoPlayerImplInternal.doSomeWork(). The renderers report they are not ready a few lines above, and then renderer.maybeThrowStreamError()
raises the exception because the stream
has stopped downloading due to the network being disconnected.
I need to dig this a bit further though, in my repros I've seen a few different reasons why a renderer reports it is not ready and need to verify which cases are buggy and which are working as expected.
[update with more findings]
I have found at least two ways to consistently trigger the behavior:
seekTo(0, 2000);
seekTo(0, 4000);
(cc @ojw28) Seeking to 4000
requires to search for a video key-frame before 4000
which is needed by the video decoder in order to decode samples (a video decoder cannot start decoding video frames at arbitrary positions). In at least one DASH video in the demo app, the key frame needed to seek to 4000
is actually before 2000
. However, the previous seek at 2000
has discarded samples before 2000
, because by default the player doesn't hold data before the current position. Seeking at 4000
requires the player to look for samples before 2000
which have been dropped already, therefore needs to fetch them from the network.
This can be mitigated setting the retainBackBufferFromKeyframe
flag at the DefaultLoadControl
, e.g. in the demo app, when creating the player, you may set the LoadControl
as follows
player =
new SimpleExoPlayer.Builder(/* context= */ this, renderersFactory)
.setMediaSourceFactory(
DefaultMediaSourceFactory.newInstance(
/* context= */ this, dataSourceFactory, new AdSupportProvider()))
.setTrackSelector(trackSelector)
.setLoadControl(new DefaultLoadControl.Builder().setBackBuffer(0, /* retainBackBufferFromKeyframe= */ true).createDefaultLoadControl())
.build();
retainBackBufferFromKeyframe
and seeking at close points. When reaching ExoPlayerImplInternal.doSomeWork(), the MediaCodecRenderer reports it is not ready here, but not because there are missing data from the sample queue.I'm not sure yet if the renderer should report it is ready, or ExoPlayerImplInternal should handle this more delicately. I will update the ticket with more findings.
This looks like a bug that's been here for a while. I will leave this issue open and we will track this in our backlog. At the moment, I cannot share a timeline for a when a fix will be available.
Issue description
Im trying to seek in buffered part without internet connection. Expected result: it is possible to start playback Actual result: Exception
Video: device-2020-05-22-130034.mp4.zip
Click listener for "2 SEC FORWARD":
new OnClickListener() { int initial = 4000; @Override public void onClick(View v) { player.seekTo(0, initial); initial += 2000; } }
Reproduction steps
Steps: 1) Open ExoPlayer demo app; 2) Start to play Widevine Dash: MP4, H264 -> WV: Clear SD(MP4, H264) 3) Pause immediately before playback will start; 4) Turn off internet connection 5) Seek to 4000 6) Seek to 6000
Link to test content
WV: Clear SD (MP4,H264) https://storage.googleapis.com/wvmedia/clear/h264/tears/tears_sd.mpd
A full bug report captured from the device
I sent Bugreport to dev.exoplayer@gmail.com
Version of ExoPlayer being used
2.11.4; Version from release-v2 branch;
Device(s) and version(s) of Android being used
Xiaomi Mi A1 (Android 9)