Support relative MPD.Location URIs

#minor-release
Issue: google/ExoPlayer#9939
PiperOrigin-RevId: 426394339
This commit is contained in:
olly 2022-02-04 15:05:45 +00:00 committed by Ian Baker
parent 0c2e77daca
commit 13626a188c
5 changed files with 75 additions and 1 deletions

View File

@ -103,6 +103,8 @@
priority in manifests that do not declare the dvb namespace. This priority in manifests that do not declare the dvb namespace. This
prevents the exclusion logic to exclude base URL when they actually prevents the exclusion logic to exclude base URL when they actually
should be used as a fallback base URL. should be used as a fallback base URL.
* Support relative `MPD.Location` URLs
([#9939](https://github.com/google/ExoPlayer/issues/9939)).
* HLS: * HLS:
* Use chunkless preparation by default to improve start up time. If your * Use chunkless preparation by default to improve start up time. If your
renditions contain muxed closed-caption tracks that are *not* declared renditions contain muxed closed-caption tracks that are *not* declared

View File

@ -161,7 +161,7 @@ public class DashManifestParser extends DefaultHandler
} else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) { } else if (XmlPullParserUtil.isStartTag(xpp, "UTCTiming")) {
utcTiming = parseUtcTiming(xpp); utcTiming = parseUtcTiming(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Location")) { } else if (XmlPullParserUtil.isStartTag(xpp, "Location")) {
location = Uri.parse(xpp.nextText()); location = UriUtil.resolveToUri(documentBaseUri.toString(), xpp.nextText());
} else if (XmlPullParserUtil.isStartTag(xpp, "ServiceDescription")) { } else if (XmlPullParserUtil.isStartTag(xpp, "ServiceDescription")) {
serviceDescription = parseServiceDescription(xpp); serviceDescription = parseServiceDescription(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) { } else if (XmlPullParserUtil.isStartTag(xpp, "Period") && !seenEarlyAccessPeriod) {

View File

@ -46,6 +46,10 @@ import org.xmlpull.v1.XmlPullParserFactory;
public class DashManifestParserTest { public class DashManifestParserTest {
private static final String SAMPLE_MPD_LIVE = "media/mpd/sample_mpd_live"; private static final String SAMPLE_MPD_LIVE = "media/mpd/sample_mpd_live";
private static final String SAMPLE_MPD_LIVE_LOCATION_REDIRECT_RELATIVE =
"media/mpd/sample_mpd_live_location_redirect_relative";
private static final String SAMPLE_MPD_LIVE_LOCATION_REDIRECT_ABSOLUTE =
"media/mpd/sample_mpd_live_location_redirect_absolute";
private static final String SAMPLE_MPD_UNKNOWN_MIME_TYPE = private static final String SAMPLE_MPD_UNKNOWN_MIME_TYPE =
"media/mpd/sample_mpd_unknown_mime_type"; "media/mpd/sample_mpd_unknown_mime_type";
private static final String SAMPLE_MPD_SEGMENT_TEMPLATE = "media/mpd/sample_mpd_segment_template"; private static final String SAMPLE_MPD_SEGMENT_TEMPLATE = "media/mpd/sample_mpd_segment_template";
@ -201,6 +205,32 @@ public class DashManifestParserTest {
assertThat(manifest.programInformation).isEqualTo(expectedProgramInformation); assertThat(manifest.programInformation).isEqualTo(expectedProgramInformation);
} }
@Test
public void parseMediaPresentationDescription_locationRedirectRelative() throws IOException {
DashManifestParser parser = new DashManifestParser();
DashManifest manifest =
parser.parse(
Uri.parse("https://example.com/a/b/test.mpd"),
TestUtil.getInputStream(
ApplicationProvider.getApplicationContext(),
SAMPLE_MPD_LIVE_LOCATION_REDIRECT_RELATIVE));
Uri expectedLocation = Uri.parse("https://example.com/a/relative/redirect.mpd");
assertThat(manifest.location).isEqualTo(expectedLocation);
}
@Test
public void parseMediaPresentationDescription_locationRedirectAbsolute() throws IOException {
DashManifestParser parser = new DashManifestParser();
DashManifest manifest =
parser.parse(
Uri.parse("https://example.com/a/b/test.mpd"),
TestUtil.getInputStream(
ApplicationProvider.getApplicationContext(),
SAMPLE_MPD_LIVE_LOCATION_REDIRECT_ABSOLUTE));
Uri expectedLocation = Uri.parse("https://example2.com/absolute/redirect.mpd");
assertThat(manifest.location).isEqualTo(expectedLocation);
}
@Test @Test
public void parseMediaPresentationDescription_images() throws IOException { public void parseMediaPresentationDescription_images() throws IOException {
DashManifestParser parser = new DashManifestParser(); DashManifestParser parser = new DashManifestParser();

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<MPD
type="dynamic"
suggestedPresentationDelay="PT2S"
availabilityStartTime="2020-01-01T00:00:00Z"
minimumUpdatePeriod="PT4M"
timeShiftBufferDepth="PT8.0S">
<Location>https://example2.com/absolute/redirect.mpd</Location>
<Period start="PT0.0S">
<AdaptationSet contentType="video">
<Representation id="0" mimeType="video/mp4">
<SegmentTemplate
timescale="1000000"
duration="2000000"
availabilityTimeOffset="2"
startNumber="1">
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<MPD
type="dynamic"
suggestedPresentationDelay="PT2S"
availabilityStartTime="2020-01-01T00:00:00Z"
minimumUpdatePeriod="PT4M"
timeShiftBufferDepth="PT8.0S">
<Location>../relative/redirect.mpd</Location>
<Period start="PT0.0S">
<AdaptationSet contentType="video">
<Representation id="0" mimeType="video/mp4">
<SegmentTemplate
timescale="1000000"
duration="2000000"
availabilityTimeOffset="2"
startNumber="1">
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>