From a04663372fe6f3538fd27c322054769996bf84e4 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Tue, 4 Jul 2017 09:38:57 -0700 Subject: [PATCH] Detect playlist stuck and playlist reset conditions in HLS This CL aims that the player fails upon: - Playlist that don't change in a suspiciously long time, which might mean there are server side issues. - Playlist with a media sequence lower that its last snapshot and no overlapping segments. This two error conditions are propagated through the renderer, but not through MediaSource#maybeThrowSourceInfoRefreshError. Issue:#2872 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=160899995 --- .../hls/playlist/HlsPlaylistTracker.java | 82 ++++++++++++++++--- 1 file changed, 72 insertions(+), 10 deletions(-) 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 62b77a0575..567dbd4af6 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 @@ -40,6 +40,38 @@ import java.util.List; */ public final class HlsPlaylistTracker implements Loader.Callback> { + /** + * Thrown when a playlist is considered to be stuck due to a server side error. + */ + public static final class PlaylistStuckException extends IOException { + + /** + * The url of the stuck playlist. + */ + public final String url; + + private PlaylistStuckException(String url) { + this.url = url; + } + + } + + /** + * Thrown when the media sequence of a new snapshot indicates the server has reset. + */ + public static final class PlaylistResetException extends IOException { + + /** + * The url of the reset playlist. + */ + public final String url; + + private PlaylistResetException(String url) { + this.url = url; + } + + } + /** * Listener for primary playlist changes. */ @@ -75,6 +107,11 @@ public final class HlsPlaylistTracker implements Loader.Callback C.usToMs(playlistSnapshot.targetDurationUs) + * PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT) { + // The playlist seems to be stuck, we blacklist it. + playlistError = new PlaylistStuckException(playlistUrl.url); + blacklistPlaylist(); + } else if (loadedPlaylist.mediaSequence + loadedPlaylist.segments.size() + < playlistSnapshot.mediaSequence) { + // The media sequence has jumped backwards. The server has likely reset. + playlistError = new PlaylistResetException(playlistUrl.url); + } refreshDelayUs = playlistSnapshot.targetDurationUs / 2; } if (refreshDelayUs != C.TIME_UNSET) { @@ -554,6 +610,12 @@ public final class HlsPlaylistTracker implements Loader.Callback