From 164d8b4242903aea3b984fc72277366418279228 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 15 Jun 2015 17:38:51 +0100 Subject: [PATCH] Rework application of Mpd.Location + fix test. --- .../exoplayer/dash/DashChunkSource.java | 8 ++----- .../mpd/MediaPresentationDescription.java | 17 ++++++++++---- .../MediaPresentationDescriptionParser.java | 8 +++---- .../exoplayer/util/ManifestFetcher.java | 23 +++++++++++++++++++ .../exoplayer/dash/DashChunkSourceTest.java | 2 +- 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java index cea977ef6b..1eb32d4f89 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/DashChunkSource.java @@ -298,10 +298,6 @@ public class DashChunkSource implements ChunkSource { if (finishedCurrentManifest && (android.os.SystemClock.elapsedRealtime() > manifestFetcher.getManifestLoadTimestamp() + minUpdatePeriod)) { - String newManifestURL = currentManifest.location; - if (newManifestURL != null) { - manifestFetcher.updateManifestUrl(newManifestURL); - } manifestFetcher.requestRefresh(); } } @@ -592,8 +588,8 @@ public class DashChunkSource implements ChunkSource { Period period = new Period(null, firstRepresentation.periodStartMs, firstRepresentation.periodDurationMs, Collections.singletonList(adaptationSet)); long duration = firstRepresentation.periodDurationMs - firstRepresentation.periodStartMs; - return new MediaPresentationDescription(-1, duration, -1, false, -1, -1, null, - Collections.singletonList(period), null); + return new MediaPresentationDescription(-1, duration, -1, false, -1, -1, null, null, + Collections.singletonList(period)); } private static class RepresentationHolder { diff --git a/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescription.java b/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescription.java index 7004401798..c1eade3180 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescription.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescription.java @@ -15,13 +15,15 @@ */ package com.google.android.exoplayer.dash.mpd; +import com.google.android.exoplayer.util.ManifestFetcher.RedirectingManifest; + import java.util.Collections; import java.util.List; /** * Represents a DASH media presentation description (mpd). */ -public class MediaPresentationDescription { +public class MediaPresentationDescription implements RedirectingManifest { public final long availabilityStartTime; @@ -35,15 +37,15 @@ public class MediaPresentationDescription { public final long timeShiftBufferDepth; - public final List periods; - public final UtcTimingElement utcTiming; public final String location; + public final List periods; + public MediaPresentationDescription(long availabilityStartTime, long duration, long minBufferTime, boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth, UtcTimingElement utcTiming, - List periods, String location) { + String location, List periods) { this.availabilityStartTime = availabilityStartTime; this.duration = duration; this.minBufferTime = minBufferTime; @@ -51,8 +53,13 @@ public class MediaPresentationDescription { this.minUpdatePeriod = minUpdatePeriod; this.timeShiftBufferDepth = timeShiftBufferDepth; this.utcTiming = utcTiming; - this.periods = Collections.unmodifiableList(periods); this.location = location; + this.periods = Collections.unmodifiableList(periods); + } + + @Override + public String getNextManifestUrl() { + return location; } } diff --git a/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java b/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java index 614ec76063..71c6320e11 100644 --- a/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java +++ b/library/src/main/java/com/google/android/exoplayer/dash/mpd/MediaPresentationDescriptionParser.java @@ -123,20 +123,20 @@ public class MediaPresentationDescriptionParser extends DefaultHandler } else if (isStartTag(xpp, "Period")) { periods.add(parsePeriod(xpp, baseUrl, durationMs)); } else if (isStartTag(xpp, "Location")) { - location = xpp.nextText(); + location = xpp.nextText(); } } while (!isEndTag(xpp, "MPD")); return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, - dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, periods, location); + dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods); } protected MediaPresentationDescription buildMediaPresentationDescription( long availabilityStartTime, long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs, long timeShiftBufferDepthMs, UtcTimingElement utcTiming, - List periods, String location) { + String location, List periods) { return new MediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs, - dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, periods, location); + dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods); } protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) { diff --git a/library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java b/library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java index d441a1f6c6..74adfe0212 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java +++ b/library/src/main/java/com/google/android/exoplayer/util/ManifestFetcher.java @@ -23,6 +23,7 @@ import com.google.android.exoplayer.upstream.UriLoadable; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; +import android.text.TextUtils; import android.util.Pair; import java.io.IOException; @@ -83,6 +84,20 @@ public class ManifestFetcher implements Loader.Callback { } + /** + * Interface for manifests that are able to specify that subsequent loads should use a different + * URL. + */ + public interface RedirectingManifest { + + /** + * Returns the URL from which subsequent manifests should be requested, or null to continue + * using the current URL. + */ + public String getNextManifestUrl(); + + } + private final UriLoadable.Parser parser; private final UriDataSource uriDataSource; private final Handler eventHandler; @@ -237,6 +252,14 @@ public class ManifestFetcher implements Loader.Callback { loadExceptionCount = 0; loadException = null; + if (manifest instanceof RedirectingManifest) { + RedirectingManifest redirectingManifest = (RedirectingManifest) manifest; + String nextLocation = redirectingManifest.getNextManifestUrl(); + if (!TextUtils.isEmpty(nextLocation)) { + manifestUrl = nextLocation; + } + } + notifyManifestRefreshed(); } diff --git a/library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java b/library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java index 1cdfa1efed..53d5706070 100644 --- a/library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java +++ b/library/src/test/java/com/google/android/exoplayer/dash/DashChunkSourceTest.java @@ -248,7 +248,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase { long duration = (live) ? TrackRenderer.UNKNOWN_TIME_US : firstRepresentation.periodDurationMs - firstRepresentation.periodStartMs; return new MediaPresentationDescription(AVAILABILITY_START_TIME, duration, -1, live, -1, -1, - null, Collections.singletonList(period)); + null, null, Collections.singletonList(period)); } private static MediaPresentationDescription generateVodMpd() {