mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-11-04 10:13:59 +00:00
fix(audio-player): android shuffle wasnt working
This commit is contained in:
parent
da394d40ea
commit
c9d16a25c6
@ -84,6 +84,8 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
private var disposed = false
|
private var disposed = false
|
||||||
|
|
||||||
private val currentPlaylist = mutableListOf<MediaItem>()
|
private val currentPlaylist = mutableListOf<MediaItem>()
|
||||||
|
private val originalPlaylist = mutableListOf<MediaItem>()
|
||||||
|
private var shuffleEnabled = false
|
||||||
private val urlIndexMap = mutableMapOf<String, Int>()
|
private val urlIndexMap = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
private val _playerState = MutableStateFlow(PlayerState.IDLE)
|
private val _playerState = MutableStateFlow(PlayerState.IDLE)
|
||||||
@ -143,10 +145,6 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
|
||||||
_shuffleMode.tryEmit(shuffleModeEnabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onVolumeChanged(volume: Float) {
|
override fun onVolumeChanged(volume: Float) {
|
||||||
_volume.tryEmit(volume)
|
_volume.tryEmit(volume)
|
||||||
}
|
}
|
||||||
@ -260,8 +258,37 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
|
|
||||||
actual override suspend fun shuffle(enabled: Boolean) {
|
actual override suspend fun shuffle(enabled: Boolean) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
exoPlayer.shuffleModeEnabled = enabled
|
if (disposed || currentPlaylist.isEmpty() || shuffleEnabled == enabled) return@withContext
|
||||||
|
|
||||||
|
val currentIndex = exoPlayer.currentMediaItemIndex
|
||||||
|
val current = currentPlaylist.getOrNull(currentIndex) ?: return@withContext
|
||||||
|
|
||||||
|
val rest = if (enabled) {
|
||||||
|
originalPlaylist.filterNot { it.url == current.url }.shuffled()
|
||||||
|
} else {
|
||||||
|
originalPlaylist.filterNot { it.url == current.url }
|
||||||
|
}
|
||||||
|
// Disabling restores original order around the current item.
|
||||||
|
val before = if (enabled) emptyList() else originalPlaylist.takeWhile { it.url != current.url }
|
||||||
|
val after = if (enabled) rest else originalPlaylist.dropWhile { it.url != current.url }.drop(1)
|
||||||
|
|
||||||
|
// Reorder in place around the playing item so playback is not interrupted.
|
||||||
|
if (currentIndex < exoPlayer.mediaItemCount - 1) {
|
||||||
|
exoPlayer.removeMediaItems(currentIndex + 1, exoPlayer.mediaItemCount)
|
||||||
|
}
|
||||||
|
if (currentIndex > 0) exoPlayer.removeMediaItems(0, currentIndex)
|
||||||
|
exoPlayer.addMediaItems(0, before.map { it.toExoMediaItem() })
|
||||||
|
exoPlayer.addMediaItems(after.map { it.toExoMediaItem() })
|
||||||
|
|
||||||
|
currentPlaylist.clear()
|
||||||
|
currentPlaylist.addAll(before + current + after)
|
||||||
|
urlIndexMap.clear()
|
||||||
|
currentPlaylist.forEachIndexed { i, item -> urlIndexMap[item.url] = i }
|
||||||
|
|
||||||
|
shuffleEnabled = enabled
|
||||||
_shuffleMode.tryEmit(enabled)
|
_shuffleMode.tryEmit(enabled)
|
||||||
|
_playlist.tryEmit(currentPlaylist.toList())
|
||||||
|
syncCurrentItem()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +300,10 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
currentPlaylist.clear()
|
currentPlaylist.clear()
|
||||||
currentPlaylist.addAll(playlist)
|
currentPlaylist.addAll(playlist)
|
||||||
|
originalPlaylist.clear()
|
||||||
|
originalPlaylist.addAll(playlist)
|
||||||
|
shuffleEnabled = false
|
||||||
|
_shuffleMode.tryEmit(false)
|
||||||
urlIndexMap.clear()
|
urlIndexMap.clear()
|
||||||
playlist.forEachIndexed { index, item ->
|
playlist.forEachIndexed { index, item ->
|
||||||
urlIndexMap[item.url] = index
|
urlIndexMap[item.url] = index
|
||||||
@ -305,6 +336,7 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
actual override suspend fun addMediaItem(mediaItem: MediaItem) {
|
actual override suspend fun addMediaItem(mediaItem: MediaItem) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
currentPlaylist.add(mediaItem)
|
currentPlaylist.add(mediaItem)
|
||||||
|
originalPlaylist.add(mediaItem)
|
||||||
urlIndexMap[mediaItem.url] = currentPlaylist.lastIndex
|
urlIndexMap[mediaItem.url] = currentPlaylist.lastIndex
|
||||||
_playlist.tryEmit(currentPlaylist.toList())
|
_playlist.tryEmit(currentPlaylist.toList())
|
||||||
exoPlayer.addMediaItem(mediaItem.toExoMediaItem())
|
exoPlayer.addMediaItem(mediaItem.toExoMediaItem())
|
||||||
@ -317,6 +349,8 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
val insertIndex = (currentIndex + 1).coerceAtMost(currentPlaylist.size)
|
val insertIndex = (currentIndex + 1).coerceAtMost(currentPlaylist.size)
|
||||||
|
|
||||||
currentPlaylist.add(insertIndex, mediaItem)
|
currentPlaylist.add(insertIndex, mediaItem)
|
||||||
|
val origCurrent = currentPlaylist.getOrNull(currentIndex)?.let { c -> originalPlaylist.indexOfFirst { it.url == c.url } } ?: -1
|
||||||
|
originalPlaylist.add((origCurrent + 1).coerceIn(0, originalPlaylist.size), mediaItem)
|
||||||
urlIndexMap.clear()
|
urlIndexMap.clear()
|
||||||
currentPlaylist.forEachIndexed { index, item ->
|
currentPlaylist.forEachIndexed { index, item ->
|
||||||
urlIndexMap[item.url] = index
|
urlIndexMap[item.url] = index
|
||||||
@ -331,6 +365,7 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
val index = urlIndexMap[mediaItem.url] ?: return@withContext
|
val index = urlIndexMap[mediaItem.url] ?: return@withContext
|
||||||
currentPlaylist.removeAt(index)
|
currentPlaylist.removeAt(index)
|
||||||
|
originalPlaylist.removeAll { it.url == mediaItem.url }
|
||||||
urlIndexMap.clear()
|
urlIndexMap.clear()
|
||||||
currentPlaylist.forEachIndexed { i, item ->
|
currentPlaylist.forEachIndexed { i, item ->
|
||||||
urlIndexMap[item.url] = i
|
urlIndexMap[item.url] = i
|
||||||
@ -346,6 +381,9 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
|
|
||||||
val item = currentPlaylist.removeAt(fromIndex)
|
val item = currentPlaylist.removeAt(fromIndex)
|
||||||
currentPlaylist.add(toIndex, item)
|
currentPlaylist.add(toIndex, item)
|
||||||
|
if (!shuffleEnabled && fromIndex in originalPlaylist.indices && toIndex in originalPlaylist.indices) {
|
||||||
|
originalPlaylist.add(toIndex, originalPlaylist.removeAt(fromIndex))
|
||||||
|
}
|
||||||
urlIndexMap.clear()
|
urlIndexMap.clear()
|
||||||
currentPlaylist.forEachIndexed { i, it ->
|
currentPlaylist.forEachIndexed { i, it ->
|
||||||
urlIndexMap[it.url] = i
|
urlIndexMap[it.url] = i
|
||||||
@ -398,6 +436,7 @@ actual class AudioPlayer actual constructor(context: Any) : AudioPlayerInterface
|
|||||||
disposed = true
|
disposed = true
|
||||||
exoPlayer.release()
|
exoPlayer.release()
|
||||||
currentPlaylist.clear()
|
currentPlaylist.clear()
|
||||||
|
originalPlaylist.clear()
|
||||||
urlIndexMap.clear()
|
urlIndexMap.clear()
|
||||||
|
|
||||||
_playerState.tryEmit(PlayerState.IDLE)
|
_playerState.tryEmit(PlayerState.IDLE)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user