diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 120540bde6..4b2923c976 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -71,6 +71,8 @@ codec input size ([#8705](https://github.com/google/ExoPlayer/issues/8705)). * HLS: + * Fix bug of ignoring `EXT-X-START` when setting the live target offset + ([#8764](https://github.com/google/ExoPlayer/pull/8764)). * Fix incorrect application of byte ranges to `EXT-X-MAP` tags ([#8783](https://github.com/google/ExoPlayer/issues/8783)). * Fix issue that could cause playback to become stuck if corresponding @@ -152,8 +154,7 @@ * Update instructions and publishing configuration for releasing to Google's Maven repository instead of bintray/JCenter. * FFmpeg extension: Fix playback failure when switching to TrueHD tracks - during playback - ([#8616](https://github.com/google/ExoPlayer/issues/8616)). + during playback ([#8616](https://github.com/google/ExoPlayer/issues/8616)). ### 2.13.2 (2021-02-25) diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index e5c233ef43..1927ceb0cb 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -616,7 +616,9 @@ public final class HlsMediaSource extends BaseMediaSource HlsMediaPlaylist.ServerControl serverControl = playlist.serverControl; // Select part hold back only if the playlist has a part target duration. long offsetToEndOfPlaylistUs; - if (serverControl.partHoldBackUs != C.TIME_UNSET + if (playlist.startOffsetUs != C.TIME_UNSET) { + offsetToEndOfPlaylistUs = playlist.durationUs - playlist.startOffsetUs; + } else if (serverControl.partHoldBackUs != C.TIME_UNSET && playlist.partTargetDurationUs != C.TIME_UNSET) { offsetToEndOfPlaylistUs = serverControl.partHoldBackUs; } else if (serverControl.holdBackUs != C.TIME_UNSET) { diff --git a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java index fd2744280a..9fdd3f1498 100644 --- a/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java +++ b/library/hls/src/test/java/com/google/android/exoplayer2/source/hls/HlsMediaSourceTest.java @@ -292,6 +292,44 @@ public class HlsMediaSourceTest { assertThat(window.defaultPositionUs).isEqualTo(0); } + @Test + public void loadPlaylist_withPlaylistStartTime_targetLiveOffsetFromStartTime() + throws TimeoutException, ParserException { + String playlistUri = "fake://foo.bar/media0/playlist.m3u8"; + // The playlist has a duration of 16 seconds, and part hold back, hold back and start time + // defined. + String playlist = + "#EXTM3U\n" + + "#EXT-X-PROGRAM-DATE-TIME:2020-01-01T00:00:00.0+00:00\n" + + "#EXT-X-TARGETDURATION:4\n" + + "#EXT-X-VERSION:3\n" + + "#EXT-X-START:TIME-OFFSET=-15" + + "#EXT-X-MEDIA-SEQUENCE:0\n" + + "#EXTINF:4.00000,\n" + + "fileSequence0.ts\n" + + "#EXTINF:4.00000,\n" + + "fileSequence1.ts\n" + + "#EXTINF:4.00000,\n" + + "fileSequence2.ts\n" + + "#EXTINF:4.00000,\n" + + "fileSequence3.ts\n" + + "#EXT-X-PART-INF:PART-TARGET=0.5\n" + + "#EXT-X-SERVER-CONTROL:HOLD-BACK=12,PART-HOLD-BACK=3"; + // The playlist finishes 1 second before the current time. + SystemClock.setCurrentTimeMillis(Util.parseXsDateTime("2020-01-01T00:00:17.0+00:00")); + HlsMediaSource.Factory factory = createHlsMediaSourceFactory(playlistUri, playlist); + MediaItem mediaItem = MediaItem.fromUri(playlistUri); + HlsMediaSource mediaSource = factory.createMediaSource(mediaItem); + + Timeline timeline = prepareAndWaitForTimeline(mediaSource); + + Timeline.Window window = timeline.getWindow(0, new Timeline.Window()); + // The target live offset is picked from start time and then expressed in relation to the live + // edge (+1 seconds). + assertThat(window.liveConfiguration.targetOffsetMs).isEqualTo(16000); + assertThat(window.defaultPositionUs).isEqualTo(0); + } + @Test public void loadPlaylist_targetLiveOffsetInMediaItem_targetLiveOffsetPickedFromMediaItem() throws TimeoutException, ParserException {