From d289dc8a5331bfe941f61cbafa40c3d5328662b1 Mon Sep 17 00:00:00 2001 From: karyogamy Date: Sat, 26 Mar 2022 20:17:52 -0400 Subject: [PATCH] updated: onPlayerError to not catch unspecified source errors so notifications are created. updated: Throwable usage to Exceptions. updated: minor styles and documentations. --- .../org/schabi/newpipe/player/Player.java | 61 ++++++++++--------- .../player/mediaitem/ExceptionTag.java | 8 +-- .../player/mediaitem/MediaItemTag.java | 2 +- .../player/mediaitem/PlaceholderTag.java | 2 +- .../player/mediaitem/StreamInfoTag.java | 2 +- .../player/mediasource/FailedMediaSource.java | 6 +- .../player/playback/MediaSourceManager.java | 3 +- 7 files changed, 44 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/Player.java b/app/src/main/java/org/schabi/newpipe/player/Player.java index ea0cab5e6..ba4c4f237 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1961,13 +1961,12 @@ public final class Player implements final boolean showPrev = playQueue.getIndex() != 0; final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size(); final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected(); - boolean showSegment = false; - showSegment = /*only when stream has segment and playing in fullscreen player*/ - !popupPlayerSelected() - && !getCurrentStreamInfo() - .map(StreamInfo::getStreamSegments) - .map(List::isEmpty) - .orElse(/*no stream info=*/true); + /* only when stream has segments and is not playing in popup player */ + final boolean showSegment = !popupPlayerSelected() + && !getCurrentStreamInfo() + .map(StreamInfo::getStreamSegments) + .map(List::isEmpty) + .orElse(/*no stream info=*/true); binding.playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE); binding.playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f); @@ -2014,7 +2013,7 @@ public final class Player implements + "playWhenReady = [" + playWhenReady + "], " + "reason = [" + reason + "]"); } - final int playbackState = simpleExoPlayer == null + final int playbackState = exoPlayerIsNull() ? com.google.android.exoplayer2.Player.STATE_IDLE : simpleExoPlayer.getPlaybackState(); updatePlaybackState(playWhenReady, playbackState); @@ -2026,8 +2025,7 @@ public final class Player implements Log.d(TAG, "ExoPlayer - onPlaybackStateChanged() called with: " + "playbackState = [" + playbackState + "]"); } - final boolean playWhenReady = simpleExoPlayer != null && simpleExoPlayer.getPlayWhenReady(); - updatePlaybackState(playWhenReady, playbackState); + updatePlaybackState(getPlayWhenReady(), playbackState); } private void updatePlaybackState(final boolean playWhenReady, final int playbackState) { @@ -2486,6 +2484,19 @@ public final class Player implements //////////////////////////////////////////////////////////////////////////*/ //region ExoPlayer listeners (that didn't fit in other categories) + /** + *

Listens for event or state changes on ExoPlayer. When any event happens, we check for + * changes in the currently-playing metadata and update the encapsulating + * {@link Player}. Downstream listeners are also informed. + * + *

When the renewed metadata contains any error, it is reported as a notification. + * This is done because not all source resolution errors are {@link PlaybackException}, which + * are also captured by {@link ExoPlayer} and stops the playback. + * + * @param player The {@link com.google.android.exoplayer2.Player} whose state changed. + * @param events The {@link com.google.android.exoplayer2.Player.Events} that has triggered + * the player state changes. + **/ @Override public void onEvents(@NonNull final com.google.android.exoplayer2.Player player, @NonNull final com.google.android.exoplayer2.Player.Events events) { @@ -2602,11 +2613,12 @@ public final class Player implements *

  • {@link PlaybackException#ERROR_CODE_BEHIND_LIVE_WINDOW BEHIND_LIVE_WINDOW}: * If the playback on livestreams are lagged too far behind the current playable * window. Then we seek to the latest timestamp and restart the playback. + * This error is catchable. *
  • *
  • From {@link PlaybackException#ERROR_CODE_IO_INVALID_HTTP_CONTENT_TYPE BAD_IO} to * {@link PlaybackException#ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED UNSUPPORTED_FORMATS}: * If the stream source is validated by the extractor but not recognized by the player, - * then we can try to recover playback by signal an error on the {@link PlayQueue}.
  • + * then we can try to recover playback by signalling an error on the {@link PlayQueue}. *
  • For {@link PlaybackException#ERROR_CODE_TIMEOUT PLAYER_TIMEOUT}, * {@link PlaybackException#ERROR_CODE_IO_UNSPECIFIED MEDIA_SOURCE_RESOLVER_TIMEOUT} and * {@link PlaybackException#ERROR_CODE_IO_NETWORK_CONNECTION_FAILED NO_NETWORK}: @@ -2617,8 +2629,8 @@ public final class Player implements * We terminate the playback.
  • *
  • For any other unspecified issue internal: We set a recovery and try to restart * the playback.
  • - * In the case of decoder/renderer or unspecified errors, the player will create a - * notification so the users are aware. + * For any error above that is not explicitly catchable, the player will + * create a notification so users are aware. * * @see com.google.android.exoplayer2.Player.Listener#onPlayerError(PlaybackException) * */ @@ -2627,7 +2639,6 @@ public final class Player implements public void onPlayerError(@NonNull final PlaybackException error) { Log.e(TAG, "ExoPlayer - onPlayerError() called with:", error); - setRecovery(); saveStreamProgressState(); boolean isCatchableException = false; @@ -2652,7 +2663,6 @@ public final class Player implements case ERROR_CODE_PARSING_MANIFEST_UNSUPPORTED: // Source errors, signal on playQueue and move on: if (!exoPlayerIsNull() && playQueue != null) { - isCatchableException = true; playQueue.error(); } break; @@ -2660,11 +2670,6 @@ public final class Player implements case ERROR_CODE_IO_UNSPECIFIED: case ERROR_CODE_IO_NETWORK_CONNECTION_FAILED: case ERROR_CODE_IO_NETWORK_CONNECTION_TIMEOUT: - // Don't create notification on timeout/networking errors: - isCatchableException = true; - setRecovery(); - reloadPlayQueueManager(); - break; case ERROR_CODE_UNSPECIFIED: // Reload playback on unexpected errors: setRecovery(); @@ -3010,10 +3015,9 @@ public final class Player implements } public void saveStreamProgressStateCompleted() { - getCurrentStreamInfo().ifPresent(info -> { - // current stream has ended, so the progress is its duration (+1 to overcome rounding) - saveStreamProgressState((info.getDuration() + 1) * 1000); - }); + // current stream has ended, so the progress is its duration (+1 to overcome rounding) + getCurrentStreamInfo().ifPresent(info -> + saveStreamProgressState((info.getDuration() + 1) * 1000)); } //endregion @@ -3414,7 +3418,8 @@ public final class Player implements case VIDEO_STREAM: if (currentMetadata == null || !currentMetadata.getMaybeQuality().isPresent() - || info.getVideoStreams().size() + info.getVideoOnlyStreams().size() == 0) { + || (info.getVideoStreams().isEmpty() + && info.getVideoOnlyStreams().isEmpty())) { break; } @@ -3684,10 +3689,8 @@ public final class Player implements } // Normalize mismatching language strings - final List preferredLanguages = - trackSelector.getParameters().preferredTextLanguages; - final String preferredLanguage = - preferredLanguages.isEmpty() ? null : preferredLanguages.get(0); + final String preferredLanguage = trackSelector.getParameters() + .preferredTextLanguages.stream().findFirst().orElse(null); // Build UI buildCaptionMenu(availableLanguages); if (trackSelector.getParameters().getRendererDisabled(textRenderer) diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java index 7e28eda20..ebedf8c71 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/ExceptionTag.java @@ -24,12 +24,12 @@ public final class ExceptionTag implements MediaItemTag { @NonNull private final PlayQueueItem item; @NonNull - private final List errors; + private final List errors; @Nullable private final Object extras; private ExceptionTag(@NonNull final PlayQueueItem item, - @NonNull final List errors, + @NonNull final List errors, @Nullable final Object extras) { this.item = item; this.errors = errors; @@ -37,13 +37,13 @@ public final class ExceptionTag implements MediaItemTag { } public static ExceptionTag of(@NonNull final PlayQueueItem playQueueItem, - @NonNull final List errors) { + @NonNull final List errors) { return new ExceptionTag(playQueueItem, errors, null); } @NonNull @Override - public List getErrors() { + public List getErrors() { return errors; } diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java index 8dbd55280..f84b0383a 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/MediaItemTag.java @@ -26,7 +26,7 @@ import androidx.annotation.Nullable; **/ public interface MediaItemTag { - List getErrors(); + List getErrors(); int getServiceId(); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/PlaceholderTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/PlaceholderTag.java index fe7aa9d92..cce4e9f17 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/PlaceholderTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/PlaceholderTag.java @@ -29,7 +29,7 @@ public final class PlaceholderTag implements MediaItemTag { @NonNull @Override - public List getErrors() { + public List getErrors() { return Collections.emptyList(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java index 6a942840d..4095f2bc8 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediaitem/StreamInfoTag.java @@ -47,7 +47,7 @@ public final class StreamInfoTag implements MediaItemTag { } @Override - public List getErrors() { + public List getErrors() { return Collections.emptyList(); } diff --git a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java index 299ae845d..fa52ab0ee 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/mediasource/FailedMediaSource.java @@ -36,7 +36,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo private final String TAG = "FailedMediaSource@" + Integer.toHexString(hashCode()); private final PlayQueueItem playQueueItem; - private final Throwable error; + private final Exception error; private final long retryTimestamp; private final MediaItem mediaItem; /** @@ -51,7 +51,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo * @param retryTimestamp epoch timestamp when this MediaSource can be refreshed */ public FailedMediaSource(@NonNull final PlayQueueItem playQueueItem, - @NonNull final Throwable error, + @NonNull final Exception error, final long retryTimestamp) { this.playQueueItem = playQueueItem; this.error = error; @@ -68,7 +68,7 @@ public class FailedMediaSource extends BaseMediaSource implements ManagedMediaSo } public static FailedMediaSource of(@NonNull final PlayQueueItem playQueueItem, - @NonNull final Throwable error, + @NonNull final Exception error, final long retryWaitMillis) { return new FailedMediaSource(playQueueItem, error, System.currentTimeMillis() + retryWaitMillis); diff --git a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java index d4ed973aa..b4e9a15ab 100644 --- a/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java +++ b/app/src/main/java/org/schabi/newpipe/player/playback/MediaSourceManager.java @@ -441,7 +441,8 @@ public class MediaSourceManager { if (throwable instanceof ExtractionException) { return FailedMediaSource.of(stream, new StreamInfoLoadException(throwable)); } - return FailedMediaSource.of(stream, throwable, /*immediatelyRetryable=*/0L); + return FailedMediaSource + .of(stream, new Exception(throwable), /*immediatelyRetryable=*/0L); }); }