playback: fix more gapless issues

This commit is contained in:
Alexander Capehart 2024-01-09 13:49:00 -07:00
parent 26d14ec6e1
commit d5622895d0
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 25 additions and 12 deletions

View file

@ -63,6 +63,10 @@ class BetterShuffleOrder private constructor(private val shuffled: IntArray) : S
} }
override fun cloneAndInsert(insertionIndex: Int, insertionCount: Int): ShuffleOrder { override fun cloneAndInsert(insertionIndex: Int, insertionCount: Int): ShuffleOrder {
if (shuffled.isEmpty()) {
return BetterShuffleOrder(insertionCount, -1)
}
val newShuffled = IntArray(shuffled.size + insertionCount) val newShuffled = IntArray(shuffled.size + insertionCount)
val pivot = indexInShuffled[insertionIndex] val pivot = indexInShuffled[insertionIndex]
for (i in shuffled.indices) { for (i in shuffled.indices) {

View file

@ -22,7 +22,6 @@ import androidx.media3.common.C
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.common.Player import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.ShuffleOrder.DefaultShuffleOrder
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
@ -33,8 +32,8 @@ val ExoPlayer.song
fun ExoPlayer.orderedQueue(queue: Collection<Song>, start: Song?) { fun ExoPlayer.orderedQueue(queue: Collection<Song>, start: Song?) {
clearMediaItems() clearMediaItems()
shuffleModeEnabled = false shuffleModeEnabled = false
setShuffleOrder(DefaultShuffleOrder(mediaItemCount))
setMediaItems(queue.map { it.toMediaItem() }) setMediaItems(queue.map { it.toMediaItem() })
if (start != null) {
val startIndex = queue.indexOf(start) val startIndex = queue.indexOf(start)
if (startIndex != -1) { if (startIndex != -1) {
seekTo(startIndex, C.TIME_UNSET) seekTo(startIndex, C.TIME_UNSET)
@ -42,13 +41,13 @@ fun ExoPlayer.orderedQueue(queue: Collection<Song>, start: Song?) {
throw IllegalArgumentException("Start song not in queue") throw IllegalArgumentException("Start song not in queue")
} }
} }
}
fun ExoPlayer.shuffledQueue(queue: Collection<Song>, start: Song?) { fun ExoPlayer.shuffledQueue(queue: Collection<Song>, start: Song?) {
// A fun thing about ShuffleOrder is that ExoPlayer will use cloneAndInsert to both add // A fun thing about ShuffleOrder is that ExoPlayer will use cloneAndInsert to both add
// MediaItems AND repopulate MediaItems (?!?!?!?!). As a result, we have to use the default // MediaItems AND repopulate MediaItems (?!?!?!?!). As a result, we have to use the default
// shuffle order and it's stupid cloneAndInsert implementation to add the songs, and then // shuffle order and it's stupid cloneAndInsert implementation to add the songs, and then
// switch back to our implementation that actually works in normal use. // switch back to our implementation that actually works in normal use.
setShuffleOrder(DefaultShuffleOrder(mediaItemCount))
setMediaItems(queue.map { it.toMediaItem() }) setMediaItems(queue.map { it.toMediaItem() })
shuffleModeEnabled = true shuffleModeEnabled = true
val startIndex = val startIndex =
@ -82,11 +81,11 @@ val ExoPlayer.repeat: RepeatMode
fun ExoPlayer.reorder(shuffled: Boolean) { fun ExoPlayer.reorder(shuffled: Boolean) {
logD("Reordering queue to $shuffled") logD("Reordering queue to $shuffled")
shuffleModeEnabled = shuffled
if (shuffled) { if (shuffled) {
// Have to manually refresh the shuffle seed. // Have to manually refresh the shuffle seed.
setShuffleOrder(BetterShuffleOrder(mediaItemCount, currentMediaItemIndex)) setShuffleOrder(BetterShuffleOrder(mediaItemCount, currentMediaItemIndex))
} }
shuffleModeEnabled = shuffled
} }
fun ExoPlayer.playNext(songs: List<Song>) { fun ExoPlayer.playNext(songs: List<Song>) {
@ -115,7 +114,17 @@ fun ExoPlayer.move(from: Int, to: Int) {
val trueFrom = queue[from] val trueFrom = queue[from]
val trueTo = queue[to] val trueTo = queue[to]
when {
trueFrom > trueTo -> {
moveMediaItem(trueFrom, trueTo) moveMediaItem(trueFrom, trueTo)
moveMediaItem(trueTo + 1, trueFrom)
}
trueTo > trueFrom -> {
moveMediaItem(trueFrom, trueTo)
moveMediaItem(trueTo - 1, trueFrom)
}
}
} }
fun ExoPlayer.remove(at: Int) { fun ExoPlayer.remove(at: Int) {

View file

@ -363,7 +363,7 @@ class PlaybackService :
"Inconsistency detected: Player does not have song despite being populated" "Inconsistency detected: Player does not have song despite being populated"
}, },
Queue(player.currentIndex, player.resolveQueue()), Queue(player.currentIndex, player.resolveQueue()),
QueueChange(changeType, UpdateInstructions.Diff))) QueueChange(changeType, UpdateInstructions.Move(from, to))))
} }
override fun remove(at: Int) { override fun remove(at: Int) {
@ -386,7 +386,7 @@ class PlaybackService :
"Inconsistency detected: Player does not have song despite being populated" "Inconsistency detected: Player does not have song despite being populated"
}, },
Queue(player.currentIndex, player.resolveQueue()), Queue(player.currentIndex, player.resolveQueue()),
QueueChange(changeType, UpdateInstructions.Diff))) QueueChange(changeType, UpdateInstructions.Remove(at, 1))))
} }
// --- PLAYER OVERRIDES --- // --- PLAYER OVERRIDES ---