google / google/ExoPlayer

Unable to resume playing primary HLS audio stream after failover

Open
#5,873 9 comments 0 reactions 1 assignee Assigned to @tianyif View on GitHub
content not playing
Dominant language
Java
Stars
21.9k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Hello,

### [REQUIRED] Content description
I use ExoPlayer to play an hls audio stream. My master playlist consists of primary and backup playlists, where the primary one sometimes restarts and begins producing segments starting from 0. But media sequences are in sync. After player switches from backup variant back to the primary, it is unable to continue playing the stream.

I checked the same stream with the hls.js player (http://github.com/video-dev/hls.js/) and it works fine there. There are also no issues with this stream on iOS.

Here are the playlist snapshots when switching variants:
from backup https://gist.github.com/makp9k/db98ed83c2efe264f97ae13faf22a221
to primary https://gist.github.com/makp9k/300f59087ab84b7e90d78d87200dfdd6

After some debugging there is a following picture in my head (please correct me if I'm wrong):
The DefaultHlsPlaylistTracker handles the primary playlist update and tries to find an overlapping segment in order to determine the start time. Because the last snapshot to compare with is not the currently playing playlist but rather the old primary playlist, it's not possible to find an overlap any more. In this case the primary playlist is aligned with the backup by setting it's startTime to primarySnapshotStartTimeUs
https://github.com/google/ExoPlayer/blob/release-v2/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java#L408
```
// No segments overlap, we assume the new playlist start coincides with the primary playlist.
return primarySnapshotStartTimeUs;
```

And then the HlsChunkSource rejects this new playlist, because it's duration is shorter than the currently playing backup's
https://github.com/google/ExoPlayer/blob/release-v2/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java#L464
```
// If the playlist is too old to contain the chunk, we need to refresh it.
return mediaPlaylist.mediaSequence + mediaPlaylist.segments.size();
```

It looks like the javascript library does the fallback a bit differently:
https://github.com/video-dev/hls.js/blob/master/src/controller/stream-controller.js#L305
```
/* we are switching level on live playlist, but we don't have any PTS info for that quality level ...
try to load frag matching with next SN.
even if SN are not synchronized between playlists, loading this frag will help us
compute playlist sliding and find the right one after in case it was not the right consecutive one */
```

What are the possible solutions to this issue? Is it possible for ExoPlayer to handle this setup the same way as the JS player? I suppose that adding EXT-X-PROGRAM-DATE-TIME tag should help, but I'm not able to modify those playlists.

### [REQUIRED] Link to test content
I will send a master playlist link to dev.exoplayer@gmail.com.

### [REQUIRED] Version of ExoPlayer being used
Tested with 2.8.2 and the 2.10.0

### [REQUIRED] Device(s) and version(s) of Android being used
Samsung S6 / Android 7.0
Honor 9 Lite / Android 8.0

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.