Format cleanup

This commit is contained in:
Oliver Woodman 2018-07-12 16:08:11 +01:00
parent 41636ada88
commit 05a31dfd24
13 changed files with 1036 additions and 271 deletions

View File

@ -101,8 +101,15 @@ import com.google.android.gms.cast.MediaTrack;
* @return The equivalent {@link Format}. * @return The equivalent {@link Format}.
*/ */
public static Format mediaTrackToFormat(MediaTrack mediaTrack) { public static Format mediaTrackToFormat(MediaTrack mediaTrack) {
return Format.createContainerFormat(mediaTrack.getContentId(), mediaTrack.getContentType(), return Format.createContainerFormat(
null, null, Format.NO_VALUE, 0, mediaTrack.getLanguage()); mediaTrack.getContentId(),
/* label= */ null,
mediaTrack.getContentType(),
/* sampleMimeType= */ null,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
/* selectionFlags= */ 0,
mediaTrack.getLanguage());
} }
private CastUtils() {} private CastUtils() {}

View File

@ -64,10 +64,35 @@ public final class FormatTest {
ColorInfo colorInfo = new ColorInfo(C.COLOR_SPACE_BT709, ColorInfo colorInfo = new ColorInfo(C.COLOR_SPACE_BT709,
C.COLOR_RANGE_LIMITED, C.COLOR_TRANSFER_SDR, new byte[] {1, 2, 3, 4, 5, 6, 7}); C.COLOR_RANGE_LIMITED, C.COLOR_TRANSFER_SDR, new byte[] {1, 2, 3, 4, 5, 6, 7});
Format formatToParcel = new Format("id", MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null, Format formatToParcel =
1024, 2048, 1920, 1080, 24, 90, 2, projectionData, C.STEREO_MODE_TOP_BOTTOM, colorInfo, 6, new Format(
44100, C.ENCODING_PCM_24BIT, 1001, 1002, 0, "und", Format.NO_VALUE, "id",
Format.OFFSET_SAMPLE_RELATIVE, INIT_DATA, drmInitData, metadata); "label",
/* containerMimeType= */ MimeTypes.VIDEO_MP4,
/* sampleMimeType= */ MimeTypes.VIDEO_H264,
"codec",
/* bitrate= */ 1024,
/* maxInputSize= */ 2048,
/* width= */ 1920,
/* height= */ 1080,
/* frameRate= */ 24,
/* rotationDegrees= */ 90,
/* pixelWidthHeightRatio= */ 2,
projectionData,
C.STEREO_MODE_TOP_BOTTOM,
colorInfo,
/* channelCount= */ 6,
/* sampleRate= */ 44100,
C.ENCODING_PCM_24BIT,
/* encoderDelay= */ 1001,
/* encoderPadding= */ 1002,
C.SELECTION_FLAG_DEFAULT,
"language",
/* accessibilityChannel= */ Format.NO_VALUE,
Format.OFFSET_SAMPLE_RELATIVE,
INIT_DATA,
drmInitData,
metadata);
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
formatToParcel.writeToParcel(parcel, 0); formatToParcel.writeToParcel(parcel, 0);

View File

@ -38,14 +38,15 @@ public final class RawCcExtractorTest {
public Extractor create() { public Extractor create() {
return new RawCcExtractor( return new RawCcExtractor(
Format.createTextContainerFormat( Format.createTextContainerFormat(
null, /* id= */ null,
null, /* label= */ null,
MimeTypes.APPLICATION_CEA608, /* containerMimeType= */ null,
"cea608", /* sampleMimeType= */ MimeTypes.APPLICATION_CEA608,
Format.NO_VALUE, /* codecs= */ "cea608",
0, /* bitrate= */ Format.NO_VALUE,
null, /* selectionFlags= */ 0,
1)); /* language= */ null,
/* accessibilityChannel= */ 1));
} }
}, },
"rawcc/sample.rawcc"); "rawcc/sample.rawcc");

View File

@ -759,45 +759,12 @@ public final class DefaultTrackSelectorTest {
/** Tests text track selection flags. */ /** Tests text track selection flags. */
@Test @Test
public void testsTextTrackSelectionFlags() throws ExoPlaybackException { public void testsTextTrackSelectionFlags() throws ExoPlaybackException {
Format forcedOnly = Format forcedOnly = buildTextFormat("forcedOnly", "eng", C.SELECTION_FLAG_FORCED);
Format.createTextContainerFormat(
"forcedOnly",
null,
MimeTypes.TEXT_VTT,
null,
Format.NO_VALUE,
C.SELECTION_FLAG_FORCED,
"eng");
Format forcedDefault = Format forcedDefault =
Format.createTextContainerFormat( buildTextFormat("forcedDefault", "eng", C.SELECTION_FLAG_FORCED | C.SELECTION_FLAG_DEFAULT);
"forcedDefault", Format defaultOnly = buildTextFormat("defaultOnly", "eng", C.SELECTION_FLAG_DEFAULT);
null, Format forcedOnlySpanish = buildTextFormat("forcedOnlySpanish", "spa", C.SELECTION_FLAG_FORCED);
MimeTypes.TEXT_VTT, Format noFlag = buildTextFormat("noFlag", "eng");
null,
Format.NO_VALUE,
C.SELECTION_FLAG_FORCED | C.SELECTION_FLAG_DEFAULT,
"eng");
Format defaultOnly =
Format.createTextContainerFormat(
"defaultOnly",
null,
MimeTypes.TEXT_VTT,
null,
Format.NO_VALUE,
C.SELECTION_FLAG_DEFAULT,
"eng");
Format forcedOnlySpanish =
Format.createTextContainerFormat(
"forcedOnlySpanish",
null,
MimeTypes.TEXT_VTT,
null,
Format.NO_VALUE,
C.SELECTION_FLAG_FORCED,
"spa");
Format noFlag =
Format.createTextContainerFormat(
"noFlag", null, MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "eng");
RendererCapabilities[] textRendererCapabilities = RendererCapabilities[] textRendererCapabilities =
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES}; new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES};
@ -891,14 +858,10 @@ public final class DefaultTrackSelectorTest {
*/ */
@Test @Test
public void testSelectUndeterminedTextLanguageAsFallback() throws ExoPlaybackException{ public void testSelectUndeterminedTextLanguageAsFallback() throws ExoPlaybackException{
Format spanish = Format.createTextContainerFormat("spanish", null, Format spanish = buildTextFormat("spanish", "spa");
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "spa"); Format german = buildTextFormat("german", "de");
Format german = Format.createTextContainerFormat("german", null, Format undeterminedUnd = buildTextFormat("undeterminedUnd", "und");
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "de"); Format undeterminedNull = buildTextFormat("undeterminedNull", null);
Format undeterminedUnd = Format.createTextContainerFormat("undeterminedUnd", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "und");
Format undeterminedNull = Format.createTextContainerFormat("undeterminedNull", null,
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, null);
RendererCapabilities[] textRendererCapabilites = RendererCapabilities[] textRendererCapabilites =
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES}; new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES};
@ -1090,6 +1053,22 @@ public final class DefaultTrackSelectorTest {
return new TrackGroupArray(trackGroups); return new TrackGroupArray(trackGroups);
} }
private static Format buildTextFormat(String id, String language) {
return buildTextFormat(id, language, /* selectionFlags= */ 0);
}
private static Format buildTextFormat(String id, String language, int selectionFlags) {
return Format.createTextContainerFormat(
id,
/* label= */ null,
/* containerMimeType= */ null,
/* sampleMimeType= */ MimeTypes.TEXT_VTT,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
selectionFlags,
language);
}
/** /**
* A {@link RendererCapabilities} that advertises support for all formats of a given type using * A {@link RendererCapabilities} that advertises support for all formats of a given type using
* a provided support value. For any format that does not have the given track type, * a provided support value. For any format that does not have the given track type,

View File

@ -247,8 +247,8 @@ public class DashManifestParser extends DefaultHandler
int audioChannels = Format.NO_VALUE; int audioChannels = Format.NO_VALUE;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE); int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
String language = xpp.getAttributeValue(null, "lang"); String language = xpp.getAttributeValue(null, "lang");
String drmSchemeType = null;
String label = xpp.getAttributeValue(null, "label"); String label = xpp.getAttributeValue(null, "label");
String drmSchemeType = null;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>(); ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>(); ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
ArrayList<Descriptor> accessibilityDescriptors = new ArrayList<>(); ArrayList<Descriptor> accessibilityDescriptors = new ArrayList<>();
@ -284,9 +284,22 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "SupplementalProperty")) { } else if (XmlPullParserUtil.isStartTag(xpp, "SupplementalProperty")) {
supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty")); supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty"));
} else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) { } else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) {
RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs, RepresentationInfo representationInfo =
width, height, frameRate, audioChannels, audioSamplingRate, language, parseRepresentation(
selectionFlags, accessibilityDescriptors, segmentBase, label); xpp,
baseUrl,
label,
mimeType,
codecs,
width,
height,
frameRate,
audioChannels,
audioSamplingRate,
language,
selectionFlags,
accessibilityDescriptors,
segmentBase);
contentType = checkContentTypeConsistency(contentType, contentType = checkContentTypeConsistency(contentType,
getContentType(representationInfo.format)); getContentType(representationInfo.format));
representationInfos.add(representationInfo); representationInfos.add(representationInfo);
@ -453,12 +466,21 @@ public class DashManifestParser extends DefaultHandler
// Representation parsing. // Representation parsing.
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, protected RepresentationInfo parseRepresentation(
String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, XmlPullParser xpp,
int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, String baseUrl,
int adaptationSetAudioSamplingRate, String adaptationSetLanguage, String label,
String adaptationSetMimeType,
String adaptationSetCodecs,
int adaptationSetWidth,
int adaptationSetHeight,
float adaptationSetFrameRate,
int adaptationSetAudioChannels,
int adaptationSetAudioSamplingRate,
String adaptationSetLanguage,
@C.SelectionFlags int adaptationSetSelectionFlags, @C.SelectionFlags int adaptationSetSelectionFlags,
List<Descriptor> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase, String label) List<Descriptor> adaptationSetAccessibilityDescriptors,
SegmentBase segmentBase)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id"); String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE); int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
@ -506,30 +528,74 @@ public class DashManifestParser extends DefaultHandler
} }
} while (!XmlPullParserUtil.isEndTag(xpp, "Representation")); } while (!XmlPullParserUtil.isEndTag(xpp, "Representation"));
Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, Format format =
audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, buildFormat(
adaptationSetAccessibilityDescriptors, codecs, supplementalProperties, label); id,
label,
mimeType,
width,
height,
frameRate,
audioChannels,
audioSamplingRate,
bandwidth,
adaptationSetLanguage,
adaptationSetSelectionFlags,
adaptationSetAccessibilityDescriptors,
codecs,
supplementalProperties);
segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase(); segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase();
return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeType, drmSchemeDatas, return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeType, drmSchemeDatas,
inbandEventStreams, Representation.REVISION_ID_DEFAULT); inbandEventStreams, Representation.REVISION_ID_DEFAULT);
} }
protected Format buildFormat(String id, String containerMimeType, int width, int height, protected Format buildFormat(
float frameRate, int audioChannels, int audioSamplingRate, int bitrate, String language, String id,
@C.SelectionFlags int selectionFlags, List<Descriptor> accessibilityDescriptors, String label,
String codecs, List<Descriptor> supplementalProperties, String label) { String containerMimeType,
int width,
int height,
float frameRate,
int audioChannels,
int audioSamplingRate,
int bitrate,
String language,
@C.SelectionFlags int selectionFlags,
List<Descriptor> accessibilityDescriptors,
String codecs,
List<Descriptor> supplementalProperties) {
String sampleMimeType = getSampleMimeType(containerMimeType, codecs); String sampleMimeType = getSampleMimeType(containerMimeType, codecs);
if (sampleMimeType != null) { if (sampleMimeType != null) {
if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) { if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) {
sampleMimeType = parseEac3SupplementalProperties(supplementalProperties); sampleMimeType = parseEac3SupplementalProperties(supplementalProperties);
} }
if (MimeTypes.isVideo(sampleMimeType)) { if (MimeTypes.isVideo(sampleMimeType)) {
return Format.createVideoContainerFormat(id, containerMimeType, sampleMimeType, codecs, return Format.createVideoContainerFormat(
bitrate, width, height, frameRate, null, selectionFlags); id,
label,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
width,
height,
frameRate,
/* initializationData= */ null,
selectionFlags);
} else if (MimeTypes.isAudio(sampleMimeType)) { } else if (MimeTypes.isAudio(sampleMimeType)) {
return Format.createAudioContainerFormat(id, containerMimeType, sampleMimeType, codecs, return Format.createAudioContainerFormat(
bitrate, audioChannels, audioSamplingRate, null, selectionFlags, language, label); id,
label,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
audioChannels,
audioSamplingRate,
/* initializationData= */ null,
selectionFlags,
language);
} else if (mimeTypeIsRawText(sampleMimeType)) { } else if (mimeTypeIsRawText(sampleMimeType)) {
int accessibilityChannel; int accessibilityChannel;
if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) { if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) {
@ -539,12 +605,20 @@ public class DashManifestParser extends DefaultHandler
} else { } else {
accessibilityChannel = Format.NO_VALUE; accessibilityChannel = Format.NO_VALUE;
} }
return Format.createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs, return Format.createTextContainerFormat(
bitrate, selectionFlags, language, accessibilityChannel, label); id,
label,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
selectionFlags,
language,
accessibilityChannel);
} }
} }
return Format.createContainerFormat(id, containerMimeType, sampleMimeType, codecs, bitrate, return Format.createContainerFormat(
selectionFlags, language); id, label, containerMimeType, sampleMimeType, codecs, bitrate, selectionFlags, language);
} }
protected Representation buildRepresentation(RepresentationInfo representationInfo, protected Representation buildRepresentation(RepresentationInfo representationInfo,

View File

@ -76,15 +76,16 @@ public final class DashUtilTest {
Format format = Format format =
Format.createVideoContainerFormat( Format.createVideoContainerFormat(
"id", "id",
"label",
MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_MP4,
MimeTypes.VIDEO_H264, MimeTypes.VIDEO_H264,
"", /* codecs= */ "",
Format.NO_VALUE, Format.NO_VALUE,
1024, /* width= */ 1024,
768, /* height= */ 768,
Format.NO_VALUE, Format.NO_VALUE,
null, /* initializationData= */ null,
0); /* selectionFlags= */ 0);
if (drmInitData != null) { if (drmInitData != null) {
format = format.copyWithDrmInitData(drmInitData); format = format.copyWithDrmInitData(drmInitData);
} }

View File

@ -32,37 +32,30 @@ public class RepresentationTest {
public void testGetCacheKey() { public void testGetCacheKey() {
String uri = "http://www.google.com"; String uri = "http://www.google.com";
SegmentBase base = new SingleSegmentBase(new RangedUri(null, 0, 1), 1, 0, 1, 1); SegmentBase base = new SingleSegmentBase(new RangedUri(null, 0, 1), 1, 0, 1, 1);
Format format = Format format = createVideoContainerFormat("0");
Format.createVideoContainerFormat(
"0",
MimeTypes.APPLICATION_MP4,
null,
MimeTypes.VIDEO_H264,
2500000,
1920,
1080,
Format.NO_VALUE,
null,
0);
Representation representation = Representation representation =
Representation.newInstance("test_stream_1", 3, format, uri, base); Representation.newInstance("test_stream_1", 3, format, uri, base);
assertThat(representation.getCacheKey()).isEqualTo("test_stream_1.0.3"); assertThat(representation.getCacheKey()).isEqualTo("test_stream_1.0.3");
format = format = createVideoContainerFormat("150");
Format.createVideoContainerFormat(
"150",
MimeTypes.APPLICATION_MP4,
null,
MimeTypes.VIDEO_H264,
2500000,
1920,
1080,
Format.NO_VALUE,
null,
0);
representation = representation =
Representation.newInstance( Representation.newInstance(
"test_stream_1", Representation.REVISION_ID_DEFAULT, format, uri, base); "test_stream_1", Representation.REVISION_ID_DEFAULT, format, uri, base);
assertThat(representation.getCacheKey()).isEqualTo("test_stream_1.150.-1"); assertThat(representation.getCacheKey()).isEqualTo("test_stream_1.150.-1");
} }
private static Format createVideoContainerFormat(String id) {
return Format.createVideoContainerFormat(
id,
"label",
/* containerMimeType= */ MimeTypes.APPLICATION_MP4,
/* sampleMimeType= */ MimeTypes.VIDEO_H264,
/* codecs= */ null,
/* bitrate= */ 2500000,
/* width= */ 1920,
/* height= */ 1080,
/* frameRate= */ Format.NO_VALUE,
/* initializationData= */ null,
/* selectionFlags= */ 0);
}
} }

View File

@ -50,8 +50,16 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
* @return An HLS url. * @return An HLS url.
*/ */
public static HlsUrl createMediaPlaylistHlsUrl(String url) { public static HlsUrl createMediaPlaylistHlsUrl(String url) {
Format format = Format.createContainerFormat("0", MimeTypes.APPLICATION_M3U8, null, null, Format format =
Format.NO_VALUE, 0, null); Format.createContainerFormat(
"0",
/* label= */ null,
MimeTypes.APPLICATION_M3U8,
/* sampleMimeType= */ null,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
/* selectionFlags= */ 0,
/* language= */ null);
return new HlsUrl(url, format); return new HlsUrl(url, format);
} }

View File

@ -274,8 +274,19 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
} }
line = iterator.next(); // #EXT-X-STREAM-INF's URI. line = iterator.next(); // #EXT-X-STREAM-INF's URI.
if (variantUrls.add(line)) { if (variantUrls.add(line)) {
Format format = Format.createVideoContainerFormat(Integer.toString(variants.size()), Format format =
MimeTypes.APPLICATION_M3U8, null, codecs, bitrate, width, height, frameRate, null, 0); Format.createVideoContainerFormat(
/* id= */ Integer.toString(variants.size()),
/* label= */ null,
/* containerMimeType= */ MimeTypes.APPLICATION_M3U8,
/* sampleMimeType= */ null,
codecs,
bitrate,
width,
height,
frameRate,
/* initializationData= */ null,
/* selectionFlags= */ 0);
variants.add(new HlsMasterPlaylist.HlsUrl(line, format)); variants.add(new HlsMasterPlaylist.HlsUrl(line, format));
} }
} }
@ -285,7 +296,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
line = mediaTags.get(i); line = mediaTags.get(i);
@C.SelectionFlags int selectionFlags = parseSelectionFlags(line); @C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
String uri = parseOptionalStringAttr(line, REGEX_URI); String uri = parseOptionalStringAttr(line, REGEX_URI);
String id = parseStringAttr(line, REGEX_NAME); String name = parseStringAttr(line, REGEX_NAME);
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE); String language = parseOptionalStringAttr(line, REGEX_LANGUAGE);
String groupId = parseOptionalStringAttr(line, REGEX_GROUP_ID); String groupId = parseOptionalStringAttr(line, REGEX_GROUP_ID);
Format format; Format format;
@ -293,9 +304,19 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
case TYPE_AUDIO: case TYPE_AUDIO:
String codecs = audioGroupIdToCodecs.get(groupId); String codecs = audioGroupIdToCodecs.get(groupId);
String sampleMimeType = codecs != null ? MimeTypes.getMediaMimeType(codecs) : null; String sampleMimeType = codecs != null ? MimeTypes.getMediaMimeType(codecs) : null;
format = Format.createAudioContainerFormat(id, MimeTypes.APPLICATION_M3U8, sampleMimeType, format =
codecs, Format.NO_VALUE, Format.NO_VALUE, Format.NO_VALUE, null, selectionFlags, Format.createAudioContainerFormat(
language, id); /* id= */ name,
/* label= */ name,
/* containerMimeType= */ MimeTypes.APPLICATION_M3U8,
sampleMimeType,
codecs,
/* bitrate= */ Format.NO_VALUE,
/* channelCount= */ Format.NO_VALUE,
/* sampleRate= */ Format.NO_VALUE,
/* initializationData= */ null,
selectionFlags,
language);
if (uri == null) { if (uri == null) {
muxedAudioFormat = format; muxedAudioFormat = format;
} else { } else {
@ -303,8 +324,16 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
} }
break; break;
case TYPE_SUBTITLES: case TYPE_SUBTITLES:
format = Format.createTextContainerFormat(id, MimeTypes.APPLICATION_M3U8, format =
MimeTypes.TEXT_VTT, null, Format.NO_VALUE, selectionFlags, language, id); Format.createTextContainerFormat(
/* id= */ name,
/* label= */ name,
/* containerMimeType= */ MimeTypes.APPLICATION_M3U8,
/* sampleMimeType= */ MimeTypes.TEXT_VTT,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
selectionFlags,
language);
subtitles.add(new HlsMasterPlaylist.HlsUrl(uri, format)); subtitles.add(new HlsMasterPlaylist.HlsUrl(uri, format));
break; break;
case TYPE_CLOSED_CAPTIONS: case TYPE_CLOSED_CAPTIONS:
@ -321,8 +350,17 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
if (muxedCaptionFormats == null) { if (muxedCaptionFormats == null) {
muxedCaptionFormats = new ArrayList<>(); muxedCaptionFormats = new ArrayList<>();
} }
muxedCaptionFormats.add(Format.createTextContainerFormat(id, null, mimeType, null, muxedCaptionFormats.add(
Format.NO_VALUE, selectionFlags, language, accessibilityChannel, id)); Format.createTextContainerFormat(
/* id= */ name,
/* label= */ name,
/* containerMimeType= */ null,
/* sampleMimeType= */ mimeType,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
selectionFlags,
language,
accessibilityChannel));
break; break;
default: default:
// Do nothing. // Do nothing.

