-
Notifications
You must be signed in to change notification settings - Fork 416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should HLS live manifest refreshing consider http request delay? #663
Comments
Hi @baiqindotfubotv, Thanks for the question! Sounds like using "the last time the client begin loading the Playlist file" should be more accurate. But even with the current implementation, we still comply the standard
We're looking forward to your feedback! |
I tested a change at this line: DefaultHlsPlaylistTracker I changed this line to
It does fix 95% of the buffering in my case. The live window size is 32 seconds in length with 8 segments but I don't think window size matters. What matters is starting playback position. The buffering issue only happens with HLS if the target playback position is close to the end of live window. For example, at 28 seconds. Let's assume each manifest refresh takes exactly 500 ms. Then the refresh sequence is something like this:
At this time the buffer size is under 500 ms and the player needs to buffer. And the same buffering issue will happen again and again. This won't be an issue if the playback position is not close to the end live window end. This is because in a later manifest refresh request, the live window will jump ahead 8 seconds instead of 4 seconds, thus the previous accumulated delay will be erased. If we set the playback position to 18 seconds instead of 28 seconds, it will be something like this:
Note that the refresh at 40500 returns a manifest that jumps ahead 8 seconds, thus previous accumulated manifest refresh delay is erased. If playback position is close to end of live window, it is very likely to cause a lot of buffering issues. The work around I am using right now is to wait for the first A note on the default playback position. Right now there is no media3 interface to configure initial playback position / buffer size for live playback. Both DASH and HLS. There are some DASH (minBufferTime) / HLS (ext-x-start) tags that could affect the initial playback position. But a lot of times the packaging is done by third parties so the client doesn't have control over it. ExoPlayer does have a Previously |
Thanks @baiqindotfubotv for the detailed explanation! After the internal discussion, we'll be making the changes for an accurate reload interval with considering the network delay. Also, as for
please keep track on the existing feature request - #652. |
And would it be possible for you to provide a media sample for us to test the change? |
Email sent. But any HLS live stream should work I think. I just hard code the "Live Akamai m3u8" here: https://ottverse.com/free-hls-m3u8-test-urls/ into media3 demo. Let it play at the end of live window, for example, seek to 118000 ms since the window size is 120000. Then I can see a buffering every couple of minutes. |
Previously, we calculated the next playlist reload time by adding the target duration (or half of it, depending on whether there is a real update in the new playlist snapshot) from the last load completion time, which makes the reload interval as long as `targetDuration(or half of it) + lastLoadDuration`. While still complying to the standard that "the client MUST wait for at least the target duration before attempting to reload the Playlist file again", this could cause buffering when the playback position is close to the end of live window. This change is to calculate the reload interval accurately by not adding the term `lastLoadDuration`. Issue: #663 #minor-release PiperOrigin-RevId: 573300009
Previously, we calculated the next playlist reload time by adding the target duration (or half of it, depending on whether there is a real update in the new playlist snapshot) from the last load completion time, which makes the reload interval as long as `targetDuration(or half of it) + lastLoadDuration`. While still complying to the standard that "the client MUST wait for at least the target duration before attempting to reload the Playlist file again", this could cause buffering when the playback position is close to the end of live window. This change is to calculate the reload interval accurately by not adding the term `lastLoadDuration`. Issue: androidx/media#663 #minor-release PiperOrigin-RevId: 573300009
Previously, we calculated the next playlist reload time by adding the target duration (or half of it, depending on whether there is a real update in the new playlist snapshot) from the last load completion time, which makes the reload interval as long as `targetDuration(or half of it) + lastLoadDuration`. While still complying to the standard that "the client MUST wait for at least the target duration before attempting to reload the Playlist file again", this could cause buffering when the playback position is close to the end of live window. This change is to calculate the reload interval accurately by not adding the term `lastLoadDuration`. Issue: #663 #minor-release PiperOrigin-RevId: 573300009 (cherry picked from commit 58a63c8)
I am using exoPlayer to play a live HLS stream. I noticed the exoPlayer doesn't take the network request delay into consideration when scheduling manifest refreshing. Here are some logs I printed in
onTimelineUpdate
method:As you can see the gap between each refresh is several hundreds of ms greater than segment size (4 seconds). According to the description in 6.3.4 here: https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming-16#section-6.3.4:
"When a client loads a Playlist file for the first time or reloads a Playlist file and finds that it has changed since the last time it was loaded, the client MUST wait for at least the target duration before attempting to reload the Playlist file again, measured from the last time the client began loading the Playlist file."
It says the next refresh time should be measured from the last time the client begin loading the Playlist file. However looks like exoPlayer is scheduling next refreshing based on the the timestamp when last loading was finished. I think this is where exoPlayer does the calculation: https://github.com/androidx/media/blob/1.1.1/libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/playlist/DefaultHlsPlaylistTracker.java#L764.
When the default playback position is close to the end of live window end, this behavior will cause a lot of bufferings.
So is this expected behavior?
For comparison, DASH manifest refreshing does consider network delay:
https://github.com/androidx/media/blob/1.1.1/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java#L931. And for this reason, when exoPlayer is playing DASH live manifest at a position close to live window end, bufferings seldom happen.
The text was updated successfully, but these errors were encountered: