diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java index 1fdb137be9..6446909808 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/DashManifest.java @@ -86,12 +86,17 @@ public class DashManifest implements FilterableManifest { */ public final Uri location; + /** + * The ProgramInformation of this manifest. + */ + public final ProgramInformation programInformation; + private final List periods; public DashManifest(long availabilityStartTimeMs, long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdatePeriodMs, long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs, UtcTimingElement utcTiming, - Uri location, List periods) { + Uri location, ProgramInformation programInformation, List periods) { this.availabilityStartTimeMs = availabilityStartTimeMs; this.durationMs = durationMs; this.minBufferTimeMs = minBufferTimeMs; @@ -102,6 +107,7 @@ public class DashManifest implements FilterableManifest { this.publishTimeMs = publishTimeMs; this.utcTiming = utcTiming; this.location = location; + this.programInformation = programInformation; this.periods = periods == null ? Collections.emptyList() : periods; } @@ -150,7 +156,7 @@ public class DashManifest implements FilterableManifest { long newDuration = durationMs != C.TIME_UNSET ? durationMs - shiftMs : C.TIME_UNSET; return new DashManifest(availabilityStartTimeMs, newDuration, minBufferTimeMs, dynamic, minUpdatePeriodMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, publishTimeMs, - utcTiming, location, copyPeriods); + utcTiming, location, programInformation, copyPeriods); } private static ArrayList copyAdaptationSets( 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 31ff7d283e..d048e22b33 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 @@ -122,6 +122,7 @@ public class DashManifestParser extends DefaultHandler long publishTimeMs = parseDateTime(xpp, "publishTime", C.TIME_UNSET); UtcTimingElement utcTiming = null; Uri location = null; + ProgramInformation programInformation = null; List periods = new ArrayList<>(); long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0; @@ -138,6 +139,8 @@ public class DashManifestParser extends DefaultHandler utcTiming = parseUtcTiming(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { location = Uri.parse(xpp.nextText()); + } else if (XmlPullParserUtil.isStartTag(xpp, "ProgramInformation")) { + programInformation = parseProgramInformation(xpp); } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { Pair periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Period period = periodWithDurationMs.first; @@ -175,16 +178,16 @@ public class DashManifestParser extends DefaultHandler return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, - publishTimeMs, utcTiming, location, periods); + publishTimeMs, utcTiming, location, programInformation, periods); } protected DashManifest buildMediaPresentationDescription(long availabilityStartTime, long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs, long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs, - UtcTimingElement utcTiming, Uri location, List periods) { + UtcTimingElement utcTiming, Uri location, ProgramInformation programInformation, List periods) { return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, - publishTimeMs, utcTiming, location, periods); + publishTimeMs, utcTiming, location, programInformation, periods); } protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) { @@ -998,6 +1001,27 @@ public class DashManifestParser extends DefaultHandler return new RangedUri(urlText, rangeStart, rangeLength); } + protected ProgramInformation parseProgramInformation(XmlPullParser xpp) throws IOException, XmlPullParserException { + String title = null; + String source = null; + String copyright = null; + String moreInformationURL = parseString(xpp, "moreInformationURL", null); + String lang = parseString(xpp, "lang", null); + do { + xpp.next(); + if (XmlPullParserUtil.isStartTag(xpp, "Title")) { + title = xpp.nextText(); + } else if (XmlPullParserUtil.isStartTag(xpp, "Source")) { + source = xpp.nextText(); + } else if (XmlPullParserUtil.isStartTag(xpp, "Copyright")) { + copyright = xpp.nextText(); + } else { + maybeSkipTag(xpp); + } + } while (!XmlPullParserUtil.isEndTag(xpp, "ProgramInformation")); + return new ProgramInformation(title, source, copyright, moreInformationURL, lang); + } + // AudioChannelConfiguration parsing. protected int parseAudioChannelConfiguration(XmlPullParser xpp) diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java new file mode 100644 index 0000000000..71b4af3a21 --- /dev/null +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/manifest/ProgramInformation.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.android.exoplayer2.source.dash.manifest; + +import com.google.android.exoplayer2.util.Util; + +/** + * A parsed ProgramInformation element. + */ +public class ProgramInformation { + /** + * The title for the media presentation. + */ + public final String title; + + /** + * Information about the original source of the media presentation. + */ + public final String source; + + /** + * A copyright statement for the media presentation. + */ + public final String copyright; + + /** + * A URL that provides more information about the media presentation. + */ + public final String moreInformationURL; + + /** + * Declares the language code(s) for this ProgramInformation. + */ + public final String lang; + + public ProgramInformation(String title, String source, String copyright, String moreInformationURL, String lang) { + this.title = title; + this.source = source; + this.copyright = copyright; + this.moreInformationURL = moreInformationURL; + this.lang = lang; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ProgramInformation)) { + return false; + } + ProgramInformation other = (ProgramInformation) obj; + return Util.areEqual(this.title, other.title) + && Util.areEqual(this.source, other.source) + && Util.areEqual(this.copyright, other.copyright) + && Util.areEqual(this.moreInformationURL, other.moreInformationURL) + && Util.areEqual(this.lang, other.lang); + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + (source != null ? source.hashCode() : 0); + result = 31 * result + (copyright != null ? copyright.hashCode() : 0); + result = 31 * result + (moreInformationURL != null ? moreInformationURL.hashCode() : 0); + result = 31 * result + (lang != null ? lang.hashCode() : 0); + return result; + } +} diff --git a/library/dash/src/test/assets/sample_mpd_1 b/library/dash/src/test/assets/sample_mpd_1 index 07bcdd4f50..ccd3ab4dd6 100644 --- a/library/dash/src/test/assets/sample_mpd_1 +++ b/library/dash/src/test/assets/sample_mpd_1 @@ -9,6 +9,12 @@ xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" yt:earliestMediaSequence="1266404" > + + MediaTitle + MediaSource + MediaCopyright +