mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
HLS: Fix incorrect handling of byte ranges for EXT-X-MAP tags
Issue: #8783 #minor-release PiperOrigin-RevId: 366265419
This commit is contained in:
parent
106294158a
commit
4fd8e791f6
3 changed files with 56 additions and 2 deletions
|
|
@ -39,6 +39,8 @@
|
|||
codec input size
|
||||
([#8705](https://github.com/google/ExoPlayer/issues/8705)).
|
||||
* HLS:
|
||||
* 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
|
||||
`EXT-X-DISCONTINUITY` tags in different media playlists occur at
|
||||
different positions in time
|
||||
|
|
|
|||
|
|
@ -702,6 +702,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
segmentByteRangeOffset = Long.parseLong(splitByteRange[1]);
|
||||
}
|
||||
}
|
||||
if (segmentByteRangeLength == C.LENGTH_UNSET) {
|
||||
// The segment has no byte range defined.
|
||||
segmentByteRangeOffset = 0;
|
||||
}
|
||||
if (fullSegmentEncryptionKeyUri != null && fullSegmentEncryptionIV == null) {
|
||||
// See RFC 8216, Section 4.3.2.5.
|
||||
throw new ParserException(
|
||||
|
|
@ -715,7 +719,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
segmentByteRangeLength,
|
||||
fullSegmentEncryptionKeyUri,
|
||||
fullSegmentEncryptionIV);
|
||||
segmentByteRangeOffset = 0;
|
||||
if (segmentByteRangeLength != C.LENGTH_UNSET) {
|
||||
segmentByteRangeOffset += segmentByteRangeLength;
|
||||
}
|
||||
segmentByteRangeLength = C.LENGTH_UNSET;
|
||||
} else if (line.startsWith(TAG_TARGET_DURATION)) {
|
||||
targetDurationUs = parseIntAttr(line, REGEX_TARGET_DURATION) * C.MICROS_PER_SECOND;
|
||||
|
|
@ -948,7 +954,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
String segmentUri = replaceVariableReferences(line, variableDefinitions);
|
||||
@Nullable Segment inferredInitSegment = urlToInferredInitSegment.get(segmentUri);
|
||||
if (segmentByteRangeLength == C.LENGTH_UNSET) {
|
||||
// The segment is not byte range defined.
|
||||
// The segment has no byte range defined.
|
||||
segmentByteRangeOffset = 0;
|
||||
} else if (isIFrameOnly && initializationSegment == null && inferredInitSegment == null) {
|
||||
// The segment is a resource byte range without an initialization segment.
|
||||
|
|
|
|||
|
|
@ -154,6 +154,52 @@ public class HlsMediaPlaylistParserTest {
|
|||
assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2683.ts");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseMediaPlaylist_withByteRanges() throws Exception {
|
||||
Uri playlistUri = Uri.parse("https://example.com/test.m3u8");
|
||||
String playlistString =
|
||||
"#EXTM3U\n"
|
||||
+ "#EXT-X-VERSION:3\n"
|
||||
+ "#EXT-X-TARGETDURATION:5\n"
|
||||
+ "\n"
|
||||
+ "#EXT-X-BYTERANGE:200@100\n"
|
||||
+ "#EXT-X-MAP:URI=\"stream.mp4\"\n"
|
||||
+ "#EXTINF:5,\n"
|
||||
+ "#EXT-X-BYTERANGE:400\n"
|
||||
+ "stream.mp4\n"
|
||||
+ "#EXTINF:5,\n"
|
||||
+ "#EXT-X-BYTERANGE:500\n"
|
||||
+ "stream.mp4\n"
|
||||
+ "#EXT-X-DISCONTINUITY\n"
|
||||
+ "#EXT-X-MAP:URI=\"init.mp4\"\n"
|
||||
+ "#EXTINF:5,\n"
|
||||
+ "segment.mp4\n";
|
||||
InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
|
||||
HlsPlaylist playlist = new HlsPlaylistParser().parse(playlistUri, inputStream);
|
||||
|
||||
HlsMediaPlaylist mediaPlaylist = (HlsMediaPlaylist) playlist;
|
||||
List<Segment> segments = mediaPlaylist.segments;
|
||||
|
||||
assertThat(segments).isNotNull();
|
||||
assertThat(segments).hasSize(3);
|
||||
|
||||
Segment segment = segments.get(0);
|
||||
assertThat(segment.initializationSegment.byteRangeOffset).isEqualTo(100);
|
||||
assertThat(segment.initializationSegment.byteRangeLength).isEqualTo(200);
|
||||
assertThat(segment.byteRangeOffset).isEqualTo(300);
|
||||
assertThat(segment.byteRangeLength).isEqualTo(400);
|
||||
|
||||
segment = segments.get(1);
|
||||
assertThat(segment.byteRangeOffset).isEqualTo(700);
|
||||
assertThat(segment.byteRangeLength).isEqualTo(500);
|
||||
|
||||
segment = segments.get(2);
|
||||
assertThat(segment.initializationSegment.byteRangeOffset).isEqualTo(0);
|
||||
assertThat(segment.initializationSegment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
|
||||
assertThat(segment.byteRangeOffset).isEqualTo(0);
|
||||
assertThat(segment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseSampleAesMethod() throws Exception {
|
||||
Uri playlistUri = Uri.parse("https://example.com/test.m3u8");
|
||||
|
|
|
|||
Loading…
Reference in a new issue