mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Show playback debug info
This commit is contained in:
parent
9cc2fc40d3
commit
64e881f51c
9 changed files with 177 additions and 28 deletions
|
|
@ -187,18 +187,17 @@ sealed interface AppPreference<T> {
|
|||
summaryOff = R.string.disabled,
|
||||
)
|
||||
|
||||
// val PlaybackDebugInfo =
|
||||
// AppSwitchPreference(
|
||||
// title = R.string.playback_debug_info,
|
||||
// prefKey = R.string.pref_key_show_playback_debug_info,
|
||||
// defaultValue = false,
|
||||
// getter = { it.playbackPreferences.showDebugInfo },
|
||||
// setter = { prefs, value ->
|
||||
// prefs.updatePlaybackPreferences { showDebugInfo = value }
|
||||
// },
|
||||
// summaryOn = R.string.show,
|
||||
// summaryOff = R.string.hide,
|
||||
// )
|
||||
val PlaybackDebugInfo =
|
||||
AppSwitchPreference(
|
||||
title = R.string.playback_debug_info,
|
||||
defaultValue = false,
|
||||
getter = { it.playbackPreferences.showDebugInfo },
|
||||
setter = { prefs, value ->
|
||||
prefs.updatePlaybackPreferences { showDebugInfo = value }
|
||||
},
|
||||
summaryOn = R.string.show,
|
||||
summaryOff = R.string.hide,
|
||||
)
|
||||
|
||||
// val AutoCheckForUpdates =
|
||||
// AppSwitchPreference(
|
||||
|
|
@ -246,6 +245,7 @@ val basicPreferences =
|
|||
AppPreference.RewatchNextUp,
|
||||
AppPreference.PlayThemeMusic,
|
||||
AppPreference.OssLicenseInfo,
|
||||
AppPreference.PlaybackDebugInfo,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class AppPreferencesSerializer
|
|||
AppPreference.SkipBack.defaultValue.seconds.inWholeMilliseconds
|
||||
controllerTimeoutMs = AppPreference.ControllerTimeout.defaultValue
|
||||
seekBarSteps = AppPreference.SeekBarSteps.defaultValue.toInt()
|
||||
showDebugInfo = AppPreference.PlaybackDebugInfo.defaultValue
|
||||
}.build()
|
||||
homePagePreferences =
|
||||
HomePagePreferences
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ fun PlaybackContent(
|
|||
modifier: Modifier = Modifier,
|
||||
viewModel: PlaybackViewModel = hiltViewModel(),
|
||||
) {
|
||||
val prefs = preferences.appPreferences.playbackPreferences
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
LaunchedEffect(destination.itemId) {
|
||||
|
|
@ -88,6 +89,7 @@ fun PlaybackContent(
|
|||
val currentPlayback by viewModel.currentPlayback.observeAsState(null)
|
||||
|
||||
var cues by remember { mutableStateOf<List<Cue>>(listOf()) }
|
||||
var showDebugInfo by remember { mutableStateOf(prefs.showDebugInfo) }
|
||||
|
||||
// TODO move to viewmodel?
|
||||
val cueListener =
|
||||
|
|
@ -246,7 +248,9 @@ fun PlaybackContent(
|
|||
contentScale = it.scale
|
||||
}
|
||||
|
||||
PlaybackAction.ShowDebug -> TODO()
|
||||
PlaybackAction.ShowDebug -> {
|
||||
showDebugInfo = !showDebugInfo
|
||||
}
|
||||
PlaybackAction.ShowPlaylist -> TODO()
|
||||
PlaybackAction.ShowVideoFilterDialog -> TODO()
|
||||
is PlaybackAction.ToggleAudio -> {
|
||||
|
|
@ -259,12 +263,11 @@ fun PlaybackContent(
|
|||
}
|
||||
},
|
||||
onSeekBarChange = seekBarState::onValueChange,
|
||||
showDebugInfo = false,
|
||||
showDebugInfo = showDebugInfo,
|
||||
scale = contentScale,
|
||||
playbackSpeed = playbackSpeed,
|
||||
moreButtonOptions = MoreButtonOptions(mapOf()),
|
||||
subtitleIndex = currentPlayback?.subtitleIndex,
|
||||
audioIndex = currentPlayback?.audioIndex,
|
||||
currentPlayback = currentPlayback,
|
||||
audioStreams = audioStreams,
|
||||
trickplayInfo = trickplay,
|
||||
trickplayUrlFor = viewModel::getTrickplayUrl,
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ fun LeftPlaybackButtons(
|
|||
val options =
|
||||
buildList {
|
||||
addAll(moreButtonOptions.options.keys)
|
||||
add(if (showDebugInfo) "Hide transcode info" else "Show transcode info")
|
||||
add(if (showDebugInfo) "Hide debug info" else "Show debug info")
|
||||
}
|
||||
BottomDialog(
|
||||
choices = options,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.github.damontecres.dolphin.ui.playback
|
|||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
|
@ -35,9 +36,11 @@ import androidx.media3.common.Player
|
|||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.dolphin.data.model.Chapter
|
||||
import com.github.damontecres.dolphin.ui.AppColors
|
||||
import com.github.damontecres.dolphin.ui.cards.ChapterCard
|
||||
import com.github.damontecres.dolphin.ui.ifElse
|
||||
import com.github.damontecres.dolphin.ui.isNotNullOrBlank
|
||||
import com.github.damontecres.dolphin.ui.letNotEmpty
|
||||
import org.jellyfin.sdk.model.api.TrickplayInfo
|
||||
import kotlin.time.Duration
|
||||
|
||||
|
|
@ -60,8 +63,7 @@ fun PlaybackOverlay(
|
|||
scale: ContentScale,
|
||||
playbackSpeed: Float,
|
||||
moreButtonOptions: MoreButtonOptions,
|
||||
subtitleIndex: Int?,
|
||||
audioIndex: Int?,
|
||||
currentPlayback: CurrentPlayback?,
|
||||
audioStreams: List<AudioStream>,
|
||||
modifier: Modifier = Modifier,
|
||||
subtitle: String? = null,
|
||||
|
|
@ -168,8 +170,8 @@ fun PlaybackOverlay(
|
|||
seekEnabled = seekEnabled,
|
||||
seekBarInteractionSource = seekBarInteractionSource,
|
||||
moreButtonOptions = moreButtonOptions,
|
||||
subtitleIndex = subtitleIndex,
|
||||
audioIndex = audioIndex,
|
||||
subtitleIndex = currentPlayback?.subtitleIndex,
|
||||
audioIndex = currentPlayback?.audioIndex,
|
||||
audioStreams = audioStreams,
|
||||
playbackSpeed = playbackSpeed,
|
||||
scale = scale,
|
||||
|
|
@ -276,5 +278,22 @@ fun PlaybackOverlay(
|
|||
}
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
showDebugInfo && controllerViewState.controlsVisible,
|
||||
modifier =
|
||||
Modifier
|
||||
.align(Alignment.TopStart),
|
||||
) {
|
||||
currentPlayback?.tracks?.letNotEmpty {
|
||||
PlaybackTrackInfo(
|
||||
trackSupport = it,
|
||||
modifier =
|
||||
Modifier
|
||||
.align(Alignment.TopStart)
|
||||
.padding(16.dp)
|
||||
.background(AppColors.TransparentBlack50),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
package com.github.damontecres.dolphin.ui.playback
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.tv.material3.Icon
|
||||
import androidx.tv.material3.MaterialTheme
|
||||
import androidx.tv.material3.Text
|
||||
import com.github.damontecres.dolphin.util.TrackSupport
|
||||
|
||||
@Composable
|
||||
fun PlaybackTrackInfo(
|
||||
trackSupport: List<TrackSupport>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val selectedWeight = .5f
|
||||
val weights = listOf(.25f, .4f, .5f, 1f, 1f)
|
||||
val textStyle =
|
||||
MaterialTheme.typography.bodySmall.copy(color = MaterialTheme.colorScheme.onBackground)
|
||||
|
||||
LazyColumn(
|
||||
modifier = modifier,
|
||||
) {
|
||||
item {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = Modifier,
|
||||
) {
|
||||
val texts =
|
||||
listOf(
|
||||
"ID",
|
||||
"Type",
|
||||
"Codec",
|
||||
"Supported",
|
||||
"Labels",
|
||||
)
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier.weight(selectedWeight),
|
||||
) {
|
||||
Text(
|
||||
text = "Selected",
|
||||
style = textStyle,
|
||||
)
|
||||
}
|
||||
texts.forEachIndexed { index, text ->
|
||||
Box(
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
modifier = Modifier.weight(weights[index]),
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = textStyle,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
items(trackSupport) { track ->
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
modifier = Modifier,
|
||||
) {
|
||||
val texts =
|
||||
listOf(
|
||||
track.id ?: "",
|
||||
track.type.name,
|
||||
track.codecs ?: "",
|
||||
track.supported.name,
|
||||
track.labels.joinToString(", "),
|
||||
)
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier.weight(selectedWeight),
|
||||
) {
|
||||
if (track.selected) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
modifier = Modifier.size(12.dp),
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = "-",
|
||||
style = textStyle,
|
||||
)
|
||||
}
|
||||
}
|
||||
texts.forEachIndexed { index, text ->
|
||||
Box(
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
modifier = Modifier.weight(weights[index]),
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
style = textStyle,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ import com.github.damontecres.dolphin.preferences.UserPreferences
|
|||
import com.github.damontecres.dolphin.ui.nav.Destination
|
||||
import com.github.damontecres.dolphin.util.ExceptionHandler
|
||||
import com.github.damontecres.dolphin.util.TrackActivityPlaybackListener
|
||||
import com.github.damontecres.dolphin.util.TrackSupport
|
||||
import com.github.damontecres.dolphin.util.checkForSupport
|
||||
import com.github.damontecres.dolphin.util.profile.PlaybackListener
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
|
|
@ -224,6 +226,7 @@ class PlaybackViewModel
|
|||
allowAudioStreamCopy = true,
|
||||
autoOpenLiveStream = true,
|
||||
mediaSourceId = null,
|
||||
alwaysBurnInSubtitleWhenTranscoding = false,
|
||||
),
|
||||
).content
|
||||
val source = response.mediaSources.firstOrNull()
|
||||
|
|
@ -251,16 +254,19 @@ class PlaybackViewModel
|
|||
val decision = StreamDecision(itemId, transcodeType, mediaUrl)
|
||||
Timber.v("Playback decision: $decision")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
duration.value = source.runTimeTicks?.ticks
|
||||
stream.value = decision
|
||||
currentPlayback.value =
|
||||
val playback =
|
||||
CurrentPlayback(
|
||||
itemId,
|
||||
audioIndex,
|
||||
subtitleIndex,
|
||||
source.id?.toUUIDOrNull(),
|
||||
listOf(),
|
||||
)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
duration.value = source.runTimeTicks?.ticks
|
||||
stream.value = decision
|
||||
currentPlayback.value = playback
|
||||
player.setMediaItem(
|
||||
decision.mediaItem,
|
||||
positionMs,
|
||||
|
|
@ -277,6 +283,10 @@ class PlaybackViewModel
|
|||
audioIndex,
|
||||
subtitleIndex,
|
||||
)
|
||||
currentPlayback.value =
|
||||
currentPlayback.value?.copy(
|
||||
tracks = checkForSupport(tracks),
|
||||
)
|
||||
player.removeListener(this)
|
||||
}
|
||||
}
|
||||
|
|
@ -338,6 +348,7 @@ data class CurrentPlayback(
|
|||
val audioIndex: Int?,
|
||||
val subtitleIndex: Int?,
|
||||
val mediaSourceId: UUID?,
|
||||
val tracks: List<TrackSupport>,
|
||||
)
|
||||
|
||||
private val Format.idAsInt: Int?
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ message PlaybackPreferences {
|
|||
int64 skip_back_ms = 2;
|
||||
int64 controller_timeout_ms = 3;
|
||||
int32 seek_bar_steps = 4;
|
||||
bool show_debug_info = 5;
|
||||
}
|
||||
|
||||
message HomePagePreferences{
|
||||
|
|
|
|||
|
|
@ -44,4 +44,5 @@
|
|||
<string name="genres">Genres</string>
|
||||
<string name="play_theme_music">Play theme music</string>
|
||||
<string name="license_info">License information</string>
|
||||
<string name="playback_debug_info">Show playback debug info</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue