From 69646e5b5d5adae43abafcfa47b2aa587665ddb7 Mon Sep 17 00:00:00 2001 From: karyogamy Date: Wed, 16 Mar 2022 20:47:29 -0400 Subject: [PATCH] added: documentations to MediaItemTags and Player. fixed: checkStyle failures. --- .../org/schabi/newpipe/player/Player.java | 53 ++++++++++++------- .../player/mediaitem/ExceptionTag.java | 10 ++++ .../player/mediaitem/MediaItemTag.java | 8 +++ .../player/mediaitem/PlaceholderTag.java | 11 +++- .../player/mediaitem/StreamInfoTag.java | 8 +++ .../player/mediasource/FailedMediaSource.java | 12 ++++- 6 files changed, 79 insertions(+), 23 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 2305eb9d0..355cd4079 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -133,7 +133,6 @@ import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player.PositionInfo; import com.google.android.exoplayer2.RenderersFactory; -import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.TracksInfo; import com.google.android.exoplayer2.source.MediaSource; @@ -2487,6 +2486,7 @@ public final class Player implements //////////////////////////////////////////////////////////////////////////*/ //region ExoPlayer listeners (that didn't fit in other categories) + @Override public void onEvents(@NonNull final com.google.android.exoplayer2.Player player, @NonNull final com.google.android.exoplayer2.Player.Events events) { Listener.super.onEvents(player, events); @@ -2546,14 +2546,6 @@ public final class Player implements return; } - if (newPosition.contentPositionMs == 0 && - simpleExoPlayer.getTotalBufferedDuration() < 500L) { - Log.d(TAG, "Playback - skipping to initial keyframe."); - simpleExoPlayer.setSeekParameters(SeekParameters.CLOSEST_SYNC); - simpleExoPlayer.seekTo(1L); - simpleExoPlayer.setSeekParameters(PlayerHelper.getSeekParameters(context)); - } - // Refresh the playback if there is a transition to the next video final int newIndex = newPosition.mediaItemIndex; switch (discontinuityReason) { @@ -2605,7 +2597,29 @@ public final class Player implements //region Errors /** * Process exceptions produced by {@link com.google.android.exoplayer2.ExoPlayer ExoPlayer}. - * + *

There are multiple types of errors:

+ * * @see com.google.android.exoplayer2.Player.Listener#onPlayerError(PlaybackException) * */ @SuppressLint("SwitchIntDef") @@ -2648,6 +2662,9 @@ public final class Player implements 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(); @@ -2749,7 +2766,6 @@ public final class Player implements return; } - final boolean onPlaybackInitial = currentItem == null; final boolean hasPlayQueueItemChanged = currentItem != item; final int currentPlayQueueIndex = playQueue.indexOf(item); @@ -2953,10 +2969,8 @@ public final class Player implements //region StreamInfo history: views and progress private void registerStreamViewed() { - getCurrentStreamInfo().ifPresent(info -> { - databaseUpdateDisposable - .add(recordManager.onViewed(info).onErrorComplete().subscribe()); - }); + getCurrentStreamInfo().ifPresent(info -> databaseUpdateDisposable + .add(recordManager.onViewed(info).onErrorComplete().subscribe())); } private void saveStreamProgressState(final long progressMillis) { @@ -3134,7 +3148,7 @@ public final class Player implements return; } - if (playQueue.getIndex() == index && simpleExoPlayer.getCurrentWindowIndex() == index) { + if (playQueue.getIndex() == index && simpleExoPlayer.getCurrentMediaItemIndex() == index) { seekToDefault(); } else { saveStreamProgressState(); @@ -3880,9 +3894,10 @@ public final class Player implements } private void onOpenInBrowserClicked() { - getCurrentStreamInfo().map(Info::getOriginalUrl).ifPresent(originalUrl -> { - ShareUtils.openUrlInBrowser(Objects.requireNonNull(getParentActivity()), originalUrl); - }); + getCurrentStreamInfo() + .map(Info::getOriginalUrl) + .ifPresent(originalUrl -> ShareUtils.openUrlInBrowser( + Objects.requireNonNull(getParentActivity()), originalUrl)); } //endregion 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 2deffcf65..3e41262d6 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 @@ -10,6 +10,16 @@ import java.util.Optional; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +/** + * This {@link MediaItemTag} object is designed to contain metadata for a stream + * that has failed to load. It supplies metadata from an underlying + * {@link PlayQueueItem}, which is used by the internal players to resolve actual + * playback info. + * + * This {@link MediaItemTag} does not contain any {@link StreamInfo} that can be + * used to start playback and can be detected by checking {@link ExceptionTag#getErrors()} + * when in generic form. + **/ public final class ExceptionTag implements MediaItemTag { @NonNull private final PlayQueueItem item; 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 872a10a57..6f9b9e9f2 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 @@ -4,6 +4,7 @@ import android.net.Uri; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaMetadata; +import com.google.android.exoplayer2.Player; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; @@ -16,6 +17,13 @@ import java.util.UUID; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +/** + * Metadata container and accessor used by player internals. + * + * This interface ensures consistency of fetching metadata on each stream, + * which is encapsulated in a {@link MediaItem} and delivered via ExoPlayer's + * {@link Player.Listener} on event triggers to the downstream users. + **/ public interface MediaItemTag { List getErrors(); 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 c4998e9af..5b53e5660 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 @@ -2,6 +2,7 @@ package org.schabi.newpipe.player.mediaitem; import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; +import org.schabi.newpipe.util.Constants; import java.util.Collections; import java.util.List; @@ -10,6 +11,12 @@ import java.util.Optional; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +/** + * This is a Placeholding {@link MediaItemTag}, designed as a dummy metadata object for + * any stream that has not been resolved. + * + * This object cannot be instantiated and does not hold real metadata of any form. + * */ public final class PlaceholderTag implements MediaItemTag { public static final PlaceholderTag EMPTY = new PlaceholderTag(null); private static final String UNKNOWN_VALUE_INTERNAL = "Placeholder"; @@ -29,7 +36,7 @@ public final class PlaceholderTag implements MediaItemTag { @Override public int getServiceId() { - return -1; + return Constants.NO_SERVICE_ID; } @Override @@ -44,7 +51,7 @@ public final class PlaceholderTag implements MediaItemTag { @Override public long getDurationSeconds() { - return -1; + return 0; } @Override 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 93cf081f9..9ae25e07b 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 @@ -1,5 +1,7 @@ package org.schabi.newpipe.player.mediaitem; +import com.google.android.exoplayer2.MediaItem; + import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; @@ -11,6 +13,12 @@ import java.util.Optional; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +/** + * This {@link MediaItemTag} object contains metadata for a resolved stream + * that is ready for playback. This object guarantees the {@link StreamInfo} + * is available and may provide the {@link Quality} of video stream used in + * the {@link MediaItem}. + **/ public final class StreamInfoTag implements MediaItemTag { @NonNull private final StreamInfo streamInfo; 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 75fbbe433..d68eb1a1a 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 @@ -23,7 +23,15 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class FailedMediaSource extends CompositeMediaSource implements ManagedMediaSource { - private static final long SILENCE_DURATION_US = TimeUnit.SECONDS.toMicros(2); + /** + * Play 2 seconds of silenced audio when a stream fails to resolve due to a known issue, + * such as {@link org.schabi.newpipe.extractor.exceptions.ExtractionException}. + * + * This silence duration allows user to react and have time to jump to a previous stream, + * while still provide a smooth playback experience. A duration lower than 1 second is + * not recommended, it may cause ExoPlayer to buffer for a while. + * */ + public static final long SILENCE_DURATION_US = TimeUnit.SECONDS.toMicros(2); private final String TAG = "FailedMediaSource@" + Integer.toHexString(hashCode()); private final PlayQueueItem playQueueItem; @@ -32,7 +40,7 @@ public class FailedMediaSource extends CompositeMediaSource implements Man private final MediaSource source; private final MediaItem mediaItem; /** - * Permanently fail the play queue item associated with this source, with no hope of retrying. + * Fail the play queue item associated with this source, with potential future retries. * * The error will be propagated if the cause for load exception is unspecified. * This means the error might be caused by reasons outside of extraction (e.g. no network).