View File

@ -617,6 +617,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
public void parseStartTag(XmlPullParser parser) throws ParserException { public void parseStartTag(XmlPullParser parser) throws ParserException {
int type = (Integer) getNormalizedAttribute(KEY_TYPE); int type = (Integer) getNormalizedAttribute(KEY_TYPE);
String id = parser.getAttributeValue(null, KEY_INDEX); String id = parser.getAttributeValue(null, KEY_INDEX);
String name = (String) getNormalizedAttribute(KEY_NAME);
int bitrate = parseRequiredInt(parser, KEY_BITRATE); int bitrate = parseRequiredInt(parser, KEY_BITRATE);
String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC)); String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
@ -625,8 +626,19 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
int height = parseRequiredInt(parser, KEY_MAX_HEIGHT); int height = parseRequiredInt(parser, KEY_MAX_HEIGHT);
List<byte[]> codecSpecificData = buildCodecSpecificData( List<byte[]> codecSpecificData = buildCodecSpecificData(
parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA)); parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA));
format = Format.createVideoContainerFormat(id, MimeTypes.VIDEO_MP4, sampleMimeType, null, format =
bitrate, width, height, Format.NO_VALUE, codecSpecificData, 0); Format.createVideoContainerFormat(
id,
name,
MimeTypes.VIDEO_MP4,
sampleMimeType,
/* codecs= */ null,
bitrate,
width,
height,
/* frameRate= */ Format.NO_VALUE,
codecSpecificData,
/* selectionFlags= */ 0);
} else if (type == C.TRACK_TYPE_AUDIO) { } else if (type == C.TRACK_TYPE_AUDIO) {
sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType; sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType;
int channels = parseRequiredInt(parser, KEY_CHANNELS); int channels = parseRequiredInt(parser, KEY_CHANNELS);
@ -638,17 +650,42 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(samplingRate, channels)); CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(samplingRate, channels));
} }
String language = (String) getNormalizedAttribute(KEY_LANGUAGE); String language = (String) getNormalizedAttribute(KEY_LANGUAGE);
String label = (String) getNormalizedAttribute(KEY_NAME); format =
format = Format.createAudioContainerFormat(id, MimeTypes.AUDIO_MP4, sampleMimeType, null, Format.createAudioContainerFormat(
bitrate, channels, samplingRate, codecSpecificData, 0, language, label); id,
name,
MimeTypes.AUDIO_MP4,
sampleMimeType,
/* codecs= */ null,
bitrate,
channels,
samplingRate,
codecSpecificData,
/* selectionFlags= */ 0,
language);
} else if (type == C.TRACK_TYPE_TEXT) { } else if (type == C.TRACK_TYPE_TEXT) {
String language = (String) getNormalizedAttribute(KEY_LANGUAGE); String language = (String) getNormalizedAttribute(KEY_LANGUAGE);
String label = (String) getNormalizedAttribute(KEY_NAME); format =
format = Format.createTextContainerFormat(id, MimeTypes.APPLICATION_MP4, sampleMimeType, Format.createTextContainerFormat(
null, bitrate, 0, language, label); id,
name,
MimeTypes.APPLICATION_MP4,
sampleMimeType,
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
language);
} else { } else {
format = Format.createContainerFormat(id, MimeTypes.APPLICATION_MP4, sampleMimeType, null, format =
bitrate, 0, null); Format.createContainerFormat(
id,
name,
MimeTypes.APPLICATION_MP4,
sampleMimeType,
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
/* language= */ null);
} }
} }

View File

@ -135,6 +135,13 @@ public class SsManifestTest {
private static Format newFormat(String id) { private static Format newFormat(String id) {
return Format.createContainerFormat( return Format.createContainerFormat(
id, MimeTypes.VIDEO_MP4, MimeTypes.VIDEO_H264, null, Format.NO_VALUE, 0, null); id,
/* label= */ null,
MimeTypes.VIDEO_MP4,
MimeTypes.VIDEO_H264,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
/* selectionFlags= */ 0,
/* language= */ null);
} }
} }

View File

@ -88,9 +88,6 @@ public class DefaultTrackNameProvider implements TrackNameProvider {
} }
private String buildLanguageString(Format format) { private String buildLanguageString(Format format) {
if ( !TextUtils.isEmpty(format.label) ){
return format.label;
}
String language = format.language; String language = format.language;
return TextUtils.isEmpty(language) || C.LANGUAGE_UNDETERMINED.equals(language) return TextUtils.isEmpty(language) || C.LANGUAGE_UNDETERMINED.equals(language)
? "" ? ""