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
This commit is contained in:
aquilescanta 2017-05-09 03:14:58 -07:00 committed by Oliver Woodman
parent 1f43fb1998
commit 002dd72e70
3 changed files with 23 additions and 5 deletions

View File

@ -92,6 +92,7 @@ import java.util.Locale;
private boolean isTimestampMaster; private boolean isTimestampMaster;
private byte[] scratchSpace; private byte[] scratchSpace;
private IOException fatalError; private IOException fatalError;
private HlsUrl expectedPlaylistUrl;
private Uri encryptionKeyUri; private Uri encryptionKeyUri;
private byte[] encryptionKey; private byte[] encryptionKey;
@ -143,6 +144,9 @@ import java.util.Locale;
if (fatalError != null) { if (fatalError != null) {
throw fatalError; throw fatalError;
} }
if (expectedPlaylistUrl != null) {
playlistTracker.maybeThrowPlaylistRefreshError(expectedPlaylistUrl);
}
} }
/** /**
@ -195,6 +199,7 @@ import java.util.Locale;
public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChunkHolder out) { public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChunkHolder out) {
int oldVariantIndex = previous == null ? C.INDEX_UNSET int oldVariantIndex = previous == null ? C.INDEX_UNSET
: trackGroup.indexOf(previous.trackFormat); : trackGroup.indexOf(previous.trackFormat);
expectedPlaylistUrl = null;
// Use start time of the previous chunk rather than its end time because switching format will // Use start time of the previous chunk rather than its end time because switching format will
// require downloading overlapping segments. // require downloading overlapping segments.
long bufferedDurationUs = previous == null ? 0 long bufferedDurationUs = previous == null ? 0
@ -208,6 +213,7 @@ import java.util.Locale;
HlsUrl selectedUrl = variants[selectedVariantIndex]; HlsUrl selectedUrl = variants[selectedVariantIndex];
if (!playlistTracker.isSnapshotValid(selectedUrl)) { if (!playlistTracker.isSnapshotValid(selectedUrl)) {
out.playlist = selectedUrl; out.playlist = selectedUrl;
expectedPlaylistUrl = selectedUrl;
// Retry when playlist is refreshed. // Retry when playlist is refreshed.
return; return;
} }
@ -247,6 +253,7 @@ import java.util.Locale;
out.endOfStream = true; out.endOfStream = true;
} else /* Live */ { } else /* Live */ {
out.playlist = selectedUrl; out.playlist = selectedUrl;
expectedPlaylistUrl = selectedUrl;
} }
return; return;
} }

View File

@ -84,7 +84,7 @@ public final class HlsMediaSource implements MediaSource,
@Override @Override
public void maybeThrowSourceInfoRefreshError() throws IOException { public void maybeThrowSourceInfoRefreshError() throws IOException {
playlistTracker.maybeThrowPlaylistRefreshError(); playlistTracker.maybeThrowPrimaryPlaylistRefreshError();
} }
@Override @Override

View File

@ -200,18 +200,29 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
} }
/** /**
* If the tracker is having trouble refreshing the primary playlist or loading an irreplaceable * If the tracker is having trouble refreshing the master playlist or the primary playlist, this
* playlist, this method throws the underlying error. Otherwise, does nothing. * method throws the underlying error. Otherwise, does nothing.
* *
* @throws IOException The underlying error. * @throws IOException The underlying error.
*/ */
public void maybeThrowPlaylistRefreshError() throws IOException { public void maybeThrowPrimaryPlaylistRefreshError() throws IOException {
initialPlaylistLoader.maybeThrowError(); initialPlaylistLoader.maybeThrowError();
if (primaryHlsUrl != null) { 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. * Triggers a playlist refresh and whitelists it.
* *