Expose all "other" tags that start with #EXT through the playlist

"other" includes tags for which there is no existing behavior defined.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157217270
This commit is contained in:
aquilescanta 2017-05-26 07:14:59 -07:00 committed by Oliver Woodman
parent 3108b07c90
commit 26728142ee
4 changed files with 118 additions and 27 deletions

View file

@ -88,16 +88,18 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
public final List<Format> muxedCaptionFormats;
/**
* @param baseUri The base uri. Used to resolve relative paths.
* @param baseUri See {@link #baseUri}.
* @param tags See {@link #tags}.
* @param variants See {@link #variants}.
* @param audios See {@link #audios}.
* @param subtitles See {@link #subtitles}.
* @param muxedAudioFormat See {@link #muxedAudioFormat}.
* @param muxedCaptionFormats See {@link #muxedCaptionFormats}.
*/
public HlsMasterPlaylist(String baseUri, List<HlsUrl> variants, List<HlsUrl> audios,
List<HlsUrl> subtitles, Format muxedAudioFormat, List<Format> muxedCaptionFormats) {
super(baseUri);
public HlsMasterPlaylist(String baseUri, List<String> tags, List<HlsUrl> variants,
List<HlsUrl> audios, List<HlsUrl> subtitles, Format muxedAudioFormat,
List<Format> muxedCaptionFormats) {
super(baseUri, tags);
this.variants = Collections.unmodifiableList(variants);
this.audios = Collections.unmodifiableList(audios);
this.subtitles = Collections.unmodifiableList(subtitles);
@ -115,7 +117,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
public static HlsMasterPlaylist createSingleVariantMasterPlaylist(String variantUrl) {
List<HlsUrl> variant = Collections.singletonList(HlsUrl.createMediaPlaylistHlsUrl(variantUrl));
List<HlsUrl> emptyList = Collections.emptyList();
return new HlsMasterPlaylist(null, variant, emptyList, emptyList, null, null);
return new HlsMasterPlaylist(null, Collections.<String>emptyList(), variant, emptyList,
emptyList, null, null);
}
}

View file

@ -70,7 +70,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
}
/**
* Type of the playlist as specified by #EXT-X-PLAYLIST-TYPE.
* Type of the playlist as defined by #EXT-X-PLAYLIST-TYPE.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({PLAYLIST_TYPE_UNKNOWN, PLAYLIST_TYPE_VOD, PLAYLIST_TYPE_EVENT})
@ -79,28 +79,86 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
public static final int PLAYLIST_TYPE_VOD = 1;
public static final int PLAYLIST_TYPE_EVENT = 2;
/**
* The type of the playlist. See {@link PlaylistType}.
*/
@PlaylistType public final int playlistType;
/**
* The start offset as defined by #EXT-X-START in microseconds.
*/
public final long startOffsetUs;
/**
* The start time of the playlist in playback timebase in microseconds.
*/
public final long startTimeUs;
/**
* Whether the playlist contains the #EXT-X-DISCONTINUITY-SEQUENCE tag.
*/
public final boolean hasDiscontinuitySequence;
/**
* The discontinuity sequence number.
*/
public final int discontinuitySequence;
/**
* The media sequence number as defined by #EXT-X-MEDIA-SEQUENCE.
*/
public final int mediaSequence;
/**
* The compatibility version as defined by #EXT-X-VERSION.
*/
public final int version;
/**
* The target duration as defined by #EXT-X-TARGETDURATION in microseconds.
*/
public final long targetDurationUs;
/**
* Whether the playlist contains the #EXT-X-INDEPENDENT-SEGMENTS tag.
*/
public final boolean hasIndependentSegmentsTag;
/**
* Whether the playlist contains the #EXT-X-ENDLIST tag.
*/
public final boolean hasEndTag;
/**
* Whether the playlist contains a #EXT-X-PROGRAM-DATE-TIME tag.
*/
public final boolean hasProgramDateTime;
/**
* The initialization segment as defined by #EXT-X-MAP.
*/
public final Segment initializationSegment;
/**
* The list of segments in the playlist.
*/
public final List<Segment> segments;
public final List<String> dateRanges;
/**
* The total duration of the playlist in microseconds.
*/
public final long durationUs;
public HlsMediaPlaylist(@PlaylistType int playlistType, String baseUri, long startOffsetUs,
long startTimeUs, boolean hasDiscontinuitySequence, int discontinuitySequence,
int mediaSequence, int version, long targetDurationUs, boolean hasIndependentSegmentsTag,
boolean hasEndTag, boolean hasProgramDateTime, Segment initializationSegment,
List<Segment> segments, List<String> dateRanges) {
super(baseUri);
/**
* @param playlistType See {@link #playlistType}.
* @param baseUri See {@link #baseUri}.
* @param tags See {@link #tags}.
* @param startOffsetUs See {@link #startOffsetUs}.
* @param startTimeUs See {@link #startTimeUs}.
* @param hasDiscontinuitySequence See {@link #hasDiscontinuitySequence}.
* @param discontinuitySequence See {@link #discontinuitySequence}.
* @param mediaSequence See {@link #mediaSequence}.
* @param version See {@link #version}.
* @param targetDurationUs See {@link #targetDurationUs}.
* @param hasIndependentSegmentsTag See {@link #hasIndependentSegmentsTag}.
* @param hasEndTag See {@link #hasEndTag}.
* @param hasProgramDateTime See {@link #hasProgramDateTime}.
* @param initializationSegment See {@link #initializationSegment}.
* @param segments See {@link #segments}.
*/
public HlsMediaPlaylist(@PlaylistType int playlistType, String baseUri, List<String> tags,
long startOffsetUs, long startTimeUs, boolean hasDiscontinuitySequence,
int discontinuitySequence, int mediaSequence, int version, long targetDurationUs,
boolean hasIndependentSegmentsTag, boolean hasEndTag, boolean hasProgramDateTime,
Segment initializationSegment, List<Segment> segments) {
super(baseUri, tags);
this.playlistType = playlistType;
this.startTimeUs = startTimeUs;
this.hasDiscontinuitySequence = hasDiscontinuitySequence;
@ -121,7 +179,6 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
}
this.startOffsetUs = startOffsetUs == C.TIME_UNSET ? C.TIME_UNSET
: startOffsetUs >= 0 ? startOffsetUs : durationUs + startOffsetUs;
this.dateRanges = Collections.unmodifiableList(dateRanges);
}
/**
@ -144,6 +201,11 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|| (segmentCount == otherSegmentCount && hasEndTag && !other.hasEndTag);
}
/**
* Returns the result of adding the duration of the playlist to its start time.
*
* @return The result of adding the duration of the playlist to its start time.
*/
public long getEndTimeUs() {
return startTimeUs + durationUs;
}
@ -158,9 +220,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* @return The playlist.
*/
public HlsMediaPlaylist copyWith(long startTimeUs, int discontinuitySequence) {
return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, startTimeUs, true,
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, startTimeUs, true,
discontinuitySequence, mediaSequence, version, targetDurationUs, hasIndependentSegmentsTag,
hasEndTag, hasProgramDateTime, initializationSegment, segments, dateRanges);
hasEndTag, hasProgramDateTime, initializationSegment, segments);
}
/**
@ -173,10 +235,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
if (this.hasEndTag) {
return this;
}
return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, startTimeUs,
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, startTimeUs,
hasDiscontinuitySequence, discontinuitySequence, mediaSequence, version, targetDurationUs,
hasIndependentSegmentsTag, true, hasProgramDateTime, initializationSegment, segments,
dateRanges);
hasIndependentSegmentsTag, true, hasProgramDateTime, initializationSegment, segments);
}
}

View file

@ -15,15 +15,30 @@
*/
package com.google.android.exoplayer2.source.hls.playlist;
import java.util.Collections;
import java.util.List;
/**
* Represents an HLS playlist.
*/
public abstract class HlsPlaylist {
/**
* The base uri. Used to resolve relative paths.
*/
public final String baseUri;
/**
* The list of tags in the playlist.
*/
public final List<String> tags;
protected HlsPlaylist(String baseUri) {
/**
* @param baseUri See {@link #baseUri}.
* @param tags See {@link #tags}.
*/
protected HlsPlaylist(String baseUri, List<String> tags) {
this.baseUri = baseUri;
this.tags = Collections.unmodifiableList(tags);
}
}

View file

@ -43,6 +43,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final String PLAYLIST_HEADER = "#EXTM3U";
private static final String TAG_PREFIX = "#EXT";
private static final String TAG_VERSION = "#EXT-X-VERSION";
private static final String TAG_PLAYLIST_TYPE = "#EXT-X-PLAYLIST-TYPE";
private static final String TAG_STREAM_INF = "#EXT-X-STREAM-INF";
@ -59,7 +61,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
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";
private static final String TAG_DATERANGE = "#EXT-X-DATERANGE";
private static final String TYPE_AUDIO = "AUDIO";
private static final String TYPE_VIDEO = "VIDEO";
@ -176,6 +177,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
ArrayList<HlsMasterPlaylist.HlsUrl> variants = new ArrayList<>();
ArrayList<HlsMasterPlaylist.HlsUrl> audios = new ArrayList<>();
ArrayList<HlsMasterPlaylist.HlsUrl> subtitles = new ArrayList<>();
ArrayList<String> tags = new ArrayList<>();
Format muxedAudioFormat = null;
List<Format> muxedCaptionFormats = null;
boolean noClosedCaptions = false;
@ -183,6 +185,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String line;
while (iterator.hasNext()) {
line = iterator.next();
if (line.startsWith(TAG_PREFIX)) {
// We expose all tags through the playlist.
tags.add(line);
}
if (line.startsWith(TAG_MEDIA)) {
@C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
String uri = parseOptionalStringAttr(line, REGEX_URI);
@ -255,7 +263,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
if (noClosedCaptions) {
muxedCaptionFormats = Collections.emptyList();
}
return new HlsMasterPlaylist(baseUri, variants, audios, subtitles, muxedAudioFormat,
return new HlsMasterPlaylist(baseUri, tags, variants, audios, subtitles, muxedAudioFormat,
muxedCaptionFormats);
}
@ -277,7 +285,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
boolean hasEndTag = false;
Segment initializationSegment = null;
List<Segment> segments = new ArrayList<>();
List<String> dateRanges = new ArrayList<>();
List<String> tags = new ArrayList<>();
long segmentDurationUs = 0;
boolean hasDiscontinuitySequence = false;
@ -296,6 +304,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String line;
while (iterator.hasNext()) {
line = iterator.next();
if (line.startsWith(TAG_PREFIX)) {
// We expose all tags through the playlist.
tags.add(line);
}
if (line.startsWith(TAG_PLAYLIST_TYPE)) {
String playlistTypeString = parseStringAttr(line, REGEX_PLAYLIST_TYPE);
if ("VOD".equals(playlistTypeString)) {
@ -358,8 +372,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
C.msToUs(Util.parseXsDateTime(line.substring(line.indexOf(':') + 1)));
playlistStartTimeUs = programDatetimeUs - segmentStartTimeUs;
}
} else if (line.startsWith(TAG_DATERANGE)) {
dateRanges.add(line);
} else if (!line.startsWith("#")) {
String segmentEncryptionIV;
if (!isEncrypted) {
@ -388,10 +400,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
hasEndTag = true;
}
}
return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, playlistStartTimeUs,
return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, playlistStartTimeUs,
hasDiscontinuitySequence, playlistDiscontinuitySequence, mediaSequence, version,
targetDurationUs, hasIndependentSegmentsTag, hasEndTag, playlistStartTimeUs != 0,
initializationSegment, segments, dateRanges);
initializationSegment, segments);
}
private static String parseStringAttr(String line, Pattern pattern) throws ParserException {