google / ExoPlayer

An extensible media player for Android
Apache License 2.0
21.65k stars 6.01k forks source link

Apple LLHLS Playlist Delta Updates playback problems #9127

Closed Falrach closed 3 years ago

Falrach commented 3 years ago

Encountering a weird behaviour when playing an Apple LLHLS stream using the Playlist Delta Updates in ExoPlayer.

The Playlist Delta Updates (rfc-6.2.5.1) are implemented according to the standard on the server side and when disabling them, all the issues are gone.

Issue 1: When starting the live playback, the position jumps sometimes multiple seconds, as you can see here in the logs:

18:24:41.488 com.google.android.exoplayer2.demo D/EventLogger: timeline [eventTime=641.71, mediaPos=1230.64, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
18:24:41.488 com.google.android.exoplayer2.demo D/EventLogger:   period [?]
18:24:41.488 com.google.android.exoplayer2.demo D/EventLogger:   window [1127.80, seekable=true, dynamic=true]
18:24:41.488 com.google.android.exoplayer2.demo D/EventLogger: ]
18:24:41.674 com.google.android.exoplayer2.demo D/EventLogger: timeline [eventTime=641.90, mediaPos=1230.83, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
18:24:41.674 com.google.android.exoplayer2.demo D/EventLogger:   period [?]
18:24:41.674 com.google.android.exoplayer2.demo D/EventLogger:   window [1128.00, seekable=true, dynamic=true]
18:24:41.674 com.google.android.exoplayer2.demo D/EventLogger: ]
18:24:41.878 com.google.android.exoplayer2.demo D/EventLogger: timeline [eventTime=642.10, mediaPos=1234.04, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
18:24:41.879 com.google.android.exoplayer2.demo D/EventLogger:   period [?]
18:24:41.879 com.google.android.exoplayer2.demo D/EventLogger:   window [1128.20, seekable=true, dynamic=true]
18:24:41.879 com.google.android.exoplayer2.demo D/EventLogger: ]
18:24:42.086 com.google.android.exoplayer2.demo D/EventLogger: timeline [eventTime=642.31, mediaPos=1234.25, window=0, period=0, periodCount=1, windowCount=1, reason=SOURCE_UPDATE
18:24:42.086 com.google.android.exoplayer2.demo D/EventLogger:   period [?]
18:24:42.086 com.google.android.exoplayer2.demo D/EventLogger:   window [1128.40, seekable=true, dynamic=true]
18:24:42.086 com.google.android.exoplayer2.demo D/EventLogger: ]

This also results in the position getting higher than the duration over time (see video files provided by mail).

Issue 2: Furthermore, when seeking to a previous playback position, the player just pauses and does not play anymore. Pausing/Starting does nothing. The playback only works again if I jump near the live edge, then playback continues with the same issue as described above.

The requests to fetch the data at the live-edge seem to be fine, so I assume there is an issue with the Timeline handling when HLS_skip=YES, and/or a problem with fetching old content when seeking back. Unfortunately, I couldn't really track down, where exactly the problem occurs but I'm happy to help with further debugging.

Environment: Tested using the ExoPlayer demo app. ExoPlayer versions: 2.13.0, 2.14.0, 2.14.1, current dev-2 branch Device: Huawei P30 Pro, Android 10

christosts commented 3 years ago

Hi, thank you for filing this issue.

I tested with the stream sent over email on the demo app at r2.14.1. At the time I tested, the UI showed that the player was playing at position 4:00:00 and the content had a duration of 2:00:00. What seems to confuse the player is the #EXT-X-PROGRAM-DATE-TIME tag defined in the playlist. At the time I tested the stream, the tag was #EXT-X-PROGRAM-DATE-TIME:2021-07-01T08:44:10.000+00:00 and the UTC time was 12:44 (i.e. 4 hours later), but the playlist had a duration of 2 hours (=> sum of segments durations).

So, there's a gap between the playlist end time and the current time of 2 hours - the playlist is 2 hours shorter. The player's current position matches the difference between the current time and time indicated by #EXT-X-PROGRAM-DATE-TIME, which works as intended. Seeking did not work because the UI is telling the player to seeking outside the playlist boundaries. Overall, I believe the misalignment between #EXT-X-PROGRAM-DATE-TIME and playlist duration is confusing the player. For example, ignoring the #EXT-X-PROGRAM-DATE-TIME in the playlist forces exoplayer to calculate the position based on the playlist duration and everything works fine, including seeking.

I checked at the HLS spec and did not see an obvious requirement about #EXT-X-PROGRAM-DATE-TIME and playlist duration. In other HLS live streams we use for testing, the #EXT-X-PROGRAM-DATE-TIME is always pointing to approximately "_current-time - playlistduration" and on every playlist update, the #EXT-X-PROGRAM-DATE-TIME is updated too, whereas in your playlist #EXT-X-PROGRAM-DATE-TIME was fixed.

As an immediate solution, may I ask you to tune (or remove) #EXT-X-PROGRAM-DATE-TIME?

Falrach commented 3 years ago

Thanks for your reply!

We removed the #EXT-X-PROGRAM-DATE-TIME and the problems don't occur anymore.

One interesting thing to note is, that we use the #EXT-X-PROGRAM-DATE-TIME the same way if we don't use the Delta Update and then the playback also works as expected without the described problems. So, it seems like the #EXT-X-PROGRAM-DATE-TIME tag specifically affects something in the Delta Update logic, where the player gets confused if it's not approximately pointing to "_current-time - playlistduration".

Falrach commented 3 years ago

A quick update: We fixed an issue with wrongly calculated timestamps for the playlists, so this now also works when using the #EXT-X-PROGRAM-DATE-TIME without issues.