Commit b8f83ac1 by ibaker Committed by marcbaechinger

Parse DASH forced_subtitle role

#minor-release

Issue: #8781
PiperOrigin-RevId: 368212289
parent f93fb5dc
...@@ -90,6 +90,9 @@ ...@@ -90,6 +90,9 @@
* Metadata: * Metadata:
* Ensure that timed metadata near the end of a period is not dropped * Ensure that timed metadata near the end of a period is not dropped
([#8710](https://github.com/google/ExoPlayer/issues/8710)). ([#8710](https://github.com/google/ExoPlayer/issues/8710)).
* DASH:
* Parse `forced_subtitle` role from DASH manifests
([#8781](https://github.com/google/ExoPlayer/issues/8781)).
* MediaSession extension: Remove dependency to core module and rely on common * MediaSession extension: Remove dependency to core module and rely on common
only. The `TimelineQueueEditor` uses a new `MediaDescriptionConverter` for only. The `TimelineQueueEditor` uses a new `MediaDescriptionConverter` for
this purpose and does not rely on the `ConcatenatingMediaSource` anymore. this purpose and does not rely on the `ConcatenatingMediaSource` anymore.
......
...@@ -1391,15 +1391,31 @@ public class DashManifestParser extends DefaultHandler ...@@ -1391,15 +1391,31 @@ public class DashManifestParser extends DefaultHandler
// Selection flag parsing. // Selection flag parsing.
@C.SelectionFlags
protected int parseSelectionFlagsFromRoleDescriptors(List<Descriptor> roleDescriptors) { protected int parseSelectionFlagsFromRoleDescriptors(List<Descriptor> roleDescriptors) {
@C.SelectionFlags int result = 0;
for (int i = 0; i < roleDescriptors.size(); i++) { for (int i = 0; i < roleDescriptors.size(); i++) {
Descriptor descriptor = roleDescriptors.get(i); Descriptor descriptor = roleDescriptors.get(i);
if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri) if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri)) {
&& "main".equals(descriptor.value)) { result |= parseSelectionFlagsFromDashRoleScheme(descriptor.value);
return C.SELECTION_FLAG_DEFAULT;
} }
} }
return 0; return result;
}
@C.SelectionFlags
protected int parseSelectionFlagsFromDashRoleScheme(@Nullable String value) {
if (value == null) {
return 0;
}
switch (value) {
case "main":
return C.SELECTION_FLAG_DEFAULT;
case "forced_subtitle":
return C.SELECTION_FLAG_FORCED;
default:
return 0;
}
} }
// Role and Accessibility parsing. // Role and Accessibility parsing.
...@@ -1410,7 +1426,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -1410,7 +1426,7 @@ public class DashManifestParser extends DefaultHandler
for (int i = 0; i < roleDescriptors.size(); i++) { for (int i = 0; i < roleDescriptors.size(); i++) {
Descriptor descriptor = roleDescriptors.get(i); Descriptor descriptor = roleDescriptors.get(i);
if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri)) { if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri)) {
result |= parseDashRoleSchemeValue(descriptor.value); result |= parseRoleFlagsFromDashRoleScheme(descriptor.value);
} }
} }
return result; return result;
...@@ -1423,7 +1439,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -1423,7 +1439,7 @@ public class DashManifestParser extends DefaultHandler
for (int i = 0; i < accessibilityDescriptors.size(); i++) { for (int i = 0; i < accessibilityDescriptors.size(); i++) {
Descriptor descriptor = accessibilityDescriptors.get(i); Descriptor descriptor = accessibilityDescriptors.get(i);
if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri)) { if (Ascii.equalsIgnoreCase("urn:mpeg:dash:role:2011", descriptor.schemeIdUri)) {
result |= parseDashRoleSchemeValue(descriptor.value); result |= parseRoleFlagsFromDashRoleScheme(descriptor.value);
} else if (Ascii.equalsIgnoreCase( } else if (Ascii.equalsIgnoreCase(
"urn:tva:metadata:cs:AudioPurposeCS:2007", descriptor.schemeIdUri)) { "urn:tva:metadata:cs:AudioPurposeCS:2007", descriptor.schemeIdUri)) {
result |= parseTvaAudioPurposeCsValue(descriptor.value); result |= parseTvaAudioPurposeCsValue(descriptor.value);
...@@ -1446,7 +1462,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -1446,7 +1462,7 @@ public class DashManifestParser extends DefaultHandler
} }
@C.RoleFlags @C.RoleFlags
protected int parseDashRoleSchemeValue(@Nullable String value) { protected int parseRoleFlagsFromDashRoleScheme(@Nullable String value) {
if (value == null) { if (value == null) {
return 0; return 0;
} }
...@@ -1465,6 +1481,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -1465,6 +1481,7 @@ public class DashManifestParser extends DefaultHandler
return C.ROLE_FLAG_EMERGENCY; return C.ROLE_FLAG_EMERGENCY;
case "caption": case "caption":
return C.ROLE_FLAG_CAPTION; return C.ROLE_FLAG_CAPTION;
case "forced_subtitle":
case "subtitle": case "subtitle":
return C.ROLE_FLAG_SUBTITLE; return C.ROLE_FLAG_SUBTITLE;
case "sign": case "sign":
......
...@@ -220,18 +220,22 @@ public class DashManifestParserTest { ...@@ -220,18 +220,22 @@ public class DashManifestParserTest {
assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_RAWCC); assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_RAWCC);
assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_CEA608); assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_CEA608);
assertThat(format.codecs).isEqualTo("cea608"); assertThat(format.codecs).isEqualTo("cea608");
assertThat(format.roleFlags).isEqualTo(C.ROLE_FLAG_SUBTITLE);
assertThat(adaptationSets.get(0).type).isEqualTo(C.TRACK_TYPE_TEXT); assertThat(adaptationSets.get(0).type).isEqualTo(C.TRACK_TYPE_TEXT);
format = adaptationSets.get(1).representations.get(0).format; format = adaptationSets.get(1).representations.get(0).format;
assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_MP4); assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_MP4);
assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_TTML); assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_TTML);
assertThat(format.codecs).isEqualTo("stpp.ttml.im1t"); assertThat(format.codecs).isEqualTo("stpp.ttml.im1t");
assertThat(format.roleFlags).isEqualTo(C.ROLE_FLAG_SUBTITLE);
assertThat(format.selectionFlags).isEqualTo(C.SELECTION_FLAG_FORCED);
assertThat(adaptationSets.get(1).type).isEqualTo(C.TRACK_TYPE_TEXT); assertThat(adaptationSets.get(1).type).isEqualTo(C.TRACK_TYPE_TEXT);
format = adaptationSets.get(2).representations.get(0).format; format = adaptationSets.get(2).representations.get(0).format;
assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_TTML); assertThat(format.containerMimeType).isEqualTo(MimeTypes.APPLICATION_TTML);
assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_TTML); assertThat(format.sampleMimeType).isEqualTo(MimeTypes.APPLICATION_TTML);
assertThat(format.codecs).isNull(); assertThat(format.codecs).isNull();
assertThat(format.roleFlags).isEqualTo(0);
assertThat(adaptationSets.get(2).type).isEqualTo(C.TRACK_TYPE_TEXT); assertThat(adaptationSets.get(2).type).isEqualTo(C.TRACK_TYPE_TEXT);
} }
......
...@@ -7,11 +7,13 @@ ...@@ -7,11 +7,13 @@
</SegmentTimeline> </SegmentTimeline>
</SegmentTemplate> </SegmentTemplate>
<AdaptationSet id="0" mimeType="application/x-rawcc" subsegmentAlignment="true"> <AdaptationSet id="0" mimeType="application/x-rawcc" subsegmentAlignment="true">
<Role schemeIdUri="urn:mpeg:DASH:role:2011" value="subtitle"/>
<Representation id="0" codecs="cea608" bandwidth="16"> <Representation id="0" codecs="cea608" bandwidth="16">
<BaseURL>https://test.com/0</BaseURL> <BaseURL>https://test.com/0</BaseURL>
</Representation> </Representation>
</AdaptationSet> </AdaptationSet>
<AdaptationSet id="0" mimeType="application/mp4" subsegmentAlignment="true"> <AdaptationSet id="0" mimeType="application/mp4" subsegmentAlignment="true">
<Role schemeIdUri="urn:mpeg:DASH:role:2011" value="forced_subtitle"/>
<Representation id="0" codecs="stpp.ttml.im1t" bandwidth="16"> <Representation id="0" codecs="stpp.ttml.im1t" bandwidth="16">
<BaseURL>https://test.com/0</BaseURL> <BaseURL>https://test.com/0</BaseURL>
</Representation> </Representation>
......
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