Skip to content

Commit

Permalink
Support multiple EXT-X-MAP tags
Browse files Browse the repository at this point in the history
Issue:#4182

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=194223312
  • Loading branch information
AquilesCanta authored and ojw28 committed May 7, 2018
1 parent dcff063 commit ddef32c
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 26 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
([#4145](https://github.com/google/ExoPlayer/issues/4145)).
* Preeptively declare an ID3 track in chunkless preparation
([#4016](https://github.com/google/ExoPlayer/issues/4016)).
* Add support for multiple #EXT-X-MAP tags in a media playlist
([#4164](https://github.com/google/ExoPlayer/issues/4182)).
* Fix ClearKey decryption error if the key contains a forward slash
([#4075](https://github.com/google/ExoPlayer/issues/4075)).
* Fix crash when switching surface on Huawei P9 Lite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, long l
}

DataSpec initDataSpec = null;
Segment initSegment = mediaPlaylist.initializationSegment;
Segment initSegment = segment.initializationSegment;
if (initSegment != null) {
Uri initSegmentUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, initSegment.url);
initDataSpec = new DataSpec(initSegmentUri, initSegment.byterangeOffset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,16 @@ protected List<Segment> getSegments(
continue;
}

HlsMediaPlaylist.Segment initSegment = mediaPlaylist.initializationSegment;
if (initSegment != null) {
addSegment(segments, mediaPlaylist, initSegment, encryptionKeyUris);
}

HlsMediaPlaylist.Segment lastInitSegment = null;
List<HlsMediaPlaylist.Segment> hlsSegments = mediaPlaylist.segments;
for (int i = 0; i < hlsSegments.size(); i++) {
addSegment(segments, mediaPlaylist, hlsSegments.get(i), encryptionKeyUris);
HlsMediaPlaylist.Segment segment = hlsSegments.get(i);
HlsMediaPlaylist.Segment initSegment = segment.initializationSegment;
if (initSegment != null && initSegment != lastInitSegment) {
lastInitSegment = initSegment;
addSegment(segments, mediaPlaylist, initSegment, encryptionKeyUris);
}
addSegment(segments, mediaPlaylist, segment, encryptionKeyUris);
}
}
return segments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData;
import java.lang.annotation.Retention;
Expand All @@ -38,8 +39,12 @@ public static final class Segment implements Comparable<Long> {
*/
public final String url;
/**
* The duration of the segment in microseconds, as defined by #EXTINF.
* The media initialization section for this segment, as defined by #EXT-X-MAP. May be null if
* the media playlist does not define a media section for this segment. The same instance is
* used for all segments that share an EXT-X-MAP tag.
*/
@Nullable public final Segment initializationSegment;
/** The duration of the segment in microseconds, as defined by #EXTINF. */
public final long durationUs;
/**
* The number of #EXT-X-DISCONTINUITY tags in the playlist before the segment.
Expand Down Expand Up @@ -78,11 +83,12 @@ public static final class Segment implements Comparable<Long> {
* @param byterangeLength See {@link #byterangeLength}.
*/
public Segment(String uri, long byterangeOffset, long byterangeLength) {
this(uri, 0, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength, false);
this(uri, null, 0, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength, false);
}

/**
* @param url See {@link #url}.
* @param initializationSegment See {@link #initializationSegment}.
* @param durationUs See {@link #durationUs}.
* @param relativeDiscontinuitySequence See {@link #relativeDiscontinuitySequence}.
* @param relativeStartTimeUs See {@link #relativeStartTimeUs}.
Expand All @@ -94,6 +100,7 @@ public Segment(String uri, long byterangeOffset, long byterangeLength) {
*/
public Segment(
String url,
Segment initializationSegment,
long durationUs,
int relativeDiscontinuitySequence,
long relativeStartTimeUs,
Expand All @@ -103,6 +110,7 @@ public Segment(
long byterangeLength,
boolean hasGapTag) {
this.url = url;
this.initializationSegment = initializationSegment;
this.durationUs = durationUs;
this.relativeDiscontinuitySequence = relativeDiscontinuitySequence;
this.relativeStartTimeUs = relativeStartTimeUs;
Expand Down Expand Up @@ -182,10 +190,6 @@ public int compareTo(@NonNull Long relativeStartTimeUs) {
* encryption.
*/
public final DrmInitData drmInitData;
/**
* The initialization segment, as defined by #EXT-X-MAP.
*/
public final Segment initializationSegment;
/**
* The list of segments in the playlist.
*/
Expand All @@ -210,7 +214,6 @@ public int compareTo(@NonNull Long relativeStartTimeUs) {
* @param hasEndTag See {@link #hasEndTag}.
* @param hasProgramDateTime See {@link #hasProgramDateTime}.
* @param drmInitData See {@link #drmInitData}.
* @param initializationSegment See {@link #initializationSegment}.
* @param segments See {@link #segments}.
*/
public HlsMediaPlaylist(
Expand All @@ -228,7 +231,6 @@ public HlsMediaPlaylist(
boolean hasEndTag,
boolean hasProgramDateTime,
DrmInitData drmInitData,
Segment initializationSegment,
List<Segment> segments) {
super(baseUri, tags);
this.playlistType = playlistType;
Expand All @@ -242,7 +244,6 @@ public HlsMediaPlaylist(
this.hasEndTag = hasEndTag;
this.hasProgramDateTime = hasProgramDateTime;
this.drmInitData = drmInitData;
this.initializationSegment = initializationSegment;
this.segments = Collections.unmodifiableList(segments);
if (!segments.isEmpty()) {
Segment last = segments.get(segments.size() - 1);
Expand Down Expand Up @@ -296,9 +297,22 @@ public long getEndTimeUs() {
* @return The playlist.
*/
public HlsMediaPlaylist copyWith(long startTimeUs, int discontinuitySequence) {
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, startTimeUs, true,
discontinuitySequence, mediaSequence, version, targetDurationUs, hasIndependentSegmentsTag,
hasEndTag, hasProgramDateTime, drmInitData, initializationSegment, segments);
return new HlsMediaPlaylist(
playlistType,
baseUri,
tags,
startOffsetUs,
startTimeUs,
/* hasDiscontinuitySequence= */ true,
discontinuitySequence,
mediaSequence,
version,
targetDurationUs,
hasIndependentSegmentsTag,
hasEndTag,
hasProgramDateTime,
drmInitData,
segments);
}

/**
Expand All @@ -311,9 +325,21 @@ public HlsMediaPlaylist copyWithEndTag() {
if (this.hasEndTag) {
return this;
}
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, startTimeUs,
hasDiscontinuitySequence, discontinuitySequence, mediaSequence, version, targetDurationUs,
hasIndependentSegmentsTag, true, hasProgramDateTime, drmInitData, initializationSegment,
return new HlsMediaPlaylist(
playlistType,
baseUri,
tags,
startOffsetUs,
startTimeUs,
hasDiscontinuitySequence,
discontinuitySequence,
mediaSequence,
version,
targetDurationUs,
hasIndependentSegmentsTag,
/* hasEndTag= */ true,
hasProgramDateTime,
drmInitData,
segments);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String
segments.add(
new Segment(
line,
initializationSegment,
segmentDurationUs,
relativeDiscontinuitySequence,
segmentStartTimeUs,
Expand All @@ -491,10 +492,22 @@ private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String
hasGapTag = false;
}
}
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, playlistStartTimeUs,
hasDiscontinuitySequence, playlistDiscontinuitySequence, mediaSequence, version,
targetDurationUs, hasIndependentSegmentsTag, hasEndTag, playlistStartTimeUs != 0,
drmInitData, initializationSegment, segments);
return new HlsMediaPlaylist(
playlistType,
baseUri,
tags,
startOffsetUs,
playlistStartTimeUs,
hasDiscontinuitySequence,
playlistDiscontinuitySequence,
mediaSequence,
version,
targetDurationUs,
hasIndependentSegmentsTag,
hasEndTag,
/* hasProgramDateTime= */ playlistStartTimeUs != 0,
drmInitData,
segments);
}

private static SchemeData parseWidevineSchemeData(String line, String keyFormat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,35 @@ public void testGapTag() throws IOException {
assertThat(playlist.segments.get(2).hasGapTag).isTrue();
assertThat(playlist.segments.get(3).hasGapTag).isFalse();
}

@Test
public void testMapTag() throws IOException {
Uri playlistUri = Uri.parse("https://example.com/test3.m3u8");
String playlistString =
"#EXTM3U\n"
+ "#EXT-X-VERSION:3\n"
+ "#EXT-X-TARGETDURATION:5\n"
+ "#EXT-X-MEDIA-SEQUENCE:10\n"
+ "#EXTINF:5.005,\n"
+ "02/00/27.ts\n"
+ "#EXT-X-MAP:URI=\"init1.ts\""
+ "#EXTINF:5.005,\n"
+ "02/00/32.ts\n"
+ "#EXTINF:5.005,\n"
+ "02/00/42.ts\n"
+ "#EXT-X-MAP:URI=\"init2.ts\""
+ "#EXTINF:5.005,\n"
+ "02/00/47.ts\n";
InputStream inputStream =
new ByteArrayInputStream(playlistString.getBytes(Charset.forName(C.UTF8_NAME)));
HlsMediaPlaylist playlist =
(HlsMediaPlaylist) new HlsPlaylistParser().parse(playlistUri, inputStream);

List<Segment> segments = playlist.segments;
assertThat(segments.get(0).initializationSegment).isNull();
assertThat(segments.get(1).initializationSegment)
.isSameAs(segments.get(2).initializationSegment);
assertThat(segments.get(1).initializationSegment.url).isEqualTo("init1.ts");
assertThat(segments.get(3).initializationSegment.url).isEqualTo("init2.ts");
}
}

0 comments on commit ddef32c

Please sign in to comment.