Use #EXT-X-START PRECISE attribute

This commit is contained in:
Justin Wong 2021-03-29 00:48:10 +08:00
parent 1fe7fbc4cd
commit b3c8ffeb50
3 changed files with 26 additions and 9 deletions

View File

@ -597,20 +597,24 @@ public final class HlsMediaSource extends BaseMediaSource
int segmentIndex = segments.size() - 1;
long minStartPositionUs =
playlist.durationUs + liveEdgeOffsetUs - C.msToUs(liveConfiguration.targetOffsetMs);
if (playlist.preciseStart)
return minStartPositionUs;
while (segmentIndex > 0
&& segments.get(segmentIndex).relativeStartTimeUs > minStartPositionUs) {
segmentIndex--;
}
HlsMediaPlaylist.Segment segment = segments.get(segmentIndex);
List<HlsMediaPlaylist.Part> parts = segment.parts;
int partIndex = parts.size();
if (partIndex > 1) {
HlsMediaPlaylist.Part part;
do {
partIndex--;
part = parts.get(partIndex);
} while (part.relativeStartTimeUs > minStartPositionUs || !part.isIndependent);
return part.relativeStartTimeUs;
if (playlist.startOffsetUs == C.TIME_UNSET) {
List<HlsMediaPlaylist.Part> parts = segment.parts;
int partIndex = parts.size();
if (partIndex > 1) {
HlsMediaPlaylist.Part part;
do {
partIndex--;
part = parts.get(partIndex);
} while (part.relativeStartTimeUs > minStartPositionUs || !part.isIndependent);
return part.relativeStartTimeUs;
}
}
return segment.relativeStartTimeUs;
}

View File

@ -397,6 +397,10 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* The start offset in microseconds, as defined by #EXT-X-START.
*/
public final long startOffsetUs;
/**
* Whether the start position should be precise, as defined by #EXT-X-START.
*/
public final boolean preciseStart;
/**
* If {@link #hasProgramDateTime} is true, contains the datetime as microseconds since epoch.
* Otherwise, contains the aggregated duration of removed segments up to this snapshot of the
@ -481,6 +485,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
String baseUri,
List<String> tags,
long startOffsetUs,
boolean preciseStart,
long startTimeUs,
boolean hasDiscontinuitySequence,
int discontinuitySequence,
@ -499,6 +504,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
super(baseUri, tags, hasIndependentSegments);
this.playlistType = playlistType;
this.startTimeUs = startTimeUs;
this.preciseStart = preciseStart;
this.hasDiscontinuitySequence = hasDiscontinuitySequence;
this.discontinuitySequence = discontinuitySequence;
this.mediaSequence = mediaSequence;
@ -576,6 +582,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
baseUri,
tags,
startOffsetUs,
preciseStart,
startTimeUs,
/* hasDiscontinuitySequence= */ true,
discontinuitySequence,
@ -606,6 +613,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
baseUri,
tags,
startOffsetUs,
preciseStart,
startTimeUs,
hasDiscontinuitySequence,
discontinuitySequence,

View File

@ -210,6 +210,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final Pattern REGEX_FORCED = compileBooleanAttrPattern("FORCED");
private static final Pattern REGEX_INDEPENDENT = compileBooleanAttrPattern("INDEPENDENT");
private static final Pattern REGEX_GAP = compileBooleanAttrPattern("GAP");
private static final Pattern REGEX_PRECISE = compileBooleanAttrPattern("PRECISE");
private static final Pattern REGEX_VALUE = Pattern.compile("VALUE=\"(.+?)\"");
private static final Pattern REGEX_IMPORT = Pattern.compile("IMPORT=\"(.+?)\"");
private static final Pattern REGEX_VARIABLE_REFERENCE =
@ -645,6 +646,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
int relativeDiscontinuitySequence = 0;
long playlistStartTimeUs = 0;
long segmentStartTimeUs = 0;
boolean preciseStart = false;
long segmentByteRangeOffset = 0;
long segmentByteRangeLength = C.LENGTH_UNSET;
long partStartTimeUs = 0;
@ -687,6 +689,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
isIFrameOnly = true;
} else if (line.startsWith(TAG_START)) {
startOffsetUs = (long) (parseDoubleAttr(line, REGEX_TIME_OFFSET) * C.MICROS_PER_SECOND);
preciseStart = parseOptionalBooleanAttribute(line, REGEX_PRECISE,
/* defaultValue= */ false);
} else if (line.startsWith(TAG_SERVER_CONTROL)) {
serverControl = parseServerControl(line);
} else if (line.startsWith(TAG_PART_INF)) {
@ -1011,6 +1015,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
baseUri,
tags,
startOffsetUs,
preciseStart,
playlistStartTimeUs,
hasDiscontinuitySequence,
playlistDiscontinuitySequence,