mirror of
https://github.com/androidx/media.git
synced 2025-05-07 23:50:44 +08:00
Add support for HLS track selection flags
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=125658752
This commit is contained in:
parent
3e6c0ced82
commit
762ec41f95
@ -60,6 +60,11 @@ public final class Format implements Parcelable {
|
|||||||
* Indicates that the track must be displayed. Only applies to text tracks.
|
* Indicates that the track must be displayed. Only applies to text tracks.
|
||||||
*/
|
*/
|
||||||
public static final int SELECTION_FLAG_FORCED = 2;
|
public static final int SELECTION_FLAG_FORCED = 2;
|
||||||
|
/**
|
||||||
|
* Indicates that the player may choose to play the track in absence of an explicit user
|
||||||
|
* preference.
|
||||||
|
*/
|
||||||
|
public static final int SELECTION_FLAG_AUTOSELECT = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A value for {@link #subsampleOffsetUs} to indicate that subsample timestamps are relative to
|
* A value for {@link #subsampleOffsetUs} to indicate that subsample timestamps are relative to
|
||||||
@ -391,6 +396,7 @@ public final class Format implements Parcelable {
|
|||||||
String codecs = this.codecs == null ? manifestFormat.codecs : this.codecs;
|
String codecs = this.codecs == null ? manifestFormat.codecs : this.codecs;
|
||||||
int bitrate = this.bitrate == NO_VALUE ? manifestFormat.bitrate : this.bitrate;
|
int bitrate = this.bitrate == NO_VALUE ? manifestFormat.bitrate : this.bitrate;
|
||||||
float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate;
|
float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate;
|
||||||
|
int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags;
|
||||||
String language = this.language == null ? manifestFormat.language : this.language;
|
String language = this.language == null ? manifestFormat.language : this.language;
|
||||||
DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null)
|
DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null)
|
||||||
|| this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData;
|
|| this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData;
|
||||||
|
@ -510,7 +510,8 @@ import java.util.List;
|
|||||||
return sampleFormat;
|
return sampleFormat;
|
||||||
}
|
}
|
||||||
return sampleFormat.copyWithContainerInfo(containerFormat.id, containerFormat.bitrate,
|
return sampleFormat.copyWithContainerInfo(containerFormat.id, containerFormat.bitrate,
|
||||||
containerFormat.width, containerFormat.height, 0, containerFormat.language);
|
containerFormat.width, containerFormat.height, containerFormat.selectionFlags,
|
||||||
|
containerFormat.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeStartLoading() {
|
private void maybeStartLoading() {
|
||||||
|
@ -25,6 +25,9 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
/* package */ final class HlsParserUtil {
|
/* package */ final class HlsParserUtil {
|
||||||
|
|
||||||
|
private static final String BOOLEAN_TRUE_VALUE = "YES";
|
||||||
|
private static final String BOOLEAN_FALSE_VALUE = "NO";
|
||||||
|
|
||||||
private HlsParserUtil() {}
|
private HlsParserUtil() {}
|
||||||
|
|
||||||
public static String parseStringAttr(String line, Pattern pattern, String tag)
|
public static String parseStringAttr(String line, Pattern pattern, String tag)
|
||||||
@ -54,4 +57,17 @@ import java.util.regex.Pattern;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean parseBooleanAttribute(String line, Pattern pattern, boolean defaultValue) {
|
||||||
|
Matcher matcher = pattern.matcher(line);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group(1).equals(BOOLEAN_TRUE_VALUE);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pattern compileBooleanAttrPattern(String attribute) {
|
||||||
|
return Pattern.compile(attribute + "=(" + BOOLEAN_FALSE_VALUE + "|" + BOOLEAN_TRUE_VALUE + ")");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
private static final String URI_ATTR = "URI";
|
private static final String URI_ATTR = "URI";
|
||||||
private static final String IV_ATTR = "IV";
|
private static final String IV_ATTR = "IV";
|
||||||
private static final String INSTREAM_ID_ATTR = "INSTREAM-ID";
|
private static final String INSTREAM_ID_ATTR = "INSTREAM-ID";
|
||||||
|
private static final String AUTOSELECT_ATTR = "AUTOSELECT";
|
||||||
|
private static final String DEFAULT_ATTR = "DEFAULT";
|
||||||
|
private static final String FORCED_ATTR = "FORCED";
|
||||||
|
|
||||||
private static final String AUDIO_TYPE = "AUDIO";
|
private static final String AUDIO_TYPE = "AUDIO";
|
||||||
private static final String VIDEO_TYPE = "VIDEO";
|
private static final String VIDEO_TYPE = "VIDEO";
|
||||||
@ -103,10 +106,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
Pattern.compile(NAME_ATTR + "=\"(.+?)\"");
|
Pattern.compile(NAME_ATTR + "=\"(.+?)\"");
|
||||||
private static final Pattern INSTREAM_ID_ATTR_REGEX =
|
private static final Pattern INSTREAM_ID_ATTR_REGEX =
|
||||||
Pattern.compile(INSTREAM_ID_ATTR + "=\"(.+?)\"");
|
Pattern.compile(INSTREAM_ID_ATTR + "=\"(.+?)\"");
|
||||||
// private static final Pattern AUTOSELECT_ATTR_REGEX =
|
private static final Pattern AUTOSELECT_ATTR_REGEX =
|
||||||
// HlsParserUtil.compileBooleanAttrPattern(AUTOSELECT_ATTR);
|
HlsParserUtil.compileBooleanAttrPattern(AUTOSELECT_ATTR);
|
||||||
// private static final Pattern DEFAULT_ATTR_REGEX =
|
private static final Pattern DEFAULT_ATTR_REGEX =
|
||||||
// HlsParserUtil.compileBooleanAttrPattern(DEFAULT_ATTR);
|
HlsParserUtil.compileBooleanAttrPattern(DEFAULT_ATTR);
|
||||||
|
private static final Pattern FORCED_ATTR_REGEX =
|
||||||
|
HlsParserUtil.compileBooleanAttrPattern(FORCED_ATTR);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HlsPlaylist parse(Uri uri, InputStream inputStream) throws IOException {
|
public HlsPlaylist parse(Uri uri, InputStream inputStream) throws IOException {
|
||||||
@ -159,6 +164,13 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
line = iterator.next();
|
line = iterator.next();
|
||||||
if (line.startsWith(MEDIA_TAG)) {
|
if (line.startsWith(MEDIA_TAG)) {
|
||||||
|
boolean isDefault = HlsParserUtil.parseBooleanAttribute(line, DEFAULT_ATTR_REGEX, false);
|
||||||
|
boolean isForced = HlsParserUtil.parseBooleanAttribute(line, FORCED_ATTR_REGEX, false);
|
||||||
|
boolean isAutoselect = HlsParserUtil.parseBooleanAttribute(line, AUTOSELECT_ATTR_REGEX,
|
||||||
|
false);
|
||||||
|
int selectionFlags = (isDefault ? Format.SELECTION_FLAG_DEFAULT : 0)
|
||||||
|
| (isForced ? Format.SELECTION_FLAG_FORCED : 0)
|
||||||
|
| (isAutoselect ? Format.SELECTION_FLAG_AUTOSELECT : 0);
|
||||||
String type = HlsParserUtil.parseStringAttr(line, TYPE_ATTR_REGEX, TYPE_ATTR);
|
String type = HlsParserUtil.parseStringAttr(line, TYPE_ATTR_REGEX, TYPE_ATTR);
|
||||||
if (CLOSED_CAPTIONS_TYPE.equals(type)) {
|
if (CLOSED_CAPTIONS_TYPE.equals(type)) {
|
||||||
String instreamId = HlsParserUtil.parseStringAttr(line, INSTREAM_ID_ATTR_REGEX,
|
String instreamId = HlsParserUtil.parseStringAttr(line, INSTREAM_ID_ATTR_REGEX,
|
||||||
@ -168,7 +180,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
String captionName = HlsParserUtil.parseStringAttr(line, NAME_ATTR_REGEX, NAME_ATTR);
|
String captionName = HlsParserUtil.parseStringAttr(line, NAME_ATTR_REGEX, NAME_ATTR);
|
||||||
String language = HlsParserUtil.parseOptionalStringAttr(line, LANGUAGE_ATTR_REGEX);
|
String language = HlsParserUtil.parseOptionalStringAttr(line, LANGUAGE_ATTR_REGEX);
|
||||||
muxedCaptionFormat = Format.createTextContainerFormat(captionName,
|
muxedCaptionFormat = Format.createTextContainerFormat(captionName,
|
||||||
MimeTypes.APPLICATION_M3U8, MimeTypes.APPLICATION_EIA608, null, -1, 0, language);
|
MimeTypes.APPLICATION_M3U8, MimeTypes.APPLICATION_EIA608, null, -1, selectionFlags,
|
||||||
|
language);
|
||||||
}
|
}
|
||||||
} else if (SUBTITLES_TYPE.equals(type)) {
|
} else if (SUBTITLES_TYPE.equals(type)) {
|
||||||
// We assume all subtitles belong to the same group.
|
// We assume all subtitles belong to the same group.
|
||||||
@ -176,7 +189,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
String uri = HlsParserUtil.parseStringAttr(line, URI_ATTR_REGEX, URI_ATTR);
|
String uri = HlsParserUtil.parseStringAttr(line, URI_ATTR_REGEX, URI_ATTR);
|
||||||
String language = HlsParserUtil.parseOptionalStringAttr(line, LANGUAGE_ATTR_REGEX);
|
String language = HlsParserUtil.parseOptionalStringAttr(line, LANGUAGE_ATTR_REGEX);
|
||||||
Format format = Format.createTextContainerFormat(subtitleName, MimeTypes.APPLICATION_M3U8,
|
Format format = Format.createTextContainerFormat(subtitleName, MimeTypes.APPLICATION_M3U8,
|
||||||
MimeTypes.TEXT_VTT, null, bitrate, 0, language);
|
MimeTypes.TEXT_VTT, null, bitrate, selectionFlags, language);
|
||||||
subtitles.add(new Variant(uri, format, codecs));
|
subtitles.add(new Variant(uri, format, codecs));
|
||||||
} else if (AUDIO_TYPE.equals(type)) {
|
} else if (AUDIO_TYPE.equals(type)) {
|
||||||
// We assume all audios belong to the same group.
|
// We assume all audios belong to the same group.
|
||||||
@ -185,7 +198,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||||||
String audioName = HlsParserUtil.parseStringAttr(line, NAME_ATTR_REGEX, NAME_ATTR);
|
String audioName = HlsParserUtil.parseStringAttr(line, NAME_ATTR_REGEX, NAME_ATTR);
|
||||||
int audioBitrate = uri != null ? bitrate : -1;
|
int audioBitrate = uri != null ? bitrate : -1;
|
||||||
Format format = Format.createAudioContainerFormat(audioName, MimeTypes.APPLICATION_M3U8,
|
Format format = Format.createAudioContainerFormat(audioName, MimeTypes.APPLICATION_M3U8,
|
||||||
null, null, audioBitrate, -1, -1, null, 0, language);
|
null, null, audioBitrate, -1, -1, null, selectionFlags, language);
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
audios.add(new Variant(uri, format, codecs));
|
audios.add(new Variant(uri, format, codecs));
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user