Version
Media3 1.10.1
More version details
Problem
Some HLS live streams have servers that change the #EXT-X-PROGRAM-DATE-TIME value between playlist refreshes. This causes ExoPlayer to compute a negative playback position (e.g., -35.96s) from which it never recovers. The player stays in READY state but at a negative position, unable to play any content.
Per RFC 8216, Section 4.3.2.6:
"Note that dates in Playlists can refer to when the content was produced (or to other times), which have no relation to the time of playback."
So this behavior from the server is allowed by the spec — it does not require PROGRAM-DATE-TIME to be consistent across playlist refreshes.
Manifest Example
The first media playlist response has PROGRAM-DATE-TIME set to one time. The second response (with overlapping segments) has it set to a different time, creating a ~36s discontinuity.
First response (seq=0):
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-START:TIME-OFFSET=0
#EXT-X-PROGRAM-DATE-TIME:2026-07-16T09:20:26.281Z
#EXT-X-DISCONTINUITY
#EXTINF:0.185760,
l1_6a58a1d3ee8ac1baff0fc11e.aac
#EXT-X-DISCONTINUITY
#EXTINF:5.990748,
l0_6a58a262ee8ac1baff0fc136.aac
#EXTINF:5.990748,
l0_6a58a268ee8ac1baff0fc137.aac
#EXTINF:5.990748,
l0_6a58a26eee8ac1baff0fc138.aac
...
Second response (seq=2):
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:2
#EXT-X-DISCONTINUITY-SEQUENCE:2
#EXT-X-START:TIME-OFFSET=0
#EXT-X-PROGRAM-DATE-TIME:2026-07-16T09:21:08.047Z
#EXTINF:5.990748,
l0_6a58a268ee8ac1baff0fc137.aac
#EXTINF:5.990748,
l0_6a58a26eee8ac1baff0fc138.aac
...
The segment l0_6a58a268ee8ac1baff0fc137.aac appears in both playlists. In the first response, its implied time is ~09:20:32Z (09:20:26.281 + 0.186 + 5.991). In the second response, PROGRAM-DATE-TIME is 09:21:08.047Z — a ~36 second discontinuity for the same segment.
Player Behavior
eventTime=0.00 mediaPos=0.00 state=BUFFERING
eventTime=1.63 mediaPos=0.00 state=READY <-- starts playing
eventTime=2.20 mediaPos=0.50 loading=false <-- playing normally
eventTime=5.82 mediaPos=4.12 loading=true <-- rebuffering after ~4s
eventTime=7.44 mediaPos=-36.03 <-- POSITION JUMPS TO -36s
eventTime=7.51 mediaPos=-35.96 loading=false
eventTime=47.41 mediaPos=-37.99 loading=true <-- stuck: loads every 6s, position ~-38
eventTime=53.39 mediaPos=-38.00 loading=true
eventTime=59.38 mediaPos=-38.01 loading=true
... (continues indefinitely, never recovers)
The player transitions from READY at position 4.12 to position -35.96 during a playlist refresh, then stays stuck at approximately -38s forever. No BehindLiveWindowException is thrown.
Where it happens
In DefaultHlsPlaylistTracker.getLoadedPlaylistStartTimeUs(), when the loaded playlist has hasProgramDateTime = true, the method unconditionally returns the server-provided startTimeUs:
if (loadedPlaylist.hasProgramDateTime) {
return loadedPlaylist.startTimeUs;
}
For playlists without PROGRAM-DATE-TIME, the tracker already computes startTimeUs from overlapping segments in the previous playlist, which maintains timeline consistency. The issue is that this safe behavior is bypassed when PROGRAM-DATE-TIME is present.
Devices that reproduce the issue
Tested on Android emulator, API 35
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
- Play an HLS live stream where
#EXT-X-PROGRAM-DATE-TIME changes between playlist refreshes
- Wait for the first playlist refresh
- Observe the player position
Expected result
The player handles inconsistent PROGRAM-DATE-TIME values gracefully, maintains a positive playback position, and continues playing live content.
Actual result
After the first playlist refresh, the player position jumps from a positive value (e.g., 4.12s) to a negative value (e.g., -35.96s). The player stays stuck in this state indefinitely — it keeps loading segments but never recovers. No BehindLiveWindowException is thrown.
Media
Sorry, can not provide stream URL (private).
hls_manifests2.log
eventlog_full.txt
Bug Report
Version
Media3 1.10.1
More version details
Problem
Some HLS live streams have servers that change the
#EXT-X-PROGRAM-DATE-TIMEvalue between playlist refreshes. This causes ExoPlayer to compute a negative playback position (e.g.,-35.96s) from which it never recovers. The player stays in READY state but at a negative position, unable to play any content.Per RFC 8216, Section 4.3.2.6:
So this behavior from the server is allowed by the spec — it does not require
PROGRAM-DATE-TIMEto be consistent across playlist refreshes.Manifest Example
The first media playlist response has
PROGRAM-DATE-TIMEset to one time. The second response (with overlapping segments) has it set to a different time, creating a ~36s discontinuity.First response (seq=0):
Second response (seq=2):
The segment
l0_6a58a268ee8ac1baff0fc137.aacappears in both playlists. In the first response, its implied time is ~09:20:32Z(09:20:26.281 + 0.186 + 5.991). In the second response,PROGRAM-DATE-TIMEis09:21:08.047Z— a ~36 second discontinuity for the same segment.Player Behavior
The player transitions from READY at position
4.12to position-35.96during a playlist refresh, then stays stuck at approximately-38sforever. NoBehindLiveWindowExceptionis thrown.Where it happens
In
DefaultHlsPlaylistTracker.getLoadedPlaylistStartTimeUs(), when the loaded playlist hashasProgramDateTime = true, the method unconditionally returns the server-providedstartTimeUs:For playlists without
PROGRAM-DATE-TIME, the tracker already computesstartTimeUsfrom overlapping segments in the previous playlist, which maintains timeline consistency. The issue is that this safe behavior is bypassed whenPROGRAM-DATE-TIMEis present.Devices that reproduce the issue
Tested on Android emulator, API 35
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
#EXT-X-PROGRAM-DATE-TIMEchanges between playlist refreshesExpected result
The player handles inconsistent
PROGRAM-DATE-TIMEvalues gracefully, maintains a positive playback position, and continues playing live content.Actual result
After the first playlist refresh, the player position jumps from a positive value (e.g.,
4.12s) to a negative value (e.g.,-35.96s). The player stays stuck in this state indefinitely — it keeps loading segments but never recovers. NoBehindLiveWindowExceptionis thrown.Media
Sorry, can not provide stream URL (private).
hls_manifests2.log
eventlog_full.txt
Bug Report
adb bugreportto android-media-github@google.com after filing this issue.