Enhancements to background playback and media button handling

This commit is contained in:
Avently 2020-01-15 21:32:29 +03:00
parent 0c394b123c
commit d1609cba90
3 changed files with 32 additions and 18 deletions

View file

@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
@ -237,9 +238,8 @@ public class VideoDetailFragment
if (!player.videoPlayerSelected()) return; if (!player.videoPlayerSelected()) return;
if (currentInfo == null && !wasCleared()) selectAndLoadVideo(serviceId, url, name, playQueue); // STATE_IDLE means the player is stopped
if (player.getPlayer() != null && player.getPlayer().getPlaybackState() != Player.STATE_IDLE) addVideoPlayerView();
if (player.getPlayQueue() != null) addVideoPlayerView();
// If the video is playing but orientation changed let's make the video in fullscreen again // 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; 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()) { if (wasLoading.getAndSet(false) && !wasCleared()) {
selectAndLoadVideo(serviceId, url, name, playQueue); selectAndLoadVideo(serviceId, url, name, playQueue);
} else if (currentInfo != null) { } else if (currentInfo != null) {
@ -537,7 +537,7 @@ public class VideoDetailFragment
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break; break;
case R.id.overlay_play_pause_button: 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.onPlayPause();
player.hideControls(0,0); player.hideControls(0,0);
showSystemUi(); showSystemUi();
@ -900,9 +900,9 @@ public class VideoDetailFragment
} }
private void setupFromHistoryItem(StackItem item) { private void setupFromHistoryItem(StackItem item) {
setAutoplay(false);
hideMainPlayer(); hideMainPlayer();
setAutoplay(false);
selectAndLoadVideo( selectAndLoadVideo(
item.getServiceId(), item.getServiceId(),
item.getUrl(), item.getUrl(),
@ -1107,7 +1107,7 @@ public class VideoDetailFragment
return; return;
removeVideoPlayerView(); removeVideoPlayerView();
playerService.stop(); playerService.stop(isAutoplayEnabled());
playerService.getView().setVisibility(View.GONE); playerService.getView().setVisibility(View.GONE);
} }

View file

@ -113,6 +113,10 @@ public final class MainPlayer extends Service {
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent + if (DEBUG) Log.d(TAG, "onStartCommand() called with: intent = [" + intent +
"], flags = [" + flags + "], startId = [" + startId + "]"); "], flags = [" + flags + "], startId = [" + startId + "]");
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction()) || intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null)
showNotificationAndStartForeground();
playerImpl.handleIntent(intent); playerImpl.handleIntent(intent);
if (playerImpl.mediaSessionManager != null) { if (playerImpl.mediaSessionManager != null) {
playerImpl.mediaSessionManager.handleMediaButtonIntent(intent); playerImpl.mediaSessionManager.handleMediaButtonIntent(intent);
@ -120,15 +124,20 @@ public final class MainPlayer extends Service {
return START_NOT_STICKY; return START_NOT_STICKY;
} }
public void stop() { public void stop(boolean autoplayEnabled) {
if (DEBUG) if (DEBUG) Log.d(TAG, "stop() called");
Log.d(TAG, "stop() called");
if (playerImpl.getPlayer() != null) { if (playerImpl.getPlayer() != null) {
playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady(); 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.getPlayer().stop(false);
playerImpl.setRecovery(); 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 // Notification
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/

View file

@ -189,12 +189,6 @@ public class VideoPlayerImpl extends VideoPlayer
reload(); 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(); setupElementsVisibility();
if (audioPlayerSelected()) { if (audioPlayerSelected()) {
@ -1167,7 +1161,7 @@ public class VideoPlayerImpl extends VideoPlayer
public void checkLandscape() { public void checkLandscape() {
AppCompatActivity parent = getParentActivity(); AppCompatActivity parent = getParentActivity();
if (parent != null && service.isLandscape() != isInFullscreen() if (parent != null && service.isLandscape() != isInFullscreen()
&& getCurrentState() != STATE_COMPLETED && videoPlayerSelected()) && getCurrentState() != STATE_COMPLETED && videoPlayerSelected() && !audioOnly)
toggleFullscreen(); toggleFullscreen();
} }
@ -1197,6 +1191,8 @@ public class VideoPlayerImpl extends VideoPlayer
return; return;
audioOnly = !video; 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(); setRecovery();
reload(); reload();
} }