You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Setting video surface after the player is ready causes a rebuffer #1973
(there are the ones I tried to reproduce. I believe this happens in other devices also)
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
The issue happens when I prepare the player with an initialPosition, playWhenReady=false and with no surface. Later, after the player is READY, I set the surface and playWhenReady=true, then the player state changes back to BUFFERING and READY again.
Detailed steps:
Set playWhenReady=false
Set an initial playback position (for example, seekTo=3_000L)
Prepare the player
The player moves to BUFFERING state
The player moves to READY state
Wait some time before setting the surface (for example, 2_000L)
Run the ExoPlayer demo APP and select a video to play
I could reproduce it 99%* of the times when:
I play the Clear DASH UHD (MP4, H264) on the Pixel 7
I play the Clear DASH UHD (MP4, H264) and HD (MP4, H264) on the Android Emulator Pixel 7 API 30
I play the Clear DASH UHD (MP4, H264) and HD (MP4, H264) on the Android Emulator Pixel 7 API 33
*in the emulator it seems it didn't happen in the first playback, but it happened 100% of the times in the following attempts.
Other info
I can only see the issue happening if I start the playback with an initialPosition != 0.
I could also reproduce the issue when I clip the media.
Expected result
The player starts playing and no new BUFFERING event is trigged, since the player is already in the READY state
Actual result
The player goes to BUFFERING state again , although it was already on the READY state.
Media
Clear DASH UHD (MP4, H264) and HD (MP4, H264)
Also reproduced with the HLS 16x9 basic stream (TS)
It probably happens with other media types, but these are the ones I played with the most.
changed the title [-]Setting video surface after the player is ready causes causes a rebuffer e[/-][+]Setting video surface after the player is ready causes a rebuffer[/+]on Dec 13, 2024
I found the underlying problem. The playback is actually not yet ready at the time of attaching the surface and calling setPlayWhenReady(true), so going into the buffering state is working as intended. You can see this by extending the delay to something like 30 seconds, where the additional buffering doesn't happen anymore.
So the real question is: why does the player need 20+ seconds to decode 2 seconds of video to get ready for playback? It turns out that this is caused by a low-power mode that only executes new actions every second. This mode is entered because the video renderer is apparently ready (because it's rendering to a placeholder surface) and the player is paused, so nothing needs to be done from the player's perspective. We'll have a look to find a solution to this issue.
If you never want to play without a surface, you can do the following as a workaround:
new ExoPlayer.Builder(context)
.setRenderersFactory(
new DefaultRenderersFactory(context) {
@Override
protected void buildVideoRenderers(...) {
// copy base class logic, or just add default renderer:
out.add(new MediaCodecVideoRenderer(...) {
@Override
public boolean isReady() {
if (getSurface() == null) {
// Ensure ExoPlayer thinks there is work to be done while we haven't attached a surface.
return false;
}
return super.isReady();
}
});
}
}
Note that this also means the player never becomes READY until the surface is attached.
@tonihei thanks for the workaround, I realized I did not reply to it.
Several times we want to play with and without a surface, so maybe this would help only in certain scenarios 🤔
Do you have any idea when this bug will be prioritized?
We already have a pending change for it to fix it properly (still in review, because there was some discussion around naming and the exact approach we take). Hoping to get the bug fix it into Media3 1.6.0-rc01 unless there are further discussion needed.
We use internal Google tooling for all changes and reviews, so there is unfortunately no way to see pending progress until it's fully submitted and uploaded to the main branch on GitHub. PRs are only used for external contributions.
Activity
[-]Setting video surface after the player is ready causes causes a rebuffer e[/-][+]Setting video surface after the player is ready causes a rebuffer[/+]sgosantos commentedon Jan 27, 2025
@marcbaechinger Hello! Do you have any update on this issue?
I've also tested it on 1.3.x and 1.4.x and could reproduce in both of them.
tonihei commentedon Feb 3, 2025
I found the underlying problem. The playback is actually not yet ready at the time of attaching the surface and calling
setPlayWhenReady(true), so going into the buffering state is working as intended. You can see this by extending the delay to something like 30 seconds, where the additional buffering doesn't happen anymore.So the real question is: why does the player need 20+ seconds to decode 2 seconds of video to get ready for playback? It turns out that this is caused by a low-power mode that only executes new actions every second. This mode is entered because the video renderer is apparently ready (because it's rendering to a placeholder surface) and the player is paused, so nothing needs to be done from the player's perspective. We'll have a look to find a solution to this issue.
sgosantos commentedon Feb 3, 2025
@tonihei thanks for having a look!
you can't think of any work around yet while we don't have a proper fix, right?
tonihei commentedon Feb 3, 2025
If you never want to play without a surface, you can do the following as a workaround:
Note that this also means the player never becomes READY until the surface is attached.
sgosantos commentedon Feb 19, 2025
@tonihei thanks for the workaround, I realized I did not reply to it.
Several times we want to play with and without a surface, so maybe this would help only in certain scenarios 🤔
Do you have any idea when this bug will be prioritized?
tonihei commentedon Feb 19, 2025
We already have a pending change for it to fix it properly (still in review, because there was some discussion around naming and the exact approach we take). Hoping to get the bug fix it into Media3 1.6.0-rc01 unless there are further discussion needed.
sgosantos commentedon Feb 19, 2025
@tonihei cool, great to know!
Is there a PR already I could track?
Thanks for taking a look at it!
tonihei commentedon Feb 19, 2025
We use internal Google tooling for all changes and reviews, so there is unfortunately no way to see pending progress until it's fully submitted and uploaded to the main branch on GitHub. PRs are only used for external contributions.
tonihei commentedon Mar 18, 2025
This issue is now fixed on the main branch. Sorry for the additional delay as it required some internal refactor before we could safely apply the fix.
Wait for first frame when using placeholder surface
sgosantos commentedon Mar 18, 2025
Cool! Thanks a lot for fixing it!
Wait for first frame when using placeholder surface