parent
92f1cf7eee
commit
a6ebb89b78
3 changed files with 73 additions and 20 deletions
|
@ -40,6 +40,7 @@ import dev.jdtech.jellyfin.core.R
|
|||
import dev.jdtech.jellyfin.destinations.VideoPlayerTrackSelectorDialogDestination
|
||||
import dev.jdtech.jellyfin.models.PlayerItem
|
||||
import dev.jdtech.jellyfin.models.Track
|
||||
import dev.jdtech.jellyfin.mpv.TrackType
|
||||
import dev.jdtech.jellyfin.ui.components.player.VideoPlayerControlsLayout
|
||||
import dev.jdtech.jellyfin.ui.components.player.VideoPlayerMediaButton
|
||||
import dev.jdtech.jellyfin.ui.components.player.VideoPlayerMediaTitle
|
||||
|
@ -47,6 +48,7 @@ import dev.jdtech.jellyfin.ui.components.player.VideoPlayerOverlay
|
|||
import dev.jdtech.jellyfin.ui.components.player.VideoPlayerSeeker
|
||||
import dev.jdtech.jellyfin.ui.components.player.VideoPlayerState
|
||||
import dev.jdtech.jellyfin.ui.components.player.rememberVideoPlayerState
|
||||
import dev.jdtech.jellyfin.ui.dialogs.VideoPlayerTrackSelectorDialogResult
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import dev.jdtech.jellyfin.utils.handleDPadKeyEvents
|
||||
import dev.jdtech.jellyfin.viewmodels.PlayerActivityViewModel
|
||||
|
@ -59,7 +61,7 @@ import kotlin.time.Duration.Companion.milliseconds
|
|||
fun PlayerScreen(
|
||||
navigator: DestinationsNavigator,
|
||||
items: ArrayList<PlayerItem>,
|
||||
resultRecipient: ResultRecipient<VideoPlayerTrackSelectorDialogDestination, Int>,
|
||||
resultRecipient: ResultRecipient<VideoPlayerTrackSelectorDialogDestination, VideoPlayerTrackSelectorDialogResult>,
|
||||
) {
|
||||
val viewModel = hiltViewModel<PlayerActivityViewModel>()
|
||||
|
||||
|
@ -120,12 +122,26 @@ fun PlayerScreen(
|
|||
when (result) {
|
||||
is NavResult.Canceled -> Unit
|
||||
is NavResult.Value -> {
|
||||
viewModel.player.trackSelectionParameters = viewModel.player.trackSelectionParameters
|
||||
.buildUpon()
|
||||
.setOverrideForType(
|
||||
TrackSelectionOverride(viewModel.player.currentTracks.groups[result.value].mediaTrackGroup, 0),
|
||||
)
|
||||
.build()
|
||||
val type = when (result.value.trackType) {
|
||||
TrackType.VIDEO -> C.TRACK_TYPE_VIDEO
|
||||
TrackType.AUDIO -> C.TRACK_TYPE_AUDIO
|
||||
TrackType.SUBTITLE -> C.TRACK_TYPE_TEXT
|
||||
}
|
||||
if (result.value.index == -1) {
|
||||
viewModel.player.trackSelectionParameters = viewModel.player.trackSelectionParameters
|
||||
.buildUpon()
|
||||
.clearOverridesOfType(type)
|
||||
.setTrackTypeDisabled(type, true)
|
||||
.build()
|
||||
} else {
|
||||
viewModel.player.trackSelectionParameters = viewModel.player.trackSelectionParameters
|
||||
.buildUpon()
|
||||
.setOverrideForType(
|
||||
TrackSelectionOverride(viewModel.player.currentTracks.groups[result.value.index].mediaTrackGroup, 0),
|
||||
)
|
||||
.setTrackTypeDisabled(type, false)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +254,7 @@ fun VideoPlayerControls(
|
|||
isPlaying = isPlaying,
|
||||
onClick = {
|
||||
val tracks = getTracks(player, C.TRACK_TYPE_AUDIO)
|
||||
navigator.navigate(VideoPlayerTrackSelectorDialogDestination(tracks))
|
||||
navigator.navigate(VideoPlayerTrackSelectorDialogDestination(TrackType.AUDIO, tracks))
|
||||
},
|
||||
)
|
||||
VideoPlayerMediaButton(
|
||||
|
@ -247,7 +263,7 @@ fun VideoPlayerControls(
|
|||
isPlaying = isPlaying,
|
||||
onClick = {
|
||||
val tracks = getTracks(player, C.TRACK_TYPE_TEXT)
|
||||
navigator.navigate(VideoPlayerTrackSelectorDialogDestination(tracks))
|
||||
navigator.navigate(VideoPlayerTrackSelectorDialogDestination(TrackType.SUBTITLE, tracks))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -270,7 +286,7 @@ private fun Modifier.dPadEvents(
|
|||
)
|
||||
|
||||
@androidx.annotation.OptIn(UnstableApi::class)
|
||||
private fun getTracks(player: Player, type: Int): ArrayList<Track> {
|
||||
private fun getTracks(player: Player, type: Int): Array<Track> {
|
||||
val tracks = arrayListOf<Track>()
|
||||
for (groupIndex in 0 until player.currentTracks.groups.count()) {
|
||||
val group = player.currentTracks.groups[groupIndex]
|
||||
|
@ -283,11 +299,20 @@ private fun getTracks(player: Player, type: Int): ArrayList<Track> {
|
|||
language = Locale(format.language.toString()).displayLanguage,
|
||||
codec = format.codecs,
|
||||
selected = group.isSelected,
|
||||
supported = group.isSupported
|
||||
supported = group.isSupported,
|
||||
)
|
||||
|
||||
tracks.add(track)
|
||||
}
|
||||
}
|
||||
return tracks
|
||||
|
||||
val noneTrack = Track(
|
||||
id = -1,
|
||||
label = null,
|
||||
language = null,
|
||||
codec = null,
|
||||
selected = !tracks.any { it.selected },
|
||||
supported = true,
|
||||
)
|
||||
return arrayOf(noneTrack) + tracks
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package dev.jdtech.jellyfin.ui.dialogs
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
@ -14,6 +15,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.foundation.lazy.list.TvLazyColumn
|
||||
|
@ -30,22 +32,38 @@ import com.ramcosta.composedestinations.annotation.Destination
|
|||
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
|
||||
import com.ramcosta.composedestinations.result.ResultBackNavigator
|
||||
import dev.jdtech.jellyfin.models.Track
|
||||
import dev.jdtech.jellyfin.mpv.TrackType
|
||||
import dev.jdtech.jellyfin.ui.theme.FindroidTheme
|
||||
import dev.jdtech.jellyfin.ui.theme.spacings
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import dev.jdtech.jellyfin.core.R as CoreR
|
||||
import dev.jdtech.jellyfin.player.video.R as PlayerVideoR
|
||||
|
||||
@Parcelize
|
||||
data class VideoPlayerTrackSelectorDialogResult(
|
||||
val trackType: TrackType,
|
||||
val index: Int,
|
||||
) : Parcelable
|
||||
|
||||
@OptIn(ExperimentalTvMaterial3Api::class)
|
||||
@Destination(style = BaseDialogStyle::class)
|
||||
@Composable
|
||||
fun VideoPlayerTrackSelectorDialog(
|
||||
tracks: ArrayList<Track>,
|
||||
resultNavigator: ResultBackNavigator<Int>,
|
||||
trackType: TrackType,
|
||||
tracks: Array<Track>,
|
||||
resultNavigator: ResultBackNavigator<VideoPlayerTrackSelectorDialogResult>,
|
||||
) {
|
||||
val dialogTitle = when (trackType) {
|
||||
TrackType.AUDIO -> PlayerVideoR.string.select_audio_track
|
||||
TrackType.SUBTITLE -> PlayerVideoR.string.select_subtile_track
|
||||
else -> CoreR.string.unknown_error
|
||||
}
|
||||
Surface {
|
||||
Column(
|
||||
modifier = Modifier.padding(MaterialTheme.spacings.medium),
|
||||
) {
|
||||
Text(
|
||||
text = "Select track",
|
||||
text = stringResource(id = dialogTitle),
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(MaterialTheme.spacings.medium))
|
||||
|
@ -56,7 +74,7 @@ fun VideoPlayerTrackSelectorDialog(
|
|||
items(tracks) { track ->
|
||||
Surface(
|
||||
onClick = {
|
||||
resultNavigator.navigateBack(result = track.id)
|
||||
resultNavigator.navigateBack(result = VideoPlayerTrackSelectorDialogResult(trackType, track.id))
|
||||
},
|
||||
enabled = track.supported,
|
||||
shape = ClickableSurfaceDefaults.shape(shape = RoundedCornerShape(4.dp)),
|
||||
|
@ -86,7 +104,13 @@ fun VideoPlayerTrackSelectorDialog(
|
|||
enabled = true,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(MaterialTheme.spacings.medium))
|
||||
Text(text = listOf(track.label, track.language, track.codec).mapNotNull { it }.joinToString(" - "), style = MaterialTheme.typography.bodyLarge)
|
||||
Text(
|
||||
text = listOf(track.label, track.language, track.codec)
|
||||
.mapNotNull { it }
|
||||
.joinToString(" - ")
|
||||
.ifEmpty { stringResource(id = PlayerVideoR.string.none) },
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,14 +124,15 @@ fun VideoPlayerTrackSelectorDialog(
|
|||
private fun VideoPlayerTrackSelectorDialogPreview() {
|
||||
FindroidTheme {
|
||||
VideoPlayerTrackSelectorDialog(
|
||||
tracks = arrayListOf(
|
||||
trackType = TrackType.AUDIO,
|
||||
tracks = arrayOf(
|
||||
Track(
|
||||
id = 0,
|
||||
label = null,
|
||||
language = "English",
|
||||
codec = "flac",
|
||||
selected = true,
|
||||
supported = true
|
||||
supported = true,
|
||||
),
|
||||
Track(
|
||||
id = 0,
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package dev.jdtech.jellyfin.mpv
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.media3.common.C
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
enum class TrackType(val type: String) {
|
||||
@Parcelize
|
||||
enum class TrackType(val type: String) : Parcelable {
|
||||
VIDEO("video"),
|
||||
AUDIO("audio"),
|
||||
SUBTITLE("sub"),
|
||||
|
|
Loading…
Reference in a new issue