playback: fix more gapless issues
This commit is contained in:
parent
26d14ec6e1
commit
d5622895d0
3 changed files with 25 additions and 12 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 ---
|
||||||
|
|
Loading…
Reference in a new issue