Commit b88c88e2 by ojw28 Committed by Oliver Woodman

Merge pull request #4930 from Comcast/program_information

Add Support for Parsing ProgramInformation
parent 8200fe5a
...@@ -86,12 +86,17 @@ public class DashManifest implements FilterableManifest<DashManifest> { ...@@ -86,12 +86,17 @@ public class DashManifest implements FilterableManifest<DashManifest> {
*/ */
public final Uri location; public final Uri location;
/**
* The ProgramInformation of this manifest.
*/
public final ProgramInformation programInformation;
private final List<Period> periods; private final List<Period> periods;
public DashManifest(long availabilityStartTimeMs, long durationMs, long minBufferTimeMs, public DashManifest(long availabilityStartTimeMs, long durationMs, long minBufferTimeMs,
boolean dynamic, long minUpdatePeriodMs, long timeShiftBufferDepthMs, boolean dynamic, long minUpdatePeriodMs, long timeShiftBufferDepthMs,
long suggestedPresentationDelayMs, long publishTimeMs, UtcTimingElement utcTiming, long suggestedPresentationDelayMs, long publishTimeMs, UtcTimingElement utcTiming,
Uri location, List<Period> periods) { Uri location, ProgramInformation programInformation, List<Period> periods) {
this.availabilityStartTimeMs = availabilityStartTimeMs; this.availabilityStartTimeMs = availabilityStartTimeMs;
this.durationMs = durationMs; this.durationMs = durationMs;
this.minBufferTimeMs = minBufferTimeMs; this.minBufferTimeMs = minBufferTimeMs;
...@@ -102,6 +107,7 @@ public class DashManifest implements FilterableManifest<DashManifest> { ...@@ -102,6 +107,7 @@ public class DashManifest implements FilterableManifest<DashManifest> {
this.publishTimeMs = publishTimeMs; this.publishTimeMs = publishTimeMs;
this.utcTiming = utcTiming; this.utcTiming = utcTiming;
this.location = location; this.location = location;
this.programInformation = programInformation;
this.periods = periods == null ? Collections.emptyList() : periods; this.periods = periods == null ? Collections.emptyList() : periods;
} }
...@@ -150,7 +156,7 @@ public class DashManifest implements FilterableManifest<DashManifest> { ...@@ -150,7 +156,7 @@ public class DashManifest implements FilterableManifest<DashManifest> {
long newDuration = durationMs != C.TIME_UNSET ? durationMs - shiftMs : C.TIME_UNSET; long newDuration = durationMs != C.TIME_UNSET ? durationMs - shiftMs : C.TIME_UNSET;
return new DashManifest(availabilityStartTimeMs, newDuration, minBufferTimeMs, dynamic, return new DashManifest(availabilityStartTimeMs, newDuration, minBufferTimeMs, dynamic,
minUpdatePeriodMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, publishTimeMs, minUpdatePeriodMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, publishTimeMs,
utcTiming, location, copyPeriods); utcTiming, location, programInformation, copyPeriods);
} }
private static ArrayList<AdaptationSet> copyAdaptationSets( private static ArrayList<AdaptationSet> copyAdaptationSets(
......
...@@ -122,6 +122,7 @@ public class DashManifestParser extends DefaultHandler ...@@ -122,6 +122,7 @@ public class DashManifestParser extends DefaultHandler
long publishTimeMs = parseDateTime(xpp, "publishTime", C.TIME_UNSET); long publishTimeMs = parseDateTime(xpp, "publishTime", C.TIME_UNSET);
UtcTimingElement utcTiming = null; UtcTimingElement utcTiming = null;
Uri location = null; Uri location = null;
ProgramInformation programInformation = null;
List<Period> periods = new ArrayList<>(); List<Period> periods = new ArrayList<>();
long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0; long nextPeriodStartMs = dynamic ? C.TIME_UNSET : 0;
...@@ -138,6 +139,8 @@ public class DashManifestParser extends DefaultHandler ...@@ -138,6 +139,8 @@ public class DashManifestParser extends DefaultHandler
utcTiming = parseUtcTiming(xpp); utcTiming = parseUtcTiming(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) {
location = Uri.parse(xpp.nextText()); location = Uri.parse(xpp.nextText());
} else if (XmlPullParserUtil.isStartTag(xpp, "ProgramInformation")) {
programInformation = parseProgramInformation(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) {
Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs); Pair<Period, Long> periodWithDurationMs = parsePeriod(xpp, baseUrl, nextPeriodStartMs);
Period period = periodWithDurationMs.first; Period period = periodWithDurationMs.first;
...@@ -175,16 +178,16 @@ public class DashManifestParser extends DefaultHandler ...@@ -175,16 +178,16 @@ public class DashManifestParser extends DefaultHandler
return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs,
publishTimeMs, utcTiming, location, periods); publishTimeMs, utcTiming, location, programInformation, periods);
} }
protected DashManifest buildMediaPresentationDescription(long availabilityStartTime, protected DashManifest buildMediaPresentationDescription(long availabilityStartTime,
long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs, long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs,
long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs, long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, long publishTimeMs,
UtcTimingElement utcTiming, Uri location, List<Period> periods) { UtcTimingElement utcTiming, Uri location, ProgramInformation programInformation, List<Period> periods) {
return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs, return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs,
publishTimeMs, utcTiming, location, periods); publishTimeMs, utcTiming, location, programInformation, periods);
} }
protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) { protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
...@@ -998,6 +1001,27 @@ public class DashManifestParser extends DefaultHandler ...@@ -998,6 +1001,27 @@ public class DashManifestParser extends DefaultHandler
return new RangedUri(urlText, rangeStart, rangeLength); 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. // AudioChannelConfiguration parsing.
protected int parseAudioChannelConfiguration(XmlPullParser xpp) protected int parseAudioChannelConfiguration(XmlPullParser xpp)
......
/*
* 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;
}
}
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns="urn:mpeg:DASH:schema:MPD:2011"
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd"
yt:earliestMediaSequence="1266404" > yt:earliestMediaSequence="1266404" >
<ProgramInformation lang="enUs"
moreInformationURL="www.example.com">
<Title>MediaTitle</Title>
<Source>MediaSource</Source>
<Copyright>MediaCopyright</Copyright>
</ProgramInformation>
<Period start="PT6462826.784S" > <Period start="PT6462826.784S" >
<SegmentList <SegmentList
presentationTimeOffset="34740095" presentationTimeOffset="34740095"
......
...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.testutil.TestUtil; ...@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.junit.Test; import org.junit.Test;
...@@ -153,6 +154,16 @@ public class DashManifestParserTest { ...@@ -153,6 +154,16 @@ public class DashManifestParserTest {
} }
@Test @Test
public void testParseMediaPresentationDescriptionCanParseProgramInformation() throws IOException {
DashManifestParser parser = new DashManifestParser();
DashManifest mpd = parser.parse(Uri.parse("Https://example.com/test.mpd"),
TestUtil.getInputStream(RuntimeEnvironment.application, SAMPLE_MPD_1));
ProgramInformation programInformation = new ProgramInformation("MediaTitle", "MediaSource",
"MediaCopyright", "www.example.com", "enUs");
assertThat(programInformation).isEqualTo(mpd.programInformation);
}
@Test
public void testParseCea608AccessibilityChannel() { public void testParseCea608AccessibilityChannel() {
assertThat( assertThat(
DashManifestParser.parseCea608AccessibilityChannel( DashManifestParser.parseCea608AccessibilityChannel(
......
...@@ -219,7 +219,7 @@ public class DashManifestTest { ...@@ -219,7 +219,7 @@ public class DashManifestTest {
private static DashManifest newDashManifest(int duration, Period... periods) { private static DashManifest newDashManifest(int duration, Period... periods) {
return new DashManifest( return new DashManifest(
0, duration, 1, false, 2, 3, 4, 12345, DUMMY_UTC_TIMING, Uri.EMPTY, Arrays.asList(periods)); 0, duration, 1, false, 2, 3, 4, 12345, DUMMY_UTC_TIMING, Uri.EMPTY, null, Arrays.asList(periods));
} }
private static Period newPeriod(String id, int startMs, AdaptationSet... adaptationSets) { private static Period newPeriod(String id, int startMs, AdaptationSet... adaptationSets) {
......
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