diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2ebd6e27dd..1801e82250 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -38,6 +38,9 @@ ([#9370](https://github.com/google/ExoPlayer/issues/9370)). * Fix base URL selection and load error handling when base URLs are shared across adaptation sets. +* HLS + * Fix bug where the player would get stuck if all download attempts fail + and would not raise an error to the application. * RTSP: * Handle when additional spaces are in SDP's RTPMAP atrribute ([#9379](https://github.com/google/ExoPlayer/issues/9379)). diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 05f7a7f8cc..4abd6a0c56 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -555,6 +555,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; chunkSource.setIsTimestampMaster(isTimestampMaster); } + /** + * Called if an error is encountered while loading a playlist. + * + * @param playlistUrl The {@link Uri} of the playlist whose load encountered an error. + * @param loadErrorInfo The load error info. + * @param forceRetry Whether retry should be forced without considering exclusion. + * @return True if excluding did not encounter errors. False otherwise. + */ public boolean onPlaylistError(Uri playlistUrl, LoadErrorInfo loadErrorInfo, boolean forceRetry) { if (!chunkSource.obtainsChunksForPlaylist(playlistUrl)) { // Return early if the chunk source doesn't deliver chunks for the failing playlist. @@ -571,7 +579,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; exclusionDurationMs = fallbackSelection.exclusionDurationMs; } } - return chunkSource.onPlaylistError(playlistUrl, exclusionDurationMs); + // We must call ChunkSource.onPlaylistError in any case to give the chunk source the chance to + // mark the playlist as failing. + return chunkSource.onPlaylistError(playlistUrl, exclusionDurationMs) + && exclusionDurationMs != C.TIME_UNSET; } // SampleStream implementation.