Revert to old playback shuffling system

The new shuffling system wasnt working out the best, so just revert to the previous and fix the issues with it.
This commit is contained in:
OxygenCobalt 2021-01-15 15:01:26 -07:00
parent 9ab8b4e018
commit d86e5f1414
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 54 additions and 90 deletions

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Auxio Debug</string> <string name="info_app_name">Auxio Debug</string>
</resources> </resources>

View file

@ -13,7 +13,7 @@
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="@xml/backup_descriptor" android:fullBackupContent="@xml/backup_descriptor"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/info_app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Base"> android:theme="@style/Theme.Base">
@ -32,7 +32,7 @@
</activity> </activity>
<service <service
android:name=".playback.PlaybackService" android:name=".playback.PlaybackService"
android:description="@string/label_service_playback" android:description="@string/info_service_desc"
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"
android:foregroundServiceType="mediaPlayback" android:foregroundServiceType="mediaPlayback"

View file

@ -128,10 +128,6 @@ class AlbumDetailFragment : DetailFragment() {
handlePlayingItem(detailAdapter) handlePlayingItem(detailAdapter)
} }
playbackModel.mode.observe(viewLifecycleOwner) {
handlePlayingItem(detailAdapter)
}
playbackModel.isInUserQueue.observe(viewLifecycleOwner) { playbackModel.isInUserQueue.observe(viewLifecycleOwner) {
if (it) { if (it) {
detailAdapter.highlightSong(null, binding.detailRecycler) detailAdapter.highlightSong(null, binding.detailRecycler)

View file

@ -96,10 +96,6 @@ class GenreDetailFragment : DetailFragment() {
handlePlayingItem(detailAdapter) handlePlayingItem(detailAdapter)
} }
playbackModel.mode.observe(viewLifecycleOwner) {
handlePlayingItem(detailAdapter)
}
playbackModel.isInUserQueue.observe(viewLifecycleOwner) { playbackModel.isInUserQueue.observe(viewLifecycleOwner) {
if (it) { if (it) {
detailAdapter.highlightSong(null, binding.detailRecycler) detailAdapter.highlightSong(null, binding.detailRecycler)

View file

@ -14,6 +14,8 @@ import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.MainActivity import org.oxycblt.auxio.MainActivity
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.coil.getBitmap import org.oxycblt.auxio.coil.getBitmap
import org.oxycblt.auxio.logE
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.playback.state.PlaybackMode import org.oxycblt.auxio.playback.state.PlaybackMode
@ -47,7 +49,7 @@ fun NotificationManager.createMediaNotification(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel( val channel = NotificationChannel(
NotificationUtils.CHANNEL_ID, NotificationUtils.CHANNEL_ID,
context.getString(R.string.label_channel), context.getString(R.string.info_channel_name),
NotificationManager.IMPORTANCE_DEFAULT NotificationManager.IMPORTANCE_DEFAULT
) )
@ -155,7 +157,14 @@ fun NotificationCompat.Builder.updateMode(context: Context) {
if (playbackManager.mode == PlaybackMode.ALL_SONGS) { if (playbackManager.mode == PlaybackMode.ALL_SONGS) {
setSubText(context.getString(R.string.label_all_songs)) setSubText(context.getString(R.string.label_all_songs))
} else { } else {
setSubText(playbackManager.parent!!.name) val parent = playbackManager.parent
if (parent != null) {
setSubText(if (parent is Genre) parent.displayName else parent.name)
} else {
logE("Parent was null when it shouldnt have been.")
setSubText("")
}
} }
} }
} }

View file

@ -111,7 +111,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} }
} }
// TODO: Add binding adapters for these
playbackModel.isShuffling.observe(viewLifecycleOwner) { playbackModel.isShuffling.observe(viewLifecycleOwner) {
// Highlight the shuffle button if Playback is shuffled, and revert it if not. // Highlight the shuffle button if Playback is shuffled, and revert it if not.
if (it) { if (it) {

View file

@ -17,7 +17,6 @@ import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.SortMode import org.oxycblt.auxio.recycler.SortMode
import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.settings.SettingsManager
import kotlin.random.Random
/** /**
* Master class (and possible god object) for the playback state. * Master class (and possible god object) for the playback state.
@ -154,60 +153,44 @@ class PlaybackStateManager private constructor() {
fun playSong(song: Song, mode: PlaybackMode) { fun playSong(song: Song, mode: PlaybackMode) {
logD("Updating song to ${song.name} and mode to $mode") logD("Updating song to ${song.name} and mode to $mode")
// Song is updated immediately, as its reference is needed for the queue calculations
updatePlayback(song)
val shouldShuffle = settingsManager.keepShuffle && mIsShuffling val shouldShuffle = settingsManager.keepShuffle && mIsShuffling
when (mode) { when (mode) {
PlaybackMode.ALL_SONGS -> { PlaybackMode.ALL_SONGS -> {
mParent = null mParent = null
mQueue = musicStore.songs.toMutableList()
mQueue = if (shouldShuffle) {
genShuffle(musicStore.songs.toMutableList(), true)
} else {
musicStore.songs.toMutableList()
}
} }
PlaybackMode.IN_GENRE -> { PlaybackMode.IN_GENRE -> {
if (song.genre != null) { val genre = song.genre
mParent = song.genre
mQueue = if (shouldShuffle) { // Dont do this if the genre is null
genShuffle(song.genre!!.songs.toMutableList(), true) if (genre != null) {
} else { mParent = genre
orderSongsInGenre(song.genre!!) mQueue = genre.songs.toMutableList()
}
} else { } else {
// If there is no song, then just play the song from ALL_SONGS
playSong(song, PlaybackMode.ALL_SONGS) playSong(song, PlaybackMode.ALL_SONGS)
return return
} }
} }
PlaybackMode.IN_ARTIST -> { PlaybackMode.IN_ARTIST -> {
mParent = song.album.artist mParent = song.album.artist
mQueue = if (shouldShuffle) { mQueue = song.album.artist.songs.toMutableList()
genShuffle(song.album.artist.songs.toMutableList(), true)
} else {
orderSongsInArtist(song.album.artist)
}
} }
PlaybackMode.IN_ALBUM -> { PlaybackMode.IN_ALBUM -> {
mParent = song.album mParent = song.album
mQueue = if (shouldShuffle) { mQueue = song.album.songs.toMutableList()
genShuffle(song.album.songs.toMutableList(), true)
} else {
orderSongsInAlbum(song.album)
}
} }
} }
mMode = mode mMode = mode
mIsShuffling = shouldShuffle
resetLoopMode() resetLoopMode()
updatePlayback(song)
setShuffleStatus(shouldShuffle)
mIndex = mQueue.indexOf(song) mIndex = mQueue.indexOf(song)
} }
@ -233,30 +216,15 @@ class PlaybackStateManager private constructor() {
when (baseModel) { when (baseModel) {
is Album -> { is Album -> {
mQueue = if (mIsShuffling) { mQueue = orderSongsInAlbum(baseModel)
genShuffle(baseModel.songs.toMutableList(), false)
} else {
orderSongsInAlbum(baseModel)
}
mMode = PlaybackMode.IN_ALBUM mMode = PlaybackMode.IN_ALBUM
} }
is Artist -> { is Artist -> {
mQueue = if (mIsShuffling) { mQueue = orderSongsInArtist(baseModel)
genShuffle(baseModel.songs.toMutableList(), false)
} else {
orderSongsInArtist(baseModel)
}
mMode = PlaybackMode.IN_ARTIST mMode = PlaybackMode.IN_ARTIST
} }
is Genre -> { is Genre -> {
mQueue = if (mIsShuffling) { mQueue = orderSongsInGenre(baseModel)
genShuffle(baseModel.songs.toMutableList(), false)
} else {
orderSongsInGenre(baseModel)
}
mMode = PlaybackMode.IN_GENRE mMode = PlaybackMode.IN_GENRE
} }
@ -267,6 +235,12 @@ class PlaybackStateManager private constructor() {
resetLoopMode() resetLoopMode()
updatePlayback(mQueue[0]) updatePlayback(mQueue[0])
if (mIsShuffling) {
genShuffle(false)
} else {
resetShuffle()
}
} }
/** /**
@ -529,47 +503,42 @@ class PlaybackStateManager private constructor() {
* Shuffle all songs. * Shuffle all songs.
*/ */
fun shuffleAll() { fun shuffleAll() {
val musicStore = MusicStore.getInstance()
mIsShuffling = true mIsShuffling = true
mQueue = genShuffle(musicStore.songs.toMutableList(), false)
mMode = PlaybackMode.ALL_SONGS mMode = PlaybackMode.ALL_SONGS
mIndex = 0 mIndex = 0
mQueue = musicStore.songs.toMutableList()
genShuffle(false)
updatePlayback(mQueue[0]) updatePlayback(mQueue[0])
} }
/** /**
* Generate a new shuffled queue. * Generate a new shuffled queue.
* @param queueToShuffle The queue to shuffle
* @param keepSong Whether to keep the currently playing song or to dispose of it * @param keepSong Whether to keep the currently playing song or to dispose of it
* @param useLastSong (Optional, defaults to false) Whether to use the last song in the queue instead of the current one * @param useLastSong (Optional, defaults to false) Whether to use the last song in the queue instead of the current one
* @return A new shuffled queue * @return A new shuffled queue
*/ */
private fun genShuffle( private fun genShuffle(
queueToShuffle: MutableList<Song>,
keepSong: Boolean, keepSong: Boolean,
useLastSong: Boolean = false useLastSong: Boolean = false
): MutableList<Song> { ) {
val newSeed = Random.Default.nextLong()
val lastSong = if (useLastSong) mQueue[0] else mSong val lastSong = if (useLastSong) mQueue[0] else mSong
logD("Shuffling queue with seed $newSeed") logD("Shuffling queue")
queueToShuffle.shuffle(Random(newSeed)) mQueue.shuffle()
mIndex = 0 mIndex = 0
// If specified, make the current song the first member of the queue. // If specified, make the current song the first member of the queue.
if (keepSong) { if (keepSong) {
val song = queueToShuffle.removeAt(queueToShuffle.indexOf(lastSong)) moveQueueItems(mQueue.indexOf(lastSong), 0)
queueToShuffle.add(0, song)
} else { } else {
// Otherwise, just start from the zeroth position in the queue. // Otherwise, just start from the zeroth position in the queue.
mSong = queueToShuffle[0] mSong = mQueue[0]
} }
return queueToShuffle forceQueueUpdate()
} }
/** /**
@ -583,7 +552,7 @@ class PlaybackStateManager private constructor() {
PlaybackMode.IN_ARTIST -> orderSongsInArtist(mParent as Artist) PlaybackMode.IN_ARTIST -> orderSongsInArtist(mParent as Artist)
PlaybackMode.IN_ALBUM -> orderSongsInAlbum(mParent as Album) PlaybackMode.IN_ALBUM -> orderSongsInAlbum(mParent as Album)
PlaybackMode.IN_GENRE -> orderSongsInGenre(mParent as Genre) PlaybackMode.IN_GENRE -> orderSongsInGenre(mParent as Genre)
PlaybackMode.ALL_SONGS -> MusicStore.getInstance().songs.toMutableList() PlaybackMode.ALL_SONGS -> musicStore.songs.toMutableList()
} }
mIndex = mQueue.indexOf(lastSong) mIndex = mQueue.indexOf(lastSong)
@ -615,8 +584,7 @@ class PlaybackStateManager private constructor() {
mIsShuffling = value mIsShuffling = value
if (mIsShuffling) { if (mIsShuffling) {
mQueue = genShuffle( genShuffle(
mQueue,
keepSong = true, keepSong = true,
useLastSong = mIsInUserQueue useLastSong = mIsInUserQueue
) )
@ -743,8 +711,6 @@ class PlaybackStateManager private constructor() {
* @param playbackState The state to unpack. * @param playbackState The state to unpack.
*/ */
private fun unpackFromPlaybackState(playbackState: PlaybackState) { private fun unpackFromPlaybackState(playbackState: PlaybackState) {
val musicStore = MusicStore.getInstance()
// Turn the simplified information from PlaybackState into values that can be used // Turn the simplified information from PlaybackState into values that can be used
mSong = musicStore.songs.find { it.name == playbackState.songName } mSong = musicStore.songs.find { it.name == playbackState.songName }
mPosition = playbackState.position mPosition = playbackState.position
@ -789,8 +755,6 @@ class PlaybackStateManager private constructor() {
* @param queueItems The list of [QueueItem]s to unpack. * @param queueItems The list of [QueueItem]s to unpack.
*/ */
private fun unpackQueue(queueItems: List<QueueItem>) { private fun unpackQueue(queueItems: List<QueueItem>) {
val musicStore = MusicStore.getInstance()
queueItems.forEach { item -> queueItems.forEach { item ->
// Traverse albums and then album songs instead of just the songs, as its faster. // Traverse albums and then album songs instead of just the songs, as its faster.
musicStore.albums.find { it.name == item.albumName } musicStore.albums.find { it.name == item.albumName }

View file

@ -34,7 +34,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:fontFamily="@font/inter_semibold" android:fontFamily="@font/inter_semibold"
android:text="@string/app_name" android:text="@string/info_app_name"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5" android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
app:layout_constraintBottom_toBottomOf="@+id/about_auxio_icon" app:layout_constraintBottom_toBottomOf="@+id/about_auxio_icon"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
@ -49,7 +49,7 @@
android:layout_marginTop="@dimen/margin_small" android:layout_marginTop="@dimen/margin_small"
android:paddingStart="@dimen/padding_small" android:paddingStart="@dimen/padding_small"
android:paddingEnd="@dimen/padding_small" android:paddingEnd="@dimen/padding_small"
android:text="@string/app_desc" android:text="@string/info_app_desc"
android:textAlignment="center" android:textAlignment="center"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Auxio</string> <!-- Info namespace | App labels -->
<string name="app_desc">A sensible and customizable music player for android.</string> <string name="info_app_name">Auxio</string>
<string name="info_app_desc">A sensible and customizable music player for android.</string>
<string name="info_channel_name">Music Playback</string>
<string name="info_service_desc">The music playback service for Auxio.</string>
<!-- Label Namespace | Static Labels --> <!-- Label Namespace | Static Labels -->
<string name="label_retry">Retry</string> <string name="label_retry">Retry</string>
@ -39,10 +42,7 @@
<string name="label_queue_add">Add to queue</string> <string name="label_queue_add">Add to queue</string>
<string name="label_queue_added">Added to queue</string> <string name="label_queue_added">Added to queue</string>
<string name="label_next_user_queue">Next in Queue</string> <string name="label_next_user_queue">Next in Queue</string>
<string name="label_channel">Music Playback</string>
<string name="label_service_playback">The music playback service for Auxio.</string>
<string name="label_about">About</string> <string name="label_about">About</string>
<string name="label_version">Version</string> <string name="label_version">Version</string>
<string name="label_code">View on Github</string> <string name="label_code">View on Github</string>