Commit 26728142 by aquilescanta Committed by Oliver Woodman

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
parent 3108b07c
...@@ -88,16 +88,18 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -88,16 +88,18 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
public final List<Format> muxedCaptionFormats; 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 variants See {@link #variants}.
* @param audios See {@link #audios}. * @param audios See {@link #audios}.
* @param subtitles See {@link #subtitles}. * @param subtitles See {@link #subtitles}.
* @param muxedAudioFormat See {@link #muxedAudioFormat}. * @param muxedAudioFormat See {@link #muxedAudioFormat}.
* @param muxedCaptionFormats See {@link #muxedCaptionFormats}. * @param muxedCaptionFormats See {@link #muxedCaptionFormats}.
*/ */
public HlsMasterPlaylist(String baseUri, List<HlsUrl> variants, List<HlsUrl> audios, public HlsMasterPlaylist(String baseUri, List<String> tags, List<HlsUrl> variants,
List<HlsUrl> subtitles, Format muxedAudioFormat, List<Format> muxedCaptionFormats) { List<HlsUrl> audios, List<HlsUrl> subtitles, Format muxedAudioFormat,
super(baseUri); List<Format> muxedCaptionFormats) {
super(baseUri, tags);
this.variants = Collections.unmodifiableList(variants); this.variants = Collections.unmodifiableList(variants);
this.audios = Collections.unmodifiableList(audios); this.audios = Collections.unmodifiableList(audios);
this.subtitles = Collections.unmodifiableList(subtitles); this.subtitles = Collections.unmodifiableList(subtitles);
...@@ -115,7 +117,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -115,7 +117,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
public static HlsMasterPlaylist createSingleVariantMasterPlaylist(String variantUrl) { public static HlsMasterPlaylist createSingleVariantMasterPlaylist(String variantUrl) {
List<HlsUrl> variant = Collections.singletonList(HlsUrl.createMediaPlaylistHlsUrl(variantUrl)); List<HlsUrl> variant = Collections.singletonList(HlsUrl.createMediaPlaylistHlsUrl(variantUrl));
List<HlsUrl> emptyList = Collections.emptyList(); 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);
} }
} }
...@@ -70,7 +70,7 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -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) @Retention(RetentionPolicy.SOURCE)
@IntDef({PLAYLIST_TYPE_UNKNOWN, PLAYLIST_TYPE_VOD, PLAYLIST_TYPE_EVENT}) @IntDef({PLAYLIST_TYPE_UNKNOWN, PLAYLIST_TYPE_VOD, PLAYLIST_TYPE_EVENT})
...@@ -79,28 +79,86 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -79,28 +79,86 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
public static final int PLAYLIST_TYPE_VOD = 1; public static final int PLAYLIST_TYPE_VOD = 1;
public static final int PLAYLIST_TYPE_EVENT = 2; public static final int PLAYLIST_TYPE_EVENT = 2;
/**
* The type of the playlist. See {@link PlaylistType}.
*/
@PlaylistType public final int playlistType; @PlaylistType public final int playlistType;
/**
* The start offset as defined by #EXT-X-START in microseconds.
*/
public final long startOffsetUs; public final long startOffsetUs;
/**
* The start time of the playlist in playback timebase in microseconds.
*/
public final long startTimeUs; public final long startTimeUs;
/**
* Whether the playlist contains the #EXT-X-DISCONTINUITY-SEQUENCE tag.
*/
public final boolean hasDiscontinuitySequence; public final boolean hasDiscontinuitySequence;
/**
* The discontinuity sequence number.
*/
public final int discontinuitySequence; public final int discontinuitySequence;
/**
* The media sequence number as defined by #EXT-X-MEDIA-SEQUENCE.
*/
public final int mediaSequence; public final int mediaSequence;
/**
* The compatibility version as defined by #EXT-X-VERSION.
*/
public final int version; public final int version;
/**
* The target duration as defined by #EXT-X-TARGETDURATION in microseconds.
*/
public final long targetDurationUs; public final long targetDurationUs;
/**
* Whether the playlist contains the #EXT-X-INDEPENDENT-SEGMENTS tag.
*/
public final boolean hasIndependentSegmentsTag; public final boolean hasIndependentSegmentsTag;
/**
* Whether the playlist contains the #EXT-X-ENDLIST tag.
*/
public final boolean hasEndTag; public final boolean hasEndTag;
/**
* Whether the playlist contains a #EXT-X-PROGRAM-DATE-TIME tag.
*/
public final boolean hasProgramDateTime; public final boolean hasProgramDateTime;
/**
* The initialization segment as defined by #EXT-X-MAP.
*/
public final Segment initializationSegment; public final Segment initializationSegment;
/**
* The list of segments in the playlist.
*/
public final List<Segment> segments; public final List<Segment> segments;
public final List<String> dateRanges; /**
* The total duration of the playlist in microseconds.
*/
public final long durationUs; public final long durationUs;
public HlsMediaPlaylist(@PlaylistType int playlistType, String baseUri, long startOffsetUs, /**
long startTimeUs, boolean hasDiscontinuitySequence, int discontinuitySequence, * @param playlistType See {@link #playlistType}.
int mediaSequence, int version, long targetDurationUs, boolean hasIndependentSegmentsTag, * @param baseUri See {@link #baseUri}.
boolean hasEndTag, boolean hasProgramDateTime, Segment initializationSegment, * @param tags See {@link #tags}.
List<Segment> segments, List<String> dateRanges) { * @param startOffsetUs See {@link #startOffsetUs}.
super(baseUri); * @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.playlistType = playlistType;
this.startTimeUs = startTimeUs; this.startTimeUs = startTimeUs;
this.hasDiscontinuitySequence = hasDiscontinuitySequence; this.hasDiscontinuitySequence = hasDiscontinuitySequence;
...@@ -121,7 +179,6 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -121,7 +179,6 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
} }
this.startOffsetUs = startOffsetUs == C.TIME_UNSET ? C.TIME_UNSET this.startOffsetUs = startOffsetUs == C.TIME_UNSET ? C.TIME_UNSET
: startOffsetUs >= 0 ? startOffsetUs : durationUs + startOffsetUs; : startOffsetUs >= 0 ? startOffsetUs : durationUs + startOffsetUs;
this.dateRanges = Collections.unmodifiableList(dateRanges);
} }
/** /**
...@@ -144,6 +201,11 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -144,6 +201,11 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
|| (segmentCount == otherSegmentCount && hasEndTag && !other.hasEndTag); || (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() { public long getEndTimeUs() {
return startTimeUs + durationUs; return startTimeUs + durationUs;
} }
...@@ -158,9 +220,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -158,9 +220,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* @return The playlist. * @return The playlist.
*/ */
public HlsMediaPlaylist copyWith(long startTimeUs, int discontinuitySequence) { 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, discontinuitySequence, mediaSequence, version, targetDurationUs, hasIndependentSegmentsTag,
hasEndTag, hasProgramDateTime, initializationSegment, segments, dateRanges); hasEndTag, hasProgramDateTime, initializationSegment, segments);
} }
/** /**
...@@ -173,10 +235,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -173,10 +235,9 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
if (this.hasEndTag) { if (this.hasEndTag) {
return this; return this;
} }
return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, startTimeUs, return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, startTimeUs,
hasDiscontinuitySequence, discontinuitySequence, mediaSequence, version, targetDurationUs, hasDiscontinuitySequence, discontinuitySequence, mediaSequence, version, targetDurationUs,
hasIndependentSegmentsTag, true, hasProgramDateTime, initializationSegment, segments, hasIndependentSegmentsTag, true, hasProgramDateTime, initializationSegment, segments);
dateRanges);
} }
} }
...@@ -15,15 +15,30 @@ ...@@ -15,15 +15,30 @@
*/ */
package com.google.android.exoplayer2.source.hls.playlist; package com.google.android.exoplayer2.source.hls.playlist;
import java.util.Collections;
import java.util.List;
/** /**
* Represents an HLS playlist. * Represents an HLS playlist.
*/ */
public abstract class HlsPlaylist { public abstract class HlsPlaylist {
/**
* The base uri. Used to resolve relative paths.
*/
public final String baseUri; 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.baseUri = baseUri;
this.tags = Collections.unmodifiableList(tags);
} }
} }
...@@ -43,6 +43,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -43,6 +43,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final String PLAYLIST_HEADER = "#EXTM3U"; 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_VERSION = "#EXT-X-VERSION";
private static final String TAG_PLAYLIST_TYPE = "#EXT-X-PLAYLIST-TYPE"; private static final String TAG_PLAYLIST_TYPE = "#EXT-X-PLAYLIST-TYPE";
private static final String TAG_STREAM_INF = "#EXT-X-STREAM-INF"; private static final String TAG_STREAM_INF = "#EXT-X-STREAM-INF";
...@@ -59,7 +61,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -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_ENDLIST = "#EXT-X-ENDLIST";
private static final String TAG_KEY = "#EXT-X-KEY"; private static final String TAG_KEY = "#EXT-X-KEY";
private static final String TAG_BYTERANGE = "#EXT-X-BYTERANGE"; 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_AUDIO = "AUDIO";
private static final String TYPE_VIDEO = "VIDEO"; private static final String TYPE_VIDEO = "VIDEO";
...@@ -176,6 +177,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -176,6 +177,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
ArrayList<HlsMasterPlaylist.HlsUrl> variants = new ArrayList<>(); ArrayList<HlsMasterPlaylist.HlsUrl> variants = new ArrayList<>();
ArrayList<HlsMasterPlaylist.HlsUrl> audios = new ArrayList<>(); ArrayList<HlsMasterPlaylist.HlsUrl> audios = new ArrayList<>();
ArrayList<HlsMasterPlaylist.HlsUrl> subtitles = new ArrayList<>(); ArrayList<HlsMasterPlaylist.HlsUrl> subtitles = new ArrayList<>();
ArrayList<String> tags = new ArrayList<>();
Format muxedAudioFormat = null; Format muxedAudioFormat = null;
List<Format> muxedCaptionFormats = null; List<Format> muxedCaptionFormats = null;
boolean noClosedCaptions = false; boolean noClosedCaptions = false;
...@@ -183,6 +185,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -183,6 +185,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String line; String line;
while (iterator.hasNext()) { while (iterator.hasNext()) {
line = iterator.next(); line = iterator.next();
if (line.startsWith(TAG_PREFIX)) {
// We expose all tags through the playlist.
tags.add(line);
}
if (line.startsWith(TAG_MEDIA)) { if (line.startsWith(TAG_MEDIA)) {
@C.SelectionFlags int selectionFlags = parseSelectionFlags(line); @C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
String uri = parseOptionalStringAttr(line, REGEX_URI); String uri = parseOptionalStringAttr(line, REGEX_URI);
...@@ -255,7 +263,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -255,7 +263,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
if (noClosedCaptions) { if (noClosedCaptions) {
muxedCaptionFormats = Collections.emptyList(); muxedCaptionFormats = Collections.emptyList();
} }
return new HlsMasterPlaylist(baseUri, variants, audios, subtitles, muxedAudioFormat, return new HlsMasterPlaylist(baseUri, tags, variants, audios, subtitles, muxedAudioFormat,
muxedCaptionFormats); muxedCaptionFormats);
} }
...@@ -277,7 +285,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -277,7 +285,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
boolean hasEndTag = false; boolean hasEndTag = false;
Segment initializationSegment = null; Segment initializationSegment = null;
List<Segment> segments = new ArrayList<>(); List<Segment> segments = new ArrayList<>();
List<String> dateRanges = new ArrayList<>(); List<String> tags = new ArrayList<>();
long segmentDurationUs = 0; long segmentDurationUs = 0;
boolean hasDiscontinuitySequence = false; boolean hasDiscontinuitySequence = false;
...@@ -296,6 +304,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -296,6 +304,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
String line; String line;
while (iterator.hasNext()) { while (iterator.hasNext()) {
line = iterator.next(); line = iterator.next();
if (line.startsWith(TAG_PREFIX)) {
// We expose all tags through the playlist.
tags.add(line);
}
if (line.startsWith(TAG_PLAYLIST_TYPE)) { if (line.startsWith(TAG_PLAYLIST_TYPE)) {
String playlistTypeString = parseStringAttr(line, REGEX_PLAYLIST_TYPE); String playlistTypeString = parseStringAttr(line, REGEX_PLAYLIST_TYPE);
if ("VOD".equals(playlistTypeString)) { if ("VOD".equals(playlistTypeString)) {
...@@ -358,8 +372,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -358,8 +372,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
C.msToUs(Util.parseXsDateTime(line.substring(line.indexOf(':') + 1))); C.msToUs(Util.parseXsDateTime(line.substring(line.indexOf(':') + 1)));
playlistStartTimeUs = programDatetimeUs - segmentStartTimeUs; playlistStartTimeUs = programDatetimeUs - segmentStartTimeUs;
} }
} else if (line.startsWith(TAG_DATERANGE)) {
dateRanges.add(line);
} else if (!line.startsWith("#")) { } else if (!line.startsWith("#")) {
String segmentEncryptionIV; String segmentEncryptionIV;
if (!isEncrypted) { if (!isEncrypted) {
...@@ -388,10 +400,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -388,10 +400,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
hasEndTag = true; hasEndTag = true;
} }
} }
return new HlsMediaPlaylist(playlistType, baseUri, startOffsetUs, playlistStartTimeUs, return new HlsMediaPlaylist(playlistType, baseUri, tags, startOffsetUs, playlistStartTimeUs,
hasDiscontinuitySequence, playlistDiscontinuitySequence, mediaSequence, version, hasDiscontinuitySequence, playlistDiscontinuitySequence, mediaSequence, version,
targetDurationUs, hasIndependentSegmentsTag, hasEndTag, playlistStartTimeUs != 0, targetDurationUs, hasIndependentSegmentsTag, hasEndTag, playlistStartTimeUs != 0,
initializationSegment, segments, dateRanges); initializationSegment, segments);
} }
private static String parseStringAttr(String line, Pattern pattern) throws ParserException { private static String parseStringAttr(String line, Pattern pattern) throws ParserException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment