diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index 575106f784..10e12f0ec6 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -104,17 +104,23 @@ public final class HlsMediaSource implements MediaSource, @Override public void onPrimaryPlaylistRefreshed(HlsMediaPlaylist playlist) { SinglePeriodTimeline timeline; + long windowDefaultStartPositionUs = playlist.startOffsetUs; if (playlistTracker.isLive()) { long periodDurationUs = playlist.hasEndTag ? (playlist.startTimeUs + playlist.durationUs) : C.TIME_UNSET; List segments = playlist.segments; - long windowDefaultStartPositionUs = segments.isEmpty() ? 0 - : segments.get(Math.max(0, segments.size() - 3)).relativeStartTimeUs; + if (windowDefaultStartPositionUs == C.TIME_UNSET) { + windowDefaultStartPositionUs = segments.isEmpty() ? 0 + : segments.get(Math.max(0, segments.size() - 3)).relativeStartTimeUs; + } timeline = new SinglePeriodTimeline(periodDurationUs, playlist.durationUs, playlist.startTimeUs, windowDefaultStartPositionUs, true, !playlist.hasEndTag); } else /* not live */ { + if (windowDefaultStartPositionUs == C.TIME_UNSET) { + windowDefaultStartPositionUs = 0; + } timeline = new SinglePeriodTimeline(playlist.startTimeUs + playlist.durationUs, - playlist.durationUs, playlist.startTimeUs, 0, true, false); + playlist.durationUs, playlist.startTimeUs, windowDefaultStartPositionUs, true, false); } sourceListener.onSourceInfoRefreshed(timeline, playlist); } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java index 4f30e018ae..079d4001fb 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsMediaPlaylist.java @@ -65,6 +65,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist { } + public final long startOffsetUs; public final long startTimeUs; public final int mediaSequence; public final int version; @@ -75,7 +76,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist { public final List segments; public final long durationUs; - public HlsMediaPlaylist(String baseUri, long startTimeUs, int mediaSequence, + public HlsMediaPlaylist(String baseUri, long startOffsetUs, long startTimeUs, int mediaSequence, int version, long targetDurationUs, boolean hasEndTag, boolean hasProgramDateTime, Segment initializationSegment, List segments) { super(baseUri, HlsPlaylist.TYPE_MEDIA); @@ -87,13 +88,14 @@ public final class HlsMediaPlaylist extends HlsPlaylist { this.hasProgramDateTime = hasProgramDateTime; this.initializationSegment = initializationSegment; this.segments = Collections.unmodifiableList(segments); - if (!segments.isEmpty()) { Segment last = segments.get(segments.size() - 1); durationUs = last.relativeStartTimeUs + last.durationUs; } else { durationUs = 0; } + this.startOffsetUs = startOffsetUs == C.TIME_UNSET ? C.TIME_UNSET + : startOffsetUs >= 0 ? startOffsetUs : durationUs + startOffsetUs; } /** @@ -132,8 +134,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist { if (this.startTimeUs == startTimeUs) { return this; } - return new HlsMediaPlaylist(baseUri, startTimeUs, mediaSequence, version, targetDurationUs, - hasEndTag, hasProgramDateTime, initializationSegment, segments); + return new HlsMediaPlaylist(baseUri, startOffsetUs, startTimeUs, mediaSequence, version, + targetDurationUs, hasEndTag, hasProgramDateTime, initializationSegment, segments); } /** @@ -146,8 +148,8 @@ public final class HlsMediaPlaylist extends HlsPlaylist { if (this.hasEndTag) { return this; } - return new HlsMediaPlaylist(baseUri, startTimeUs, mediaSequence, version, targetDurationUs, - true, hasProgramDateTime, initializationSegment, segments); + return new HlsMediaPlaylist(baseUri, startOffsetUs, startTimeUs, mediaSequence, version, + targetDurationUs, true, hasProgramDateTime, initializationSegment, segments); } } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 460c4576bd..e9bd5b6696 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -58,13 +58,14 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser