From 70b628526a742a433fdf5d1fccbb9e1995e4297d Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Tue, 9 May 2017 03:14:58 -0700 Subject: [PATCH] Propagate playlist loading error if it prevents playback This imitates DashMediaSource's behavior. Issue:#2623 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=155485738 --- .../exoplayer2/source/hls/HlsChunkSource.java | 7 +++++++ .../exoplayer2/source/hls/HlsMediaSource.java | 2 +- .../hls/playlist/HlsPlaylistTracker.java | 19 +++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java index 49c4d04abc1..795e2f0eaa6 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java @@ -92,6 +92,7 @@ public void clear() { private boolean isTimestampMaster; private byte[] scratchSpace; private IOException fatalError; + private HlsUrl expectedPlaylistUrl; private Uri encryptionKeyUri; private byte[] encryptionKey; @@ -143,6 +144,9 @@ public void maybeThrowError() throws IOException { if (fatalError != null) { throw fatalError; } + if (expectedPlaylistUrl != null) { + playlistTracker.maybeThrowPlaylistRefreshError(expectedPlaylistUrl); + } } /** @@ -195,6 +199,7 @@ public void setIsTimestampMaster(boolean isTimestampMaster) { public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChunkHolder out) { int oldVariantIndex = previous == null ? C.INDEX_UNSET : trackGroup.indexOf(previous.trackFormat); + expectedPlaylistUrl = null; // Use start time of the previous chunk rather than its end time because switching format will // require downloading overlapping segments. long bufferedDurationUs = previous == null ? 0 @@ -208,6 +213,7 @@ public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChu HlsUrl selectedUrl = variants[selectedVariantIndex]; if (!playlistTracker.isSnapshotValid(selectedUrl)) { out.playlist = selectedUrl; + expectedPlaylistUrl = selectedUrl; // Retry when playlist is refreshed. return; } @@ -247,6 +253,7 @@ public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChu out.endOfStream = true; } else /* Live */ { out.playlist = selectedUrl; + expectedPlaylistUrl = selectedUrl; } return; } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index 3cd9f19522d..1bfb8371a07 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -84,7 +84,7 @@ public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener l @Override public void maybeThrowSourceInfoRefreshError() throws IOException { - playlistTracker.maybeThrowPlaylistRefreshError(); + playlistTracker.maybeThrowPrimaryPlaylistRefreshError(); } @Override diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java index 02a8e3f0983..62b77a0575b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java @@ -200,18 +200,29 @@ public void release() { } /** - * If the tracker is having trouble refreshing the primary playlist or loading an irreplaceable - * playlist, this method throws the underlying error. Otherwise, does nothing. + * If the tracker is having trouble refreshing the master playlist or the primary playlist, this + * method throws the underlying error. Otherwise, does nothing. * * @throws IOException The underlying error. */ - public void maybeThrowPlaylistRefreshError() throws IOException { + public void maybeThrowPrimaryPlaylistRefreshError() throws IOException { initialPlaylistLoader.maybeThrowError(); if (primaryHlsUrl != null) { - playlistBundles.get(primaryHlsUrl).mediaPlaylistLoader.maybeThrowError(); + maybeThrowPlaylistRefreshError(primaryHlsUrl); } } + /** + * If the playlist is having trouble loading the playlist referenced by the given {@link HlsUrl}, + * this method throws the underlying error. + * + * @param url The {@link HlsUrl}. + * @throws IOException The underyling error. + */ + public void maybeThrowPlaylistRefreshError(HlsUrl url) throws IOException { + playlistBundles.get(url).mediaPlaylistLoader.maybeThrowError(); + } + /** * Triggers a playlist refresh and whitelists it. *