diff --git a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java index 8a86a5326..0938f7f46 100644 --- a/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java +++ b/app/src/main/java/org/schabi/newpipe/player/NotificationUtil.java @@ -23,6 +23,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.util.NavigationHelper; +import java.lang.ref.WeakReference; import java.util.List; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; @@ -54,6 +55,8 @@ public final class NotificationUtil { private NotificationManagerCompat notificationManager; private NotificationCompat.Builder notificationBuilder; + @Nullable + private WeakReference foregroundService; private NotificationUtil() { } @@ -79,11 +82,16 @@ public static NotificationUtil getInstance() { */ public synchronized void createNotificationIfNeededAndUpdate(final Player player, final boolean forceRecreate) { + final Service service = foregroundService == null ? null : foregroundService.get(); if (forceRecreate || notificationBuilder == null) { - notificationBuilder = createNotification(player, null); + notificationBuilder = createNotification(player, service); } updateNotification(player); - notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + if (service != null) { + startForeground(service, notificationBuilder); + } else { + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + } } private synchronized NotificationCompat.Builder createNotification(final Player player, final Service service) { @@ -192,16 +200,20 @@ boolean shouldUpdateBufferingSlot() { void createNotificationAndStartForeground(final Player player, final Service service) { - if (notificationBuilder == null) { - notificationBuilder = createNotification(player, service); - } + foregroundService = new WeakReference<>(service); + notificationBuilder = createNotification(player, service); updateNotification(player); + startForeground(service, notificationBuilder); + } + + private void startForeground(final Service service, + final NotificationCompat.Builder builder) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - service.startForeground(NOTIFICATION_ID, notificationBuilder.build(), + service.startForeground(NOTIFICATION_ID, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK); } else { - service.startForeground(NOTIFICATION_ID, notificationBuilder.build()); + service.startForeground(NOTIFICATION_ID, builder.build()); } } @@ -229,6 +241,7 @@ void cancelNotificationAndStopForeground(final Service service) { } notificationManager = null; notificationBuilder = null; + foregroundService = null; } 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 2c08ea004..b79125495 100644 --- a/app/src/main/java/org/schabi/newpipe/player/Player.java +++ b/app/src/main/java/org/schabi/newpipe/player/Player.java @@ -968,6 +968,10 @@ private void initPlayback(@NonNull final PlayQueue queue, simpleExoPlayer.setVolume(isMuted ? 0 : 1); if (playQueue != null) { simpleExoPlayer.setShuffleModeEnabled(playQueue.isShuffled()); + if (mediaSessionManager != null) { + mediaSessionManager.dispose(); + mediaSessionManager = null; + } playerMediaSession = new PlayerMediaSession(this, simpleExoPlayer); mediaSessionManager = new MediaSessionManager(context, simpleExoPlayer, playerMediaSession, service.getMediaSession(), diff --git a/app/src/main/java/org/schabi/newpipe/player/datasource/SabrMediaPeriod.java b/app/src/main/java/org/schabi/newpipe/player/datasource/SabrMediaPeriod.java index a0d2c3fdf..f48c0ce78 100644 --- a/app/src/main/java/org/schabi/newpipe/player/datasource/SabrMediaPeriod.java +++ b/app/src/main/java/org/schabi/newpipe/player/datasource/SabrMediaPeriod.java @@ -56,6 +56,8 @@ final class SabrMediaPeriod implements MediaPeriod, private SequenceableLoader compositeLoader = new EmptyLoader(); @Nullable private MediaPeriod.Callback callback; + private boolean videoActive; + private boolean audioActive; SabrMediaPeriod(final SabrSessionStore.Holder holder, final Format audioFormat, @@ -123,14 +125,14 @@ public long selectTracks(final ExoTrackSelection[] selections, final boolean[] m streamResetFlags[i] = true; } } - updateActiveTracks(selections); + updateActiveTracks(selections, positionUs); rebuildCompositeLoader(); return positionUs; } - private void updateActiveTracks(final ExoTrackSelection[] selections) { - boolean videoActive = false; - boolean audioActive = false; + private void updateActiveTracks(final ExoTrackSelection[] selections, final long positionUs) { + boolean selectedVideo = false; + boolean selectedAudio = false; for (final ExoTrackSelection selection : selections) { if (selection == null) { continue; @@ -140,14 +142,17 @@ private void updateActiveTracks(final ExoTrackSelection[] selections) { continue; } if (trackTypes[groupIndex] == C.TRACK_TYPE_VIDEO) { - videoActive = true; + selectedVideo = true; } else if (trackTypes[groupIndex] == C.TRACK_TYPE_AUDIO) { - audioActive = true; + selectedAudio = true; } } - holder.setActiveTracks(videoActive, audioActive); + videoActive = selectedVideo; + audioActive = selectedAudio; + holder.prepareForPlaybackPositionMs(positionUs / 1000, selectedVideo, selectedAudio); + holder.setActiveTracks(selectedVideo, selectedAudio); Log.d(TAG, "activeTracks video=" + holder.videoId - + " video=" + videoActive + " audio=" + audioActive); + + " video=" + selectedVideo + " audio=" + selectedAudio); } private ChunkSampleStream buildStream(final ExoTrackSelection selection, @@ -242,6 +247,7 @@ public long readDiscontinuity() { @Override public long seekToUs(final long positionUs) { + holder.prepareForPlaybackPositionMs(positionUs / 1000, videoActive, audioActive); for (final ChunkSampleStream s : streams) { s.seekToUs(positionUs); } diff --git a/app/src/main/java/org/schabi/newpipe/player/datasource/SabrSessionStore.java b/app/src/main/java/org/schabi/newpipe/player/datasource/SabrSessionStore.java index 76124fcac..24ed2cf91 100644 --- a/app/src/main/java/org/schabi/newpipe/player/datasource/SabrSessionStore.java +++ b/app/src/main/java/org/schabi/newpipe/player/datasource/SabrSessionStore.java @@ -119,6 +119,32 @@ void setActiveTracks(final boolean videoActive, final boolean audioActive) { } } + void prepareForPlaybackPositionMs(final long positionMs, + final boolean videoActive, + final boolean audioActive) { + if (positionMs <= 0 || (!videoActive && !audioActive)) { + return; + } + if (videoActive) { + final int sequence = session.getStreamState() + .getSegmentNumberAtOrAfterTimeMs(videoFormat, positionMs); + final long segmentStartMs = session.getStreamState() + .getSegmentStartMs(videoFormat, sequence); + setReaderPositionMs(videoFormat.getItag(), segmentStartMs); + session.prepareForForwardJump(SabrSegmentRequest.media(videoFormat, sequence)); + } + if (audioActive) { + final int sequence = session.getStreamState() + .getSegmentNumberAtOrAfterTimeMs(audioFormat, positionMs); + final long segmentStartMs = session.getStreamState() + .getSegmentStartMs(audioFormat, sequence); + setReaderPositionMs(audioFormat.getItag(), segmentStartMs); + if (!videoActive) { + session.prepareForForwardJump(SabrSegmentRequest.media(audioFormat, sequence)); + } + } + } + private boolean hasActiveTracks() { return !activeReaderItags.isEmpty(); }