make shuffle and repeatmode work
This commit is contained in:
parent
c0a006f238
commit
9a71e8f0b5
|
@ -53,6 +53,12 @@ enum class PlayMode {
|
|||
AUDIO_FOREGROUND,
|
||||
}
|
||||
|
||||
enum class RepeatMode {
|
||||
DONT_REPEAT,
|
||||
REPEAT_ALL,
|
||||
REPEAT_ONE
|
||||
}
|
||||
|
||||
private val TAG = "NewPlayer"
|
||||
|
||||
interface NewPlayer {
|
||||
|
@ -68,6 +74,8 @@ interface NewPlayer {
|
|||
var fastSeekAmountSec: Int
|
||||
var playBackMode: PlayMode
|
||||
var playMode: StateFlow<PlayMode?>
|
||||
var shuffle: Boolean
|
||||
var repeatMode: RepeatMode
|
||||
|
||||
val playlist: StateFlow<List<PlaylistItem>>
|
||||
|
||||
|
@ -154,6 +162,27 @@ class NewPlayerImpl(
|
|||
var mutablePlayMode = MutableStateFlow<PlayMode?>(null)
|
||||
override var playMode = mutablePlayMode.asStateFlow()
|
||||
|
||||
override var shuffle: Boolean
|
||||
get() = internalPlayer.shuffleModeEnabled
|
||||
set(value) {
|
||||
internalPlayer.shuffleModeEnabled = value
|
||||
}
|
||||
|
||||
override var repeatMode: RepeatMode
|
||||
get() = when(internalPlayer.repeatMode) {
|
||||
Player.REPEAT_MODE_OFF -> RepeatMode.DONT_REPEAT
|
||||
Player.REPEAT_MODE_ALL -> RepeatMode.REPEAT_ALL
|
||||
Player.REPEAT_MODE_ONE -> RepeatMode.REPEAT_ONE
|
||||
else -> throw NewPlayerException("Unknown Repeatmode option returned by ExoPlayer: ${internalPlayer.repeatMode}")
|
||||
}
|
||||
set(value) {
|
||||
when(value) {
|
||||
RepeatMode.DONT_REPEAT -> internalPlayer.repeatMode = Player.REPEAT_MODE_OFF
|
||||
RepeatMode.REPEAT_ALL -> internalPlayer.repeatMode = Player.REPEAT_MODE_ALL
|
||||
RepeatMode.REPEAT_ONE -> internalPlayer.repeatMode = Player.REPEAT_MODE_ONE
|
||||
}
|
||||
}
|
||||
|
||||
var mutableOnEvent = MutableSharedFlow<Pair<Player, Player.Events>>()
|
||||
override val onExoPlayerEvent: SharedFlow<Pair<Player, Player.Events>> =
|
||||
mutableOnEvent.asSharedFlow()
|
||||
|
|
|
@ -22,6 +22,7 @@ package net.newpipe.newplayer.model
|
|||
|
||||
import androidx.media3.common.Player
|
||||
import net.newpipe.newplayer.Chapter
|
||||
import net.newpipe.newplayer.RepeatMode
|
||||
import net.newpipe.newplayer.playerInternals.PlaylistItem
|
||||
import net.newpipe.newplayer.ui.ContentScale
|
||||
|
||||
|
@ -43,7 +44,7 @@ data class VideoPlayerUIState(
|
|||
val playList: List<PlaylistItem>,
|
||||
val chapters: List<Chapter>,
|
||||
val shuffleEnabled: Boolean,
|
||||
val repeatMode: Int,
|
||||
val repeatMode: RepeatMode,
|
||||
val playListDurationInS: Int
|
||||
) {
|
||||
companion object {
|
||||
|
@ -68,7 +69,7 @@ data class VideoPlayerUIState(
|
|||
playList = emptyList(),
|
||||
chapters = emptyList(),
|
||||
shuffleEnabled = false,
|
||||
repeatMode = Player.REPEAT_MODE_OFF,
|
||||
repeatMode = RepeatMode.DONT_REPEAT,
|
||||
playListDurationInS = 0
|
||||
)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.SharedFlow
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
import net.newpipe.newplayer.Chapter
|
||||
import net.newpipe.newplayer.NewPlayer
|
||||
import net.newpipe.newplayer.RepeatMode
|
||||
import net.newpipe.newplayer.ui.ContentScale
|
||||
import net.newpipe.newplayer.utils.Thumbnail
|
||||
|
||||
|
@ -60,8 +61,8 @@ interface VideoPlayerViewModel {
|
|||
fun closeStreamSelection()
|
||||
fun chapterSelected(chapter: Chapter)
|
||||
fun streamSelected(streamId: Int)
|
||||
fun setRepeatmode(repeatMode: Int)
|
||||
fun setSuffleEnabled(enabled: Boolean)
|
||||
fun cycleRepeatmode()
|
||||
fun toggleShuffle()
|
||||
fun onStorePlaylist()
|
||||
fun movePlaylistItem(from: Int, to: Int)
|
||||
fun removePlaylistItem(index: Int)
|
||||
|
|
|
@ -45,6 +45,7 @@ import kotlinx.coroutines.launch
|
|||
import net.newpipe.newplayer.Chapter
|
||||
import net.newpipe.newplayer.utils.VideoSize
|
||||
import net.newpipe.newplayer.NewPlayer
|
||||
import net.newpipe.newplayer.RepeatMode
|
||||
import net.newpipe.newplayer.ui.ContentScale
|
||||
import java.util.LinkedList
|
||||
|
||||
|
@ -132,7 +133,8 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
override val onBackPressed: SharedFlow<Unit> = mutableOnBackPressed.asSharedFlow()
|
||||
|
||||
private fun installNewPlayer() {
|
||||
newPlayer?.internalPlayer?.let { player ->
|
||||
newPlayer?.let { newPlayer ->
|
||||
val player = newPlayer.internalPlayer
|
||||
Log.d(TAG, "Install player: ${player.videoSize.width}")
|
||||
|
||||
player.addListener(object : Player.Listener {
|
||||
|
@ -157,6 +159,20 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
it.copy(isLoading = isLoading)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||
super.onRepeatModeChanged(repeatMode)
|
||||
mutableUiState.update {
|
||||
it.copy(repeatMode = newPlayer.repeatMode)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||
super.onShuffleModeEnabledChanged(shuffleModeEnabled)
|
||||
mutableUiState.update {
|
||||
it.copy(shuffleEnabled = newPlayer.shuffle)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
newPlayer?.let { newPlayer ->
|
||||
|
@ -406,19 +422,20 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
println("stream selected: $streamId")
|
||||
}
|
||||
|
||||
override fun setRepeatmode(repeatMode: Int) {
|
||||
assert(
|
||||
repeatMode == Player.REPEAT_MODE_ALL
|
||||
|| repeatMode == Player.REPEAT_MODE_OFF
|
||||
|| repeatMode == Player.REPEAT_MODE_ONE
|
||||
) {
|
||||
"Illegal repeat mode: $repeatMode"
|
||||
override fun cycleRepeatmode() {
|
||||
newPlayer?.let {
|
||||
it.repeatMode = when (it.repeatMode) {
|
||||
RepeatMode.DONT_REPEAT -> RepeatMode.REPEAT_ALL
|
||||
RepeatMode.REPEAT_ALL -> RepeatMode.REPEAT_ONE
|
||||
RepeatMode.REPEAT_ONE -> RepeatMode.DONT_REPEAT
|
||||
}
|
||||
}
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun setSuffleEnabled(enabled: Boolean) {
|
||||
TODO("Not yet implemented")
|
||||
override fun toggleShuffle() {
|
||||
newPlayer?.let {
|
||||
it.shuffle = !it.shuffle
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStorePlaylist() {
|
||||
|
@ -426,7 +443,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
}
|
||||
|
||||
override fun movePlaylistItem(from: Int, to: Int) {
|
||||
if(playlistItemToBeMoved == null) {
|
||||
if (playlistItemToBeMoved == null) {
|
||||
playlistItemToBeMoved = from
|
||||
}
|
||||
playlistItemNewPosition = to
|
||||
|
@ -453,7 +470,6 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
}
|
||||
|
||||
|
||||
|
||||
private fun updateUiMode(newState: UIModeState) {
|
||||
val newPlayMode = newState.toPlayMode()
|
||||
val currentPlayMode = mutableUiState.value.uiMode.toPlayMode()
|
||||
|
|
|
@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.SharedFlow
|
|||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import net.newpipe.newplayer.Chapter
|
||||
import net.newpipe.newplayer.NewPlayer
|
||||
import net.newpipe.newplayer.RepeatMode
|
||||
import net.newpipe.newplayer.ui.ContentScale
|
||||
|
||||
open class VideoPlayerViewModelDummy : VideoPlayerViewModel {
|
||||
|
@ -91,12 +92,12 @@ open class VideoPlayerViewModelDummy : VideoPlayerViewModel {
|
|||
println("dummy impl stream selected: $streamId")
|
||||
}
|
||||
|
||||
override fun setRepeatmode(repeatMode: Int) {
|
||||
println("dummy impl repeat mode: $repeatMode")
|
||||
override fun cycleRepeatmode() {
|
||||
println("dummy impl")
|
||||
}
|
||||
|
||||
override fun setSuffleEnabled(enabled: Boolean) {
|
||||
println("dummy impl shuffle enabled: $enabled")
|
||||
override fun toggleShuffle() {
|
||||
println("dummy impl")
|
||||
}
|
||||
|
||||
override fun onStorePlaylist() {
|
||||
|
|
|
@ -46,6 +46,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.media3.common.Player
|
||||
import net.newpipe.newplayer.NewPlayerException
|
||||
import net.newpipe.newplayer.R
|
||||
import net.newpipe.newplayer.RepeatMode
|
||||
import net.newpipe.newplayer.model.VideoPlayerUIState
|
||||
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||
import net.newpipe.newplayer.model.VideoPlayerViewModelDummy
|
||||
|
@ -75,41 +76,28 @@ fun StreamSelectTopBar(
|
|||
)
|
||||
}, actions = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
viewModel.setRepeatmode(
|
||||
when (uiState.repeatMode) {
|
||||
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ALL
|
||||
Player.REPEAT_MODE_ALL -> Player.REPEAT_MODE_ONE
|
||||
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_OFF
|
||||
else -> throw NewPlayerException("Unknown repeat mode: ${uiState.repeatMode}")
|
||||
}
|
||||
)
|
||||
}
|
||||
onClick = viewModel::cycleRepeatmode
|
||||
) {
|
||||
when (uiState.repeatMode) {
|
||||
Player.REPEAT_MODE_OFF -> Icon(
|
||||
RepeatMode.DONT_REPEAT -> Icon(
|
||||
imageVector = Icons.Filled.Repeat,
|
||||
contentDescription = stringResource(R.string.repeat_mode_no_repeat)
|
||||
)
|
||||
|
||||
Player.REPEAT_MODE_ALL -> Icon(
|
||||
RepeatMode.REPEAT_ALL -> Icon(
|
||||
imageVector = Icons.Filled.RepeatOn,
|
||||
contentDescription = stringResource(R.string.repeat_mode_repeat_all)
|
||||
)
|
||||
|
||||
Player.REPEAT_MODE_ONE -> Icon(
|
||||
RepeatMode.REPEAT_ONE -> Icon(
|
||||
imageVector = Icons.Filled.RepeatOneOn,
|
||||
contentDescription = stringResource(R.string.repeat_mode_repeat_all)
|
||||
)
|
||||
|
||||
else -> throw NewPlayerException("Unknown repeat mode: ${uiState.repeatMode}")
|
||||
}
|
||||
}
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
viewModel.setSuffleEnabled(!uiState.shuffleEnabled)
|
||||
}
|
||||
onClick = viewModel::toggleShuffle
|
||||
) {
|
||||
if (uiState.shuffleEnabled) {
|
||||
Icon(
|
||||
|
|
Loading…
Reference in New Issue