diff --git a/CHANGELOG.md b/CHANGELOG.md index 66ccedd7b..ce0284a29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Sorting songs by date now uses songs date first, before the earliest album date #### What's Fixed +- Playback no longer briefly pauses when adding songs to playlists - Music loader no longer spawns thousands of threads when scanning - Excessive CPU no longer spent showing music loading process - Fixed playback sheet flickering on warm start diff --git a/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt b/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt index 058b33403..adf3a782c 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt @@ -49,6 +49,7 @@ import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.service.toMediaItem import org.oxycblt.auxio.music.service.toSong import org.oxycblt.auxio.playback.PlaybackSettings +import org.oxycblt.auxio.playback.msToSecs import org.oxycblt.auxio.playback.persist.PersistenceRepository import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor import org.oxycblt.auxio.playback.state.DeferredPlayback @@ -365,13 +366,21 @@ class ExoPlaybackStateHolder( override fun applySavedState( parent: MusicParent?, rawQueue: RawQueue, + positionMs: Long, + repeatMode: RepeatMode, ack: StateAck.NewPlayback? ) { - logD("Applying saved state") - var sendEvent = false + val resolve = resolveQueue() + logD("${rawQueue.heap == resolve.heap}") + logD("${rawQueue.shuffledMapping == resolve.shuffledMapping}") + logD("${rawQueue.heapIndex == resolve.heapIndex}") + logD("${rawQueue.isShuffled == resolve.isShuffled}") + logD("${rawQueue == resolve}") + var sendNewPlaybackEvent = false + var shouldSeek = false if (this.parent != parent) { this.parent = parent - sendEvent = true + sendNewPlaybackEvent = true } if (rawQueue != resolveQueue()) { player.setMediaItems(rawQueue.heap.map { it.toMediaItem(context, null) }) @@ -384,9 +393,18 @@ class ExoPlaybackStateHolder( player.seekTo(rawQueue.heapIndex, C.TIME_UNSET) player.prepare() player.pause() - sendEvent = true + sendNewPlaybackEvent = true + shouldSeek = true } - if (sendEvent) { + + repeatMode(repeatMode) + // Positions in milliseconds will drift during tight restores (i.e what the music loader + // does to sanitize the state), compare by seconds instead. + if (positionMs.msToSecs() != player.currentPosition.msToSecs() || shouldSeek) { + player.seekTo(positionMs) + } + + if (sendNewPlaybackEvent) { ack?.let { playbackManager.ack(this, it) } } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt index 857ac6898..01ff1e520 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt @@ -145,7 +145,13 @@ interface PlaybackStateHolder { * @param ack The [StateAck] to return to [PlaybackStateManager]. If null, do not return any * ack. */ - fun applySavedState(parent: MusicParent?, rawQueue: RawQueue, ack: StateAck.NewPlayback?) + fun applySavedState( + parent: MusicParent?, + rawQueue: RawQueue, + positionMs: Long, + repeatMode: RepeatMode, + ack: StateAck.NewPlayback? + ) /** End whatever ongoing playback session may be going on */ fun endSession() diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 494ab2c0e..948be122e 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -24,6 +24,7 @@ import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.playback.state.PlaybackStateManager.Listener import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logW @@ -416,9 +417,12 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager { this.stateHolder = stateHolder if (isInitialized && currentSong != null) { - stateHolder.applySavedState(stateMirror.parent, stateMirror.rawQueue, null) - stateHolder.seekTo(stateMirror.progression.calculateElapsedPositionMs()) - stateHolder.playing(false) + stateHolder.applySavedState( + stateMirror.parent, + stateMirror.rawQueue, + stateMirror.progression.calculateElapsedPositionMs(), + stateMirror.repeatMode, + null) } pendingDeferredPlayback?.let(stateHolder::handleDeferred) } @@ -795,9 +799,12 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager { index }) - stateHolder.applySavedState(savedState.parent, rawQueue, StateAck.NewPlayback) - stateHolder.seekTo(savedState.positionMs) - stateHolder.repeatMode(savedState.repeatMode) + stateHolder.applySavedState( + savedState.parent, + rawQueue, + savedState.positionMs, + savedState.repeatMode, + StateAck.NewPlayback) isInitialized = true }