From 170fc852cab1ec5460914dcb564c465a4592935d Mon Sep 17 00:00:00 2001 From: Nicola Verbeeck Date: Fri, 6 Mar 2020 12:24:04 +0100 Subject: [PATCH] DASH: Include AssetIdentifier in period DASH: Parse AssetIdentifier in period Breaking: DashManifestParser.buildPeriod signature has changed --- .../dash/manifest/DashManifestParser.java | 13 ++++++---- .../source/dash/manifest/Period.java | 20 +++++++++++++++- .../dash/manifest/DashManifestParserTest.java | 22 +++++++++++++++++ .../assets/mpd/sample_mpd_asset_identifier | 24 +++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 testdata/src/test/assets/mpd/sample_mpd_asset_identifier diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java index 85470b07b5..7fd1a0f889 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParser.java @@ -226,6 +226,7 @@ public class DashManifestParser extends DefaultHandler long startMs = parseDuration(xpp, "start", defaultStartMs); long durationMs = parseDuration(xpp, "duration", C.TIME_UNSET); SegmentBase segmentBase = null; + Descriptor assetIdentifier = null; List adaptationSets = new ArrayList<>(); List eventStreams = new ArrayList<>(); boolean seenFirstBaseUrl = false; @@ -246,17 +247,21 @@ public class DashManifestParser extends DefaultHandler segmentBase = parseSegmentList(xpp, null, durationMs); } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) { segmentBase = parseSegmentTemplate(xpp, null, Collections.emptyList(), durationMs); + } else if (XmlPullParserUtil.isStartTag(xpp, "AssetIdentifier")) { + assetIdentifier = parseDescriptor(xpp, "AssetIdentifier"); } else { maybeSkipTag(xpp); } } while (!XmlPullParserUtil.isEndTag(xpp, "Period")); - return Pair.create(buildPeriod(id, startMs, adaptationSets, eventStreams), durationMs); + return Pair.create(buildPeriod(id, startMs, adaptationSets, eventStreams, assetIdentifier), + durationMs); } - protected Period buildPeriod(String id, long startMs, List adaptationSets, - List eventStreams) { - return new Period(id, startMs, adaptationSets, eventStreams); + protected Period buildPeriod(@Nullable String id, long startMs, + List adaptationSets, List eventStreams, + @Nullable Descriptor assetIdentifier) { + return new Period(id, startMs, adaptationSets, eventStreams, assetIdentifier); } // AdaptationSet parsing. diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Period.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Period.java index 18614ca4b0..2fbf4e029e 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Period.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/Period.java @@ -45,13 +45,18 @@ public class Period { */ public final List eventStreams; + /** + * The asset identifier for this period, if one exists + */ + @Nullable public final Descriptor assetIdentifier; + /** * @param id The period identifier. May be null. * @param startMs The start time of the period in milliseconds. * @param adaptationSets The adaptation sets belonging to the period. */ public Period(@Nullable String id, long startMs, List adaptationSets) { - this(id, startMs, adaptationSets, Collections.emptyList()); + this(id, startMs, adaptationSets, Collections.emptyList(), null); } /** @@ -62,10 +67,23 @@ public class Period { */ public Period(@Nullable String id, long startMs, List adaptationSets, List eventStreams) { + this(id, startMs, adaptationSets, eventStreams, null); + } + + /** + * @param id The period identifier. May be null. + * @param startMs The start time of the period in milliseconds. + * @param adaptationSets The adaptation sets belonging to the period. + * @param eventStreams The {@link EventStream}s belonging to the period. + * @param assetIdentifier The asset identifier for this period + */ + public Period(@Nullable String id, long startMs, List adaptationSets, + List eventStreams, @Nullable Descriptor assetIdentifier) { this.id = id; this.startMs = startMs; this.adaptationSets = Collections.unmodifiableList(adaptationSets); this.eventStreams = Collections.unmodifiableList(eventStreams); + this.assetIdentifier = assetIdentifier; } /** diff --git a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java index e7963c5c48..84e4b1be32 100644 --- a/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java +++ b/library/dash/src/test/java/com/google/android/exoplayer2/source/dash/manifest/DashManifestParserTest.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.dash.manifest; import static com.google.common.truth.Truth.assertThat; import android.net.Uri; +import androidx.annotation.Nullable; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; @@ -45,6 +46,7 @@ public class DashManifestParserTest { private static final String SAMPLE_MPD_SEGMENT_TEMPLATE = "mpd/sample_mpd_segment_template"; private static final String SAMPLE_MPD_EVENT_STREAM = "mpd/sample_mpd_event_stream"; private static final String SAMPLE_MPD_LABELS = "mpd/sample_mpd_labels"; + private static final String SAMPLE_ASSET_IDENTIFIER = "mpd/sample_mpd_asset_identifier"; private static final String NEXT_TAG_NAME = "Next"; private static final String NEXT_TAG = "<" + NEXT_TAG_NAME + "/>"; @@ -377,6 +379,26 @@ public class DashManifestParserTest { .isEqualTo(Format.NO_VALUE); } + @Test + public void parsePeriodAssetIdentifier() throws IOException { + DashManifestParser parser = new DashManifestParser(); + DashManifest mpd = parser.parse( + Uri.parse("https://example.com/test.mpd"), + TestUtil + .getInputStream(ApplicationProvider.getApplicationContext(), SAMPLE_ASSET_IDENTIFIER)); + + assertThat(mpd.getPeriodCount()).isEqualTo(1); + + Period period = mpd.getPeriod(0); + assertThat(period).isNotNull(); + @Nullable Descriptor assetIdentifier = period.assetIdentifier; + assertThat(assetIdentifier).isNotNull(); + + assertThat(assetIdentifier.schemeIdUri).isEqualTo("urn:org:dashif:asset-id:2013"); + assertThat(assetIdentifier.value).isEqualTo("md:cid:EIDR:10.5240%2f0EFB-02CD-126E-8092-1E49-W"); + assertThat(assetIdentifier.id).isEqualTo("uniqueId"); + } + private static List buildCea608AccessibilityDescriptors(String value) { return Collections.singletonList(new Descriptor("urn:scte:dash:cc:cea-608:2015", value, null)); } diff --git a/testdata/src/test/assets/mpd/sample_mpd_asset_identifier b/testdata/src/test/assets/mpd/sample_mpd_asset_identifier new file mode 100644 index 0000000000..ff5bc874b9 --- /dev/null +++ b/testdata/src/test/assets/mpd/sample_mpd_asset_identifier @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + http://www.dummy.url/ + + + + + + http://www.dummy.url/ + + + +