Add support for #EXT-X-START tag
This overrides the start position relative to the window. Issue:#1544 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=144434903
This commit is contained in:
parent
63123f455c
commit
28e117d25f
@ -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<HlsMediaPlaylist.Segment> 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);
|
||||
}
|
||||
|
@ -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<Segment> 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<Segment> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,13 +58,14 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
||||
private static final String TAG_VERSION = "#EXT-X-VERSION";
|
||||
private static final String TAG_STREAM_INF = "#EXT-X-STREAM-INF";
|
||||
private static final String TAG_MEDIA = "#EXT-X-MEDIA";
|
||||
private static final String TAG_TARGET_DURATION = "#EXT-X-TARGETDURATION";
|
||||
private static final String TAG_DISCONTINUITY = "#EXT-X-DISCONTINUITY";
|
||||
private static final String TAG_DISCONTINUITY_SEQUENCE = "#EXT-X-DISCONTINUITY-SEQUENCE";
|
||||
private static final String TAG_PROGRAM_DATE_TIME = "#EXT-X-PROGRAM-DATE-TIME";
|
||||
private static final String TAG_INIT_SEGMENT = "#EXT-X-MAP";
|
||||
private static final String TAG_MEDIA_DURATION = "#EXTINF";
|
||||
private static final String TAG_MEDIA_SEQUENCE = "#EXT-X-MEDIA-SEQUENCE";
|
||||
private static final String TAG_TARGET_DURATION = "#EXT-X-TARGETDURATION";
|
||||
private static final String TAG_START = "#EXT-X-START";
|
||||
private static final String TAG_ENDLIST = "#EXT-X-ENDLIST";
|
||||
private static final String TAG_KEY = "#EXT-X-KEY";
|
||||
private static final String TAG_BYTERANGE = "#EXT-X-BYTERANGE";
|
||||
@ -90,6 +91,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
||||
+ ":(\\d+)\\b");
|
||||
private static final Pattern REGEX_MEDIA_DURATION = Pattern.compile(TAG_MEDIA_DURATION
|
||||
+ ":([\\d\\.]+)\\b");
|
||||
private static final Pattern REGEX_TIME_OFFSET = Pattern.compile("TIME-OFFSET=([\\d\\.]+)\\b");
|
||||
private static final Pattern REGEX_BYTERANGE = Pattern.compile(TAG_BYTERANGE
|
||||
+ ":(\\d+(?:@\\d+)?)\\b");
|
||||
private static final Pattern REGEX_ATTR_BYTERANGE =
|
||||
@ -255,6 +257,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
||||
|
||||
private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String baseUri)
|
||||
throws IOException {
|
||||
long startOffsetUs = C.TIME_UNSET;
|
||||
int mediaSequence = 0;
|
||||
int version = 1; // Default version == 1.
|
||||
long targetDurationUs = C.TIME_UNSET;
|
||||
@ -277,7 +280,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
||||
String line;
|
||||
while (iterator.hasNext()) {
|
||||
line = iterator.next();
|
||||
if (line.startsWith(TAG_INIT_SEGMENT)) {
|
||||
if (line.startsWith(TAG_START)) {
|
||||
startOffsetUs = (long) (parseDoubleAttr(line, REGEX_TIME_OFFSET) * C.MICROS_PER_SECOND);
|
||||
} else if (line.startsWith(TAG_INIT_SEGMENT)) {
|
||||
String uri = parseStringAttr(line, REGEX_URI);
|
||||
String byteRange = parseOptionalStringAttr(line, REGEX_ATTR_BYTERANGE);
|
||||
if (byteRange != null) {
|
||||
@ -353,7 +358,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
||||
hasEndTag = true;
|
||||
}
|
||||
}
|
||||
return new HlsMediaPlaylist(baseUri, playlistStartTimeUs, mediaSequence, version,
|
||||
return new HlsMediaPlaylist(baseUri, startOffsetUs, playlistStartTimeUs, mediaSequence, version,
|
||||
targetDurationUs, hasEndTag, playlistStartTimeUs != 0, initializationSegment, segments);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user