Use #EXT-X-START PRECISE attribute
This commit is contained in:
parent
1fe7fbc4cd
commit
b3c8ffeb50
@ -597,11 +597,14 @@ public final class HlsMediaSource extends BaseMediaSource
|
|||||||
int segmentIndex = segments.size() - 1;
|
int segmentIndex = segments.size() - 1;
|
||||||
long minStartPositionUs =
|
long minStartPositionUs =
|
||||||
playlist.durationUs + liveEdgeOffsetUs - C.msToUs(liveConfiguration.targetOffsetMs);
|
playlist.durationUs + liveEdgeOffsetUs - C.msToUs(liveConfiguration.targetOffsetMs);
|
||||||
|
if (playlist.preciseStart)
|
||||||
|
return minStartPositionUs;
|
||||||
while (segmentIndex > 0
|
while (segmentIndex > 0
|
||||||
&& segments.get(segmentIndex).relativeStartTimeUs > minStartPositionUs) {
|
&& segments.get(segmentIndex).relativeStartTimeUs > minStartPositionUs) {
|
||||||
segmentIndex--;
|
segmentIndex--;
|
||||||
}
|
}
|
||||||
HlsMediaPlaylist.Segment segment = segments.get(segmentIndex);
|
HlsMediaPlaylist.Segment segment = segments.get(segmentIndex);
|
||||||
|
if (playlist.startOffsetUs == C.TIME_UNSET) {
|
||||||
List<HlsMediaPlaylist.Part> parts = segment.parts;
|
List<HlsMediaPlaylist.Part> parts = segment.parts;
|
||||||
int partIndex = parts.size();
|
int partIndex = parts.size();
|
||||||
if (partIndex > 1) {
|
if (partIndex > 1) {
|
||||||
@ -612,6 +615,7 @@ public final class HlsMediaSource extends BaseMediaSource
|
|||||||
} while (part.relativeStartTimeUs > minStartPositionUs || !part.isIndependent);
|
} while (part.relativeStartTimeUs > minStartPositionUs || !part.isIndependent);
|
||||||
return part.relativeStartTimeUs;
|
return part.relativeStartTimeUs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return segment.relativeStartTimeUs;
|
return segment.relativeStartTimeUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,6 +397,10 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|
|||||||
* The start offset in microseconds, as defined by #EXT-X-START.
|
* The start offset in microseconds, as defined by #EXT-X-START.
|
||||||
*/
|
*/
|
||||||
public final long startOffsetUs;
|
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.
|
* 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
|
* 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,
|
String baseUri,
|
||||||
List<String> tags,
|
List<String> tags,
|
||||||
long startOffsetUs,
|
long startOffsetUs,
|
||||||
|
boolean preciseStart,
|
||||||
long startTimeUs,
|
long startTimeUs,
|
||||||
boolean hasDiscontinuitySequence,
|
boolean hasDiscontinuitySequence,
|
||||||
int discontinuitySequence,
|
int discontinuitySequence,
|
||||||
@ -499,6 +504,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|
|||||||
super(baseUri, tags, hasIndependentSegments);
|
super(baseUri, tags, hasIndependentSegments);
|
||||||
this.playlistType = playlistType;
|
this.playlistType = playlistType;
|
||||||
this.startTimeUs = startTimeUs;
|
this.startTimeUs = startTimeUs;
|
||||||
|
this.preciseStart = preciseStart;
|
||||||
this.hasDiscontinuitySequence = hasDiscontinuitySequence;
|
this.hasDiscontinuitySequence = hasDiscontinuitySequence;
|
||||||
this.discontinuitySequence = discontinuitySequence;
|
this.discontinuitySequence = discontinuitySequence;
|
||||||
this.mediaSequence = mediaSequence;
|
this.mediaSequence = mediaSequence;
|
||||||
@ -576,6 +582,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|
|||||||
baseUri,
|
baseUri,
|
||||||
tags,
|
tags,
|
||||||
startOffsetUs,
|
startOffsetUs,
|
||||||
|
preciseStart,
|
||||||
startTimeUs,
|
startTimeUs,
|
||||||
/* hasDiscontinuitySequence= */ true,
|
/* hasDiscontinuitySequence= */ true,
|
||||||
discontinuitySequence,
|
discontinuitySequence,
|
||||||
@ -606,6 +613,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|
|||||||
baseUri,
|
baseUri,
|
||||||
tags,
|
tags,
|
||||||
startOffsetUs,
|
startOffsetUs,
|
||||||
|
preciseStart,
|
||||||
startTimeUs,
|
startTimeUs,
|
||||||
hasDiscontinuitySequence,
|
hasDiscontinuitySequence,
|
||||||
discontinuitySequence,
|
discontinuitySequence,
|
||||||
|
@ -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_FORCED = compileBooleanAttrPattern("FORCED");
|
||||||
private static final Pattern REGEX_INDEPENDENT = compileBooleanAttrPattern("INDEPENDENT");
|
private static final Pattern REGEX_INDEPENDENT = compileBooleanAttrPattern("INDEPENDENT");
|
||||||
private static final Pattern REGEX_GAP = compileBooleanAttrPattern("GAP");
|
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_VALUE = Pattern.compile("VALUE=\"(.+?)\"");
|
||||||
private static final Pattern REGEX_IMPORT = Pattern.compile("IMPORT=\"(.+?)\"");
|
private static final Pattern REGEX_IMPORT = Pattern.compile("IMPORT=\"(.+?)\"");
|
||||||
private static final Pattern REGEX_VARIABLE_REFERENCE =
|
private static final Pattern REGEX_VARIABLE_REFERENCE =
|
||||||
@ -645,6 +646,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
int relativeDiscontinuitySequence = 0;
|
int relativeDiscontinuitySequence = 0;
|
||||||
long playlistStartTimeUs = 0;
|
long playlistStartTimeUs = 0;
|
||||||
long segmentStartTimeUs = 0;
|
long segmentStartTimeUs = 0;
|
||||||
|
boolean preciseStart = false;
|
||||||
long segmentByteRangeOffset = 0;
|
long segmentByteRangeOffset = 0;
|
||||||
long segmentByteRangeLength = C.LENGTH_UNSET;
|
long segmentByteRangeLength = C.LENGTH_UNSET;
|
||||||
long partStartTimeUs = 0;
|
long partStartTimeUs = 0;
|
||||||
@ -687,6 +689,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
isIFrameOnly = true;
|
isIFrameOnly = true;
|
||||||
} else if (line.startsWith(TAG_START)) {
|
} else if (line.startsWith(TAG_START)) {
|
||||||
startOffsetUs = (long) (parseDoubleAttr(line, REGEX_TIME_OFFSET) * C.MICROS_PER_SECOND);
|
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)) {
|
} else if (line.startsWith(TAG_SERVER_CONTROL)) {
|
||||||
serverControl = parseServerControl(line);
|
serverControl = parseServerControl(line);
|
||||||
} else if (line.startsWith(TAG_PART_INF)) {
|
} else if (line.startsWith(TAG_PART_INF)) {
|
||||||
@ -1011,6 +1015,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
baseUri,
|
baseUri,
|
||||||
tags,
|
tags,
|
||||||
startOffsetUs,
|
startOffsetUs,
|
||||||
|
preciseStart,
|
||||||
playlistStartTimeUs,
|
playlistStartTimeUs,
|
||||||
hasDiscontinuitySequence,
|
hasDiscontinuitySequence,
|
||||||
playlistDiscontinuitySequence,
|
playlistDiscontinuitySequence,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user