Save shuffel/repeat mode in PlaybackState

This commit is contained in:
tzugen 2022-07-05 22:51:37 +02:00
parent bf55e9ebc1
commit 8c160a31eb
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
5 changed files with 67 additions and 48 deletions

View File

@ -1,19 +1,19 @@
package org.moire.ultrasonic.service; package org.moire.ultrasonic.service
import org.moire.ultrasonic.domain.Track; import java.io.Serializable
import org.moire.ultrasonic.domain.Track
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/** /**
* Represents the state of the Media Player implementation * Represents the state of the Media Player implementation
*/ */
public class State implements Serializable data class PlaybackState(
{ val songs: List<Track> = listOf(),
public static final long serialVersionUID = -6346438781062572270L; val currentPlayingIndex: Int = 0,
val currentPlayingPosition: Int = 0,
public List<Track> songs = new ArrayList<>(); var shufflePlay: Boolean = false,
public int currentPlayingIndex; var repeatMode: Int = 0
public int currentPlayingPosition; ) : Serializable {
companion object {
const val serialVersionUID = -293487987L
}
} }

View File

@ -17,6 +17,7 @@ import org.moire.ultrasonic.adapters.BaseAdapter
import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.MusicDirectory
import org.moire.ultrasonic.domain.Track import org.moire.ultrasonic.domain.Track
import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.service.PlaybackState
/** /**
* Lists the Bookmarks available on the server * Lists the Bookmarks available on the server
@ -65,12 +66,14 @@ class BookmarksFragment : TrackCollectionFragment() {
private fun playNow(songs: List<Track>) { private fun playNow(songs: List<Track>) {
if (songs.isNotEmpty()) { if (songs.isNotEmpty()) {
val position = songs[0].bookmarkPosition val state = PlaybackState(
mediaPlayerController.restore(
songs = songs, songs = songs,
currentPlayingIndex = 0, currentPlayingIndex = 0,
currentPlayingPosition = position, currentPlayingPosition = songs[0].bookmarkPosition
)
mediaPlayerController.restore(
state = state,
autoPlay = true, autoPlay = true,
newPlaylist = true newPlaylist = true
) )

View File

@ -256,9 +256,7 @@ class MediaPlayerController(
@Synchronized @Synchronized
fun restore( fun restore(
songs: List<Track>, state: PlaybackState,
currentPlayingIndex: Int,
currentPlayingPosition: Int,
autoPlay: Boolean, autoPlay: Boolean,
newPlaylist: Boolean newPlaylist: Boolean
) { ) {
@ -266,21 +264,24 @@ class MediaPlayerController(
else InsertionMode.APPEND else InsertionMode.APPEND
addToPlaylist( addToPlaylist(
songs, state.songs,
cachePermanently = false, cachePermanently = false,
autoPlay = false, autoPlay = false,
shuffle = false, shuffle = false,
insertionMode = insertionMode insertionMode = insertionMode
) )
if (currentPlayingIndex != -1) { repeatMode = state.repeatMode
isShufflePlayEnabled = state.shufflePlay
if (state.currentPlayingIndex != -1) {
if (jukeboxMediaPlayer.isEnabled) { if (jukeboxMediaPlayer.isEnabled) {
jukeboxMediaPlayer.skip( jukeboxMediaPlayer.skip(
currentPlayingIndex, state.currentPlayingIndex,
currentPlayingPosition / 1000 state.currentPlayingPosition / 1000
) )
} else { } else {
seekTo(currentPlayingIndex, currentPlayingPosition) seekTo(state.currentPlayingIndex, state.currentPlayingPosition)
} }
prepare() prepare()
@ -445,8 +446,8 @@ class MediaPlayerController(
controller?.clearMediaItems() controller?.clearMediaItems()
if (controller != null && serialize) { if (controller != null && serialize) {
playbackStateSerializer.serialize( playbackStateSerializer.serializeAsync(
listOf(), -1, 0 listOf(), -1, 0, isShufflePlayEnabled, repeatMode
) )
} }
@ -481,10 +482,12 @@ class MediaPlayerController(
// Don't serialize invalid sessions // Don't serialize invalid sessions
if (currentMediaItemIndex == -1) return if (currentMediaItemIndex == -1) return
playbackStateSerializer.serialize( playbackStateSerializer.serializeAsync(
legacyPlaylistManager.playlist, songs = legacyPlaylistManager.playlist,
currentMediaItemIndex, currentPlayingIndex = currentMediaItemIndex,
playerPosition currentPlayingPosition = playerPosition,
isShufflePlayEnabled,
repeatMode
) )
} }

View File

@ -60,9 +60,7 @@ class MediaPlayerLifecycleSupport : KoinComponent {
Timber.i("Restoring %s songs", it!!.songs.size) Timber.i("Restoring %s songs", it!!.songs.size)
mediaPlayerController.restore( mediaPlayerController.restore(
it.songs, it,
it.currentPlayingIndex,
it.currentPlayingPosition,
autoPlay, autoPlay,
false false
) )
@ -78,7 +76,9 @@ class MediaPlayerLifecycleSupport : KoinComponent {
playbackStateSerializer.serializeNow( playbackStateSerializer.serializeNow(
mediaPlayerController.playList, mediaPlayerController.playList,
mediaPlayerController.currentMediaItemIndex, mediaPlayerController.currentMediaItemIndex,
mediaPlayerController.playerPosition mediaPlayerController.playerPosition,
mediaPlayerController.isShufflePlayEnabled,
mediaPlayerController.repeatMode
) )
mediaPlayerController.clear(false) mediaPlayerController.clear(false)

View File

@ -31,17 +31,25 @@ class PlaybackStateSerializer : KoinComponent {
private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val mainScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) private val mainScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
fun serialize( fun serializeAsync(
songs: Iterable<DownloadFile>, songs: Iterable<DownloadFile>,
currentPlayingIndex: Int, currentPlayingIndex: Int,
currentPlayingPosition: Int currentPlayingPosition: Int,
shufflePlay: Boolean,
repeatMode: Int
) { ) {
if (isSerializing.get() || !isSetup.get()) return if (isSerializing.get() || !isSetup.get()) return
isSerializing.set(true) isSerializing.set(true)
ioScope.launch { ioScope.launch {
serializeNow(songs, currentPlayingIndex, currentPlayingPosition) serializeNow(
songs,
currentPlayingIndex,
currentPlayingPosition,
shufflePlay,
repeatMode
)
}.invokeOnCompletion { }.invokeOnCompletion {
isSerializing.set(false) isSerializing.set(false)
} }
@ -50,17 +58,22 @@ class PlaybackStateSerializer : KoinComponent {
fun serializeNow( fun serializeNow(
referencedList: Iterable<DownloadFile>, referencedList: Iterable<DownloadFile>,
currentPlayingIndex: Int, currentPlayingIndex: Int,
currentPlayingPosition: Int currentPlayingPosition: Int,
shufflePlay: Boolean,
repeatMode: Int
) { ) {
val state = State()
val songs = referencedList.toList()
for (downloadFile in songs) { val tracks = referencedList.toList().map {
state.songs.add(downloadFile.track) it.track
} }
state.currentPlayingIndex = currentPlayingIndex val state = PlaybackState(
state.currentPlayingPosition = currentPlayingPosition tracks,
currentPlayingIndex,
currentPlayingPosition,
shufflePlay,
repeatMode
)
Timber.i( Timber.i(
"Serialized currentPlayingIndex: %d, currentPlayingPosition: %d", "Serialized currentPlayingIndex: %d, currentPlayingPosition: %d",
@ -71,7 +84,7 @@ class PlaybackStateSerializer : KoinComponent {
FileUtil.serialize(context, state, Constants.FILENAME_PLAYLIST_SER) FileUtil.serialize(context, state, Constants.FILENAME_PLAYLIST_SER)
} }
fun deserialize(afterDeserialized: (State?) -> Unit?) { fun deserialize(afterDeserialized: (PlaybackState?) -> Unit?) {
if (isDeserializing.get()) return if (isDeserializing.get()) return
ioScope.launch { ioScope.launch {
try { try {
@ -85,9 +98,9 @@ class PlaybackStateSerializer : KoinComponent {
} }
} }
private fun deserializeNow(afterDeserialized: (State?) -> Unit?) { private fun deserializeNow(afterDeserialized: (PlaybackState?) -> Unit?) {
val state = FileUtil.deserialize<State>( val state = FileUtil.deserialize<PlaybackState>(
context, Constants.FILENAME_PLAYLIST_SER context, Constants.FILENAME_PLAYLIST_SER
) ?: return ) ?: return