From d1609cba90006e18a0dde03f09d133aedf73e985 Mon Sep 17 00:00:00 2001 From: Avently <7953703+avently@users.noreply.github.com> Date: Wed, 15 Jan 2020 21:32:29 +0300 Subject: [PATCH] Enhancements to background playback and media button handling --- .../fragments/detail/VideoDetailFragment.java | 14 +++++----- .../org/schabi/newpipe/player/MainPlayer.java | 26 ++++++++++++++++--- .../newpipe/player/VideoPlayerImpl.java | 10 +++---- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index b1929891b..5493d05cc 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -21,6 +21,7 @@ import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.PlaybackParameters; +import com.google.android.exoplayer2.Player; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.tabs.TabLayout; @@ -237,9 +238,8 @@ public class VideoDetailFragment if (!player.videoPlayerSelected()) return; - if (currentInfo == null && !wasCleared()) selectAndLoadVideo(serviceId, url, name, playQueue); - - if (player.getPlayQueue() != null) addVideoPlayerView(); + // STATE_IDLE means the player is stopped + if (player.getPlayer() != null && player.getPlayer().getPlaybackState() != Player.STATE_IDLE) addVideoPlayerView(); // If the video is playing but orientation changed let's make the video in fullscreen again @@ -375,7 +375,7 @@ public class VideoDetailFragment updateFlags = 0; } - // Check if it was loading when the fragment was stopped/paused, + // Check if it was loading when the fragment was stopped/paused if (wasLoading.getAndSet(false) && !wasCleared()) { selectAndLoadVideo(serviceId, url, name, playQueue); } else if (currentInfo != null) { @@ -537,7 +537,7 @@ public class VideoDetailFragment bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); break; case R.id.overlay_play_pause_button: - if (player != null) { + if (player != null && player.getPlayer() != null && player.getPlayer().getPlaybackState() != Player.STATE_IDLE) { player.onPlayPause(); player.hideControls(0,0); showSystemUi(); @@ -900,9 +900,9 @@ public class VideoDetailFragment } private void setupFromHistoryItem(StackItem item) { + setAutoplay(false); hideMainPlayer(); - setAutoplay(false); selectAndLoadVideo( item.getServiceId(), item.getUrl(), @@ -1107,7 +1107,7 @@ public class VideoDetailFragment return; removeVideoPlayerView(); - playerService.stop(); + playerService.stop(isAutoplayEnabled()); playerService.getView().setVisibility(View.GONE); } diff --git a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java index 4e3c070a5..b7081f71e 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainPlayer.java @@ -113,6 +113,10 @@ public final class MainPlayer extends Service { public int onStartCommand(Intent intent, int flags, int startId) { if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]"); + + if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) || intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) + showNotificationAndStartForeground(); + playerImpl.handleIntent(intent); if (playerImpl.mediaSessionManager != null) { playerImpl.mediaSessionManager.handleMediaButtonIntent(intent); @@ -120,15 +124,20 @@ public final class MainPlayer extends Service { return START_NOT_STICKY; } - public void stop() { - if (DEBUG) - Log.d(TAG, "stop() called"); + public void stop(boolean autoplayEnabled) { + if (DEBUG) Log.d(TAG, "stop() called"); if (playerImpl.getPlayer() != null) { playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady(); - // We can't pause the player here because it will make transition from one stream to a new stream not smooth + // Releases wifi & cpu, disables keepScreenOn, etc. + if (!autoplayEnabled) playerImpl.onPause(); + // We can't just pause the player here because it will make transition from one stream to a new stream not smooth playerImpl.getPlayer().stop(false); playerImpl.setRecovery(); + // Notification shows information about old stream but if a user selects a stream from backStack it's not actual anymore + // So we should hide the notification at all. + // When autoplay enabled such notification flashing is annoying so skip this case + if (!autoplayEnabled) stopForeground(true); } } @@ -211,6 +220,15 @@ public final class MainPlayer extends Service { } } + private void showNotificationAndStartForeground() { + resetNotification(); + if (getBigNotRemoteView() != null) + getBigNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); + if (getNotRemoteView() != null) + getNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); + startForeground(NOTIFICATION_ID, getNotBuilder().build()); + } + /*////////////////////////////////////////////////////////////////////////// // Notification //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java index 3bf734458..2da110712 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayerImpl.java @@ -189,12 +189,6 @@ public class VideoPlayerImpl extends VideoPlayer reload(); } - service.resetNotification(); - if (service.getBigNotRemoteView() != null) - service.getBigNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); - if (service.getNotRemoteView() != null) - service.getNotRemoteView().setProgressBar(R.id.notificationProgressBar, 100, 0, false); - service.startForeground(NOTIFICATION_ID, service.getNotBuilder().build()); setupElementsVisibility(); if (audioPlayerSelected()) { @@ -1167,7 +1161,7 @@ public class VideoPlayerImpl extends VideoPlayer public void checkLandscape() { AppCompatActivity parent = getParentActivity(); if (parent != null && service.isLandscape() != isInFullscreen() - && getCurrentState() != STATE_COMPLETED && videoPlayerSelected()) + && getCurrentState() != STATE_COMPLETED && videoPlayerSelected() && !audioOnly) toggleFullscreen(); } @@ -1197,6 +1191,8 @@ public class VideoPlayerImpl extends VideoPlayer return; audioOnly = !video; + // When a user returns from background controls could be hidden but systemUI will be shown 100%. Hide it + if (!audioOnly && !isControlsVisible()) hideSystemUIIfNeeded(); setRecovery(); reload(); }