From ec6612dd71163578f4cd45500202ecf7a3f8f0b9 Mon Sep 17 00:00:00 2001 From: Stypox Date: Sun, 16 Feb 2025 09:14:26 +0100 Subject: [PATCH] Call exoPlayer.prepare() on PlaybackPreparer.onPrepare() If a playbackPreparer is set, then instead of calling `player.prepare()`, the MediaSessionConnector will call `playbackPreparer.onPrepare(true)` instead, as seen below. This commit makes it so that playbackPreparer.onPrepare(true) restores the original behavior of just calling player.prepare(). From MediaSessionConnector -> MediaSessionCompat.Callback implementation: ```java @Override public void onPlay() { if (canDispatchPlaybackAction(PlaybackStateCompat.ACTION_PLAY)) { if (player.getPlaybackState() == Player.STATE_IDLE) { if (playbackPreparer != null) { playbackPreparer.onPrepare(/* playWhenReady= */ true); } else { player.prepare(); } } else if (player.getPlaybackState() == Player.STATE_ENDED) { seekTo(player, player.getCurrentMediaItemIndex(), C.TIME_UNSET); } Assertions.checkNotNull(player).play(); } } ``` --- .../main/java/org/schabi/newpipe/player/Player.java | 13 +++++++++++++ .../org/schabi/newpipe/player/PlayerService.java | 7 ++++++- .../mediabrowser/MediaBrowserPlaybackPreparer.kt | 7 ++++++- 3 files changed, 25 insertions(+), 2 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 41705ffb2..b86d11e5c 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -1386,6 +1386,19 @@ public final class Player implements PlaybackListener, Listener { public void onCues(@NonNull final CueGroup cueGroup) { UIs.call(playerUi -> playerUi.onCues(cueGroup.cues)); } + + /** + * To be called when the {@code PlaybackPreparer} set in the {@link MediaSessionConnector} + * receives an {@code onPrepare()} call. This function allows restoring the default behavior + * that would happen if there was no playback preparer set, i.e. to just call + * {@code player.prepare()}. You can find the default behavior in `onPlay()` inside the + * {@link MediaSessionConnector} file. + */ + public void onPrepare() { + if (!exoPlayerIsNull()) { + simpleExoPlayer.prepare(); + } + } //endregion diff --git a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java index cbad4220c..fa8dda526 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PlayerService.java +++ b/app/src/main/java/org/schabi/newpipe/player/PlayerService.java @@ -96,7 +96,12 @@ public final class PlayerService extends MediaBrowserServiceCompat { mediaBrowserPlaybackPreparer = new MediaBrowserPlaybackPreparer( this, sessionConnector::setCustomErrorMessage, - () -> sessionConnector.setCustomErrorMessage(null) + () -> sessionConnector.setCustomErrorMessage(null), + (playWhenReady) -> { + if (player != null) { + player.onPrepare(); + } + } ); sessionConnector.setPlaybackPreparer(mediaBrowserPlaybackPreparer); diff --git a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt index 9d77ae8b9..d059bbdde 100644 --- a/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt +++ b/app/src/main/java/org/schabi/newpipe/player/mediabrowser/MediaBrowserPlaybackPreparer.kt @@ -29,6 +29,7 @@ import org.schabi.newpipe.util.ChannelTabHelper import org.schabi.newpipe.util.ExtractorHelper import org.schabi.newpipe.util.NavigationHelper import java.util.function.BiConsumer +import java.util.function.Consumer /** * This class is used to cleanly separate the Service implementation (in @@ -40,11 +41,15 @@ import java.util.function.BiConsumer * @param setMediaSessionError takes an error String and an error code from [PlaybackStateCompat], * calls `sessionConnector.setCustomErrorMessage(errorString, errorCode)` * @param clearMediaSessionError calls `sessionConnector.setCustomErrorMessage(null)` + * @param onPrepare takes playWhenReady, calls `player.prepare()`; this is needed because + * `MediaSessionConnector`'s `onPlay()` method calls this class' [onPrepare] instead of + * `player.prepare()` if the playback preparer is not null, but we want the original behavior */ class MediaBrowserPlaybackPreparer( private val context: Context, private val setMediaSessionError: BiConsumer, // error string, error code private val clearMediaSessionError: Runnable, + private val onPrepare: Consumer, ) : PlaybackPreparer { private val database = NewPipeDatabase.getInstance(context) private var disposable: Disposable? = null @@ -59,7 +64,7 @@ class MediaBrowserPlaybackPreparer( } override fun onPrepare(playWhenReady: Boolean) { - // TODO handle onPrepare + onPrepare.accept(playWhenReady) } override fun onPrepareFromMediaId(mediaId: String, playWhenReady: Boolean, extras: Bundle?) {