make goto next or prev streem buttons work
This commit is contained in:
parent
106060625c
commit
58e0ad9f09
|
@ -79,6 +79,7 @@ interface NewPlayer {
|
|||
|
||||
val playlist: StateFlow<List<PlaylistItem>>
|
||||
val currentlyPlaying: StateFlow<PlaylistItem?>
|
||||
var currentlyPlayingPlaylistItem: Int
|
||||
|
||||
val currentChapters: StateFlow<List<Chapter>>
|
||||
|
||||
|
@ -96,7 +97,6 @@ interface NewPlayer {
|
|||
fun removePlaylistItem(index: Int)
|
||||
fun playStream(item: String, playMode: PlayMode)
|
||||
fun selectChapter(index: Int)
|
||||
fun selectPlaylistItem(index: Int)
|
||||
fun playStream(item: String, streamVariant: String, playMode: PlayMode)
|
||||
|
||||
data class Builder(val app: Application, val repository: MediaRepository) {
|
||||
|
@ -209,6 +209,15 @@ class NewPlayerImpl(
|
|||
private val mutableCurrentChapter = MutableStateFlow<List<Chapter>>(emptyList())
|
||||
override val currentChapters: StateFlow<List<Chapter>> = mutableCurrentChapter.asStateFlow()
|
||||
|
||||
override var currentlyPlayingPlaylistItem: Int
|
||||
get() = internalPlayer.currentMediaItemIndex
|
||||
set(value) {
|
||||
assert(value in 0..<playlist.value.size) {
|
||||
throw NewPlayerException("Playlist item selection out of bound: selected item index: $value, available chapters: ${playlist.value.size}")
|
||||
}
|
||||
internalPlayer.seekTo(value, 0)
|
||||
}
|
||||
|
||||
init {
|
||||
internalPlayer.addListener(object : Player.Listener {
|
||||
override fun onPlayerError(error: PlaybackException) {
|
||||
|
@ -349,13 +358,6 @@ class NewPlayerImpl(
|
|||
currentPosition = chapter.chapterStartInMs
|
||||
}
|
||||
|
||||
override fun selectPlaylistItem(index: Int) {
|
||||
assert(index in 0..<playlist.value.size) {
|
||||
throw NewPlayerException("Playlist item selection out of bound: selected item index: $index, available chapters: ${playlist.value.size}")
|
||||
}
|
||||
internalPlayer.seekTo(index, 0)
|
||||
}
|
||||
|
||||
private fun internalPlayStream(mediaItem: MediaItem, playMode: PlayMode) {
|
||||
if (internalPlayer.playbackState == Player.STATE_IDLE) {
|
||||
internalPlayer.prepare()
|
||||
|
|
|
@ -46,7 +46,8 @@ data class VideoPlayerUIState(
|
|||
val shuffleEnabled: Boolean,
|
||||
val repeatMode: RepeatMode,
|
||||
val playListDurationInS: Int,
|
||||
val currentlyPlaying: PlaylistItem
|
||||
val currentlyPlaying: PlaylistItem,
|
||||
val currentPlaylistItemIndex: Int
|
||||
) {
|
||||
companion object {
|
||||
val DEFAULT = VideoPlayerUIState(
|
||||
|
@ -70,7 +71,8 @@ data class VideoPlayerUIState(
|
|||
shuffleEnabled = false,
|
||||
repeatMode = RepeatMode.DONT_REPEAT,
|
||||
playListDurationInS = 0,
|
||||
currentlyPlaying = PlaylistItem.DEFAULT
|
||||
currentlyPlaying = PlaylistItem.DEFAULT,
|
||||
currentPlaylistItemIndex = 0
|
||||
)
|
||||
|
||||
val DUMMY = DEFAULT.copy(
|
||||
|
@ -87,7 +89,51 @@ data class VideoPlayerUIState(
|
|||
brightness = 0.2f,
|
||||
shuffleEnabled = true,
|
||||
playListDurationInS = 5493,
|
||||
currentlyPlaying = PlaylistItem.DUMMY
|
||||
currentlyPlaying = PlaylistItem.DUMMY,
|
||||
currentPlaylistItemIndex = 1,
|
||||
chapters = arrayListOf(
|
||||
Chapter(
|
||||
chapterStartInMs = 5000,
|
||||
chapterTitle = "First Chapter",
|
||||
thumbnail = null
|
||||
),
|
||||
Chapter(
|
||||
chapterStartInMs = 10000,
|
||||
chapterTitle = "Second Chapter",
|
||||
thumbnail = null
|
||||
),
|
||||
Chapter(
|
||||
chapterStartInMs = 20000,
|
||||
chapterTitle = "Third Chapter",
|
||||
thumbnail = null
|
||||
)
|
||||
),
|
||||
playList = arrayListOf(
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 1",
|
||||
creator = "The Creator",
|
||||
lengthInS = 6 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 0
|
||||
),
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 2",
|
||||
creator = "The Creator 2",
|
||||
lengthInS = 2 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 1
|
||||
),
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 3",
|
||||
creator = "The Creator 3",
|
||||
lengthInS = 29 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 2
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ import androidx.core.content.ContextCompat.getSystemService
|
|||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -42,7 +43,6 @@ import javax.inject.Inject
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
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
|
||||
|
@ -194,13 +194,20 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
}
|
||||
viewModelScope.launch {
|
||||
newPlayer.playlist.collect { playlist ->
|
||||
mutableUiState.update { it.copy(playList = playlist) }
|
||||
mutableUiState.update {
|
||||
it.copy(
|
||||
playList = playlist,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
newPlayer.currentlyPlaying.collect { playlistItem ->
|
||||
mutableUiState.update {
|
||||
it.copy(currentlyPlaying = playlistItem ?: PlaylistItem.DEFAULT)
|
||||
it.copy(
|
||||
currentlyPlaying = playlistItem ?: PlaylistItem.DEFAULT,
|
||||
currentPlaylistItemIndex = newPlayer.currentlyPlayingPlaylistItem
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,12 +268,20 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
|
||||
override fun prevStream() {
|
||||
resetHideUiDelayedJob()
|
||||
Log.e(TAG, "imeplement prev stream")
|
||||
newPlayer?.let { newPlayer ->
|
||||
if (0 <= newPlayer.currentlyPlayingPlaylistItem - 1) {
|
||||
newPlayer.currentlyPlayingPlaylistItem -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun nextStream() {
|
||||
resetHideUiDelayedJob()
|
||||
Log.e(TAG, "implement next stream")
|
||||
newPlayer?.let { newPlayer ->
|
||||
if (newPlayer.currentlyPlayingPlaylistItem + 1 < newPlayer.internalPlayer.mediaItemCount) {
|
||||
newPlayer.currentlyPlayingPlaylistItem += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun showUi() {
|
||||
|
@ -427,7 +442,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
if (selectChapter) uiState.value.uiMode.getChapterSelectUiState()
|
||||
else uiState.value.uiMode.getStreamSelectUiState()
|
||||
)
|
||||
if(selectChapter) {
|
||||
if (selectChapter) {
|
||||
resetProgressUpdatePeriodicallyJob()
|
||||
} else {
|
||||
resetPlaylistProgressUpdaterJob()
|
||||
|
@ -468,8 +483,7 @@ class VideoPlayerViewModelImpl @Inject constructor(
|
|||
}
|
||||
|
||||
override fun streamSelected(streamId: Int) {
|
||||
println("gurken stream selected: $streamId")
|
||||
newPlayer?.selectPlaylistItem(streamId)
|
||||
newPlayer?.currentlyPlayingPlaylistItem = streamId
|
||||
}
|
||||
|
||||
override fun cycleRepeatMode() {
|
||||
|
|
|
@ -21,9 +21,15 @@
|
|||
package net.newpipe.newplayer.ui.videoplayer
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Pause
|
||||
|
@ -33,6 +39,7 @@ import androidx.compose.material.icons.filled.SkipPrevious
|
|||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
|
@ -60,13 +67,22 @@ fun CenterUI(
|
|||
modifier = modifier,
|
||||
) {
|
||||
|
||||
CenterControllButton(
|
||||
buttonModifier = Modifier.size(80.dp),
|
||||
iconModifier = Modifier.size(40.dp),
|
||||
icon = Icons.Filled.SkipPrevious,
|
||||
contentDescription = stringResource(R.string.widget_description_previous_stream),
|
||||
onClick = viewModel::prevStream
|
||||
)
|
||||
Box(modifier = Modifier.size(80.dp)) {
|
||||
androidx.compose.animation.AnimatedVisibility(
|
||||
uiState.currentPlaylistItemIndex != 0,
|
||||
enter = fadeIn(animationSpec = tween(200)),
|
||||
exit = fadeOut(animationSpec = tween(400))
|
||||
|
||||
) {
|
||||
CenterControllButton(
|
||||
buttonModifier = Modifier.fillMaxSize(),
|
||||
iconModifier = Modifier.size(40.dp),
|
||||
icon = Icons.Filled.SkipPrevious,
|
||||
contentDescription = stringResource(R.string.widget_description_previous_stream),
|
||||
onClick = viewModel::prevStream
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CenterControllButton(
|
||||
buttonModifier = Modifier.size(80.dp),
|
||||
|
@ -78,14 +94,21 @@ fun CenterUI(
|
|||
),
|
||||
onClick = if (uiState.playing) viewModel::pause else viewModel::play
|
||||
)
|
||||
|
||||
CenterControllButton(
|
||||
buttonModifier = Modifier.size(80.dp),
|
||||
iconModifier = Modifier.size(40.dp),
|
||||
icon = Icons.Filled.SkipNext,
|
||||
contentDescription = stringResource(R.string.widget_description_next_stream),
|
||||
onClick = viewModel::nextStream
|
||||
)
|
||||
Box(modifier = Modifier.size(80.dp)) {
|
||||
androidx.compose.animation.AnimatedVisibility(
|
||||
uiState.currentPlaylistItemIndex < uiState.playList.size - 1,
|
||||
enter = fadeIn(animationSpec = tween(200)),
|
||||
exit = fadeOut(animationSpec = tween(400))
|
||||
) {
|
||||
CenterControllButton(
|
||||
buttonModifier = Modifier.fillMaxSize(),
|
||||
iconModifier = Modifier.size(40.dp),
|
||||
icon = Icons.Filled.SkipNext,
|
||||
contentDescription = stringResource(R.string.widget_description_next_stream),
|
||||
onClick = viewModel::nextStream
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +147,8 @@ fun VideoPlayerControllerUICenterUIPreview() {
|
|||
viewModel = VideoPlayerViewModelDummy(),
|
||||
uiState = VideoPlayerUIState.DUMMY.copy(
|
||||
isLoading = false,
|
||||
playing = true
|
||||
playing = true,
|
||||
currentPlaylistItemIndex = 1
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -172,25 +172,7 @@ fun VideoPlayerChannelSelectUIPreview() {
|
|||
StreamSelectUI(
|
||||
isChapterSelect = true,
|
||||
viewModel = VideoPlayerViewModelDummy(),
|
||||
uiState = VideoPlayerUIState.DEFAULT.copy(
|
||||
chapters = arrayListOf(
|
||||
Chapter(
|
||||
chapterStartInMs = 5000,
|
||||
chapterTitle = "First Chapter",
|
||||
thumbnail = null
|
||||
),
|
||||
Chapter(
|
||||
chapterStartInMs = 10000,
|
||||
chapterTitle = "Second Chapter",
|
||||
thumbnail = null
|
||||
),
|
||||
Chapter(
|
||||
chapterStartInMs = 20000,
|
||||
chapterTitle = "Third Chapter",
|
||||
thumbnail = null
|
||||
),
|
||||
)
|
||||
)
|
||||
uiState = VideoPlayerUIState.DUMMY
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -205,32 +187,6 @@ fun VideoPlayerStreamSelectUIPreview() {
|
|||
isChapterSelect = false,
|
||||
viewModel = VideoPlayerViewModelDummy(),
|
||||
uiState = VideoPlayerUIState.DUMMY.copy(
|
||||
playList = arrayListOf(
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 1",
|
||||
creator = "The Creator",
|
||||
lengthInS = 6 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 0
|
||||
),
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 2",
|
||||
creator = "The Creator 2",
|
||||
lengthInS = 2 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 1
|
||||
),
|
||||
PlaylistItem(
|
||||
id = "6502",
|
||||
title = "Stream 3",
|
||||
creator = "The Creator 3",
|
||||
lengthInS = 29 * 60 + 5,
|
||||
thumbnail = null,
|
||||
uniqueId = 2
|
||||
)
|
||||
),
|
||||
currentlyPlaying = PlaylistItem.DUMMY.copy(uniqueId = 1)
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue