mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-05-17 15:56:36 +03:00
Merge branch 'save-shuffle' into 'develop'
Save shuffle See merge request ultrasonic/ultrasonic!777
This commit is contained in:
commit
8ecf7f468e
@ -0,0 +1,19 @@
|
|||||||
|
package org.moire.ultrasonic.service
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
import org.moire.ultrasonic.domain.Track
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the state of the Media Player implementation
|
||||||
|
*/
|
||||||
|
data class PlaybackState(
|
||||||
|
val songs: List<Track> = listOf(),
|
||||||
|
val currentPlayingIndex: Int = 0,
|
||||||
|
val currentPlayingPosition: Int = 0,
|
||||||
|
var shufflePlay: Boolean = false,
|
||||||
|
var repeatMode: Int = 0
|
||||||
|
) : Serializable {
|
||||||
|
companion object {
|
||||||
|
const val serialVersionUID = -293487987L
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
package org.moire.ultrasonic.service;
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
public class State implements Serializable
|
|
||||||
{
|
|
||||||
public static final long serialVersionUID = -6346438781062572270L;
|
|
||||||
|
|
||||||
public List<Track> songs = new ArrayList<>();
|
|
||||||
public int currentPlayingIndex;
|
|
||||||
public int currentPlayingPosition;
|
|
||||||
}
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,28 +58,34 @@ 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, shuffle: %b",
|
||||||
state.currentPlayingIndex,
|
state.currentPlayingIndex,
|
||||||
state.currentPlayingPosition
|
state.currentPlayingPosition,
|
||||||
|
state.shufflePlay
|
||||||
)
|
)
|
||||||
|
|
||||||
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,16 +99,17 @@ 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
|
||||||
|
|
||||||
Timber.i(
|
Timber.i(
|
||||||
"Deserialized currentPlayingIndex: %d, currentPlayingPosition: %d ",
|
"Deserialized currentPlayingIndex: %d, currentPlayingPosition: %d, shuffle: %b",
|
||||||
state.currentPlayingIndex,
|
state.currentPlayingIndex,
|
||||||
state.currentPlayingPosition
|
state.currentPlayingPosition,
|
||||||
|
state.shufflePlay
|
||||||
)
|
)
|
||||||
|
|
||||||
mainScope.launch {
|
mainScope.launch {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user