From 72fb732e639b15e246a6d2404c8bba2bccf276cc Mon Sep 17 00:00:00 2001 From: damontecres <154766448+damontecres@users.noreply.github.com> Date: Fri, 14 Nov 2025 16:13:18 -0500 Subject: [PATCH] Fix & refactor some image aspect ratios (#222) Fix image aspect ratios for episode cards that differ from the video's aspect ratio. Also use the video's aspect ratio for chapter cards instead of assuming 16x9. Dev: Create constants for the main ratios used Fixes #215 --- .../damontecres/wholphin/ui/UiConstants.kt | 6 +++ .../wholphin/ui/cards/BannerCard.kt | 3 +- .../wholphin/ui/cards/ChapterCard.kt | 2 +- .../wholphin/ui/cards/ChapterRow.kt | 2 + .../wholphin/ui/cards/EpisodeCard.kt | 3 +- .../damontecres/wholphin/ui/cards/GridCard.kt | 3 +- .../damontecres/wholphin/ui/cards/ItemRow.kt | 4 +- .../wholphin/ui/cards/PersonCard.kt | 3 +- .../wholphin/ui/cards/SeasonCard.kt | 6 +-- .../wholphin/ui/detail/movie/MovieDetails.kt | 3 ++ .../ui/detail/series/SeriesOverviewContent.kt | 8 ++- .../damontecres/wholphin/ui/main/HomePage.kt | 4 +- .../wholphin/ui/playback/NextUpEpisode.kt | 5 +- .../wholphin/ui/playback/PlaybackOverlay.kt | 4 ++ .../wholphin/ui/playback/PlaybackPage.kt | 6 ++- .../wholphin/ui/playback/PlaybackViewModel.kt | 52 +++++++++++-------- 16 files changed, 72 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt index c0678736..cc4791e2 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/UiConstants.kt @@ -74,6 +74,12 @@ object Cards { val playedPercentHeight = 6.dp } +object AspectRatios { + const val WIDE = 16f / 9f + const val FOUR_THREE = 4f / 3f + const val TALL = 2f / 3f +} + @Preview( device = "spec:parent=tv_1080p", backgroundColor = 0xFF383535, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt index 06f994f5..28de1f7b 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/BannerCard.kt @@ -34,6 +34,7 @@ import androidx.tv.material3.Text import coil3.compose.AsyncImage import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.ui.AppColors +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.FontAwesome import com.github.damontecres.wholphin.ui.isNotNullOrBlank @@ -53,7 +54,7 @@ fun BannerCard( favorite: Boolean = false, playPercent: Double = 0.0, cardHeight: Dp = 140.dp * .85f, - aspectRatio: Float = 16f / 9, + aspectRatio: Float = AspectRatios.WIDE, interactionSource: MutableInteractionSource? = null, ) { var imageError by remember { mutableStateOf(false) } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterCard.kt index aad0ddd0..4739b80c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterCard.kt @@ -30,9 +30,9 @@ fun ChapterCard( position: Duration, imageUrl: String?, onClick: () -> Unit, + aspectRatio: Float, modifier: Modifier = Modifier, cardHeight: Dp = 140.dp * .85f, - aspectRatio: Float = 16f / 9, onLongClick: (() -> Unit)? = null, interactionSource: MutableInteractionSource? = null, ) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterRow.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterRow.kt index 1c206990..cf799c54 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterRow.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ChapterRow.kt @@ -21,6 +21,7 @@ import com.github.damontecres.wholphin.data.model.Chapter @Composable fun ChapterRow( chapters: List, + aspectRatio: Float, onClick: (Chapter) -> Unit, modifier: Modifier = Modifier, onLongClick: ((Chapter) -> Unit)? = null, @@ -50,6 +51,7 @@ fun ChapterRow( position = item.position, imageUrl = item.imageUrl, onClick = { onClick(item) }, + aspectRatio = aspectRatio, modifier = Modifier, onLongClick = onLongClick?.let { { it(item) } }, ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/EpisodeCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/EpisodeCard.kt index 9eafb1ca..6d25aa80 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/EpisodeCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/EpisodeCard.kt @@ -30,6 +30,7 @@ import androidx.tv.material3.CardDefaults import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.ui.AppColors +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.enableMarquee import com.github.damontecres.wholphin.ui.seasonEpisode import kotlinx.coroutines.delay @@ -63,7 +64,7 @@ fun EpisodeCard( } else { focusedAfterDelay = false } - val aspectRatio = dto?.primaryImageAspectRatio?.toFloat() ?: (2f / 3f) + val aspectRatio = dto?.primaryImageAspectRatio?.toFloat() ?: AspectRatios.TALL val width = imageHeight * aspectRatio val height = imageWidth * (1f / aspectRatio) Column( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GridCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GridCard.kt index 39cb13f2..e5e30a3c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GridCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/GridCard.kt @@ -25,6 +25,7 @@ import androidx.tv.material3.CardDefaults import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.BaseItem +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.enableMarquee import kotlinx.coroutines.delay @@ -38,7 +39,7 @@ fun GridCard( onLongClick: () -> Unit, modifier: Modifier = Modifier, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, - imageAspectRatio: Float = 2f / 3f, + imageAspectRatio: Float = AspectRatios.TALL, ) { val dto = item?.data val focused by interactionSource.collectIsFocusedAsState() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemRow.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemRow.kt index 71df426b..e629fb97 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemRow.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/ItemRow.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp import androidx.tv.material3.MaterialTheme import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.BaseItem +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.util.FocusPair @Composable @@ -112,7 +113,8 @@ fun BannerItemRow( name = title, imageUrl = item?.imageUrl, aspectRatio = - aspectRatioOverride ?: item?.data?.primaryImageAspectRatio?.toFloat() ?: (16f / 9), + aspectRatioOverride ?: item?.data?.primaryImageAspectRatio?.toFloat() + ?: AspectRatios.WIDE, cornerText = item?.data?.indexNumber?.let { "E$it" }, played = item?.data?.userData?.played ?: false, playPercent = item?.data?.userData?.playedPercentage ?: 0.0, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt index dcde2ff0..83d72010 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/PersonCard.kt @@ -22,6 +22,7 @@ import androidx.tv.material3.Card import androidx.tv.material3.CardDefaults import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.Person +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.enableMarquee import kotlinx.coroutines.delay @@ -81,7 +82,7 @@ fun PersonCard( modifier = Modifier .fillMaxWidth() - .aspectRatio(2f / 3f), // TODO, + .aspectRatio(AspectRatios.TALL), // TODO, ) } Column( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/SeasonCard.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/SeasonCard.kt index 22ad8b1b..ed9d01cd 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/cards/SeasonCard.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/cards/SeasonCard.kt @@ -26,6 +26,7 @@ import androidx.tv.material3.Card import androidx.tv.material3.CardDefaults import androidx.tv.material3.Text import com.github.damontecres.wholphin.data.model.BaseItem +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.enableMarquee import kotlinx.coroutines.delay @@ -42,7 +43,7 @@ fun SeasonCard( imageWidth: Dp = Dp.Unspecified, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, showImageOverlay: Boolean = false, - aspectRatio: Float = item?.data?.primaryImageAspectRatio?.toFloat() ?: (2f / 3f), + aspectRatio: Float = item?.data?.primaryImageAspectRatio?.toFloat() ?: AspectRatios.TALL, ) = SeasonCard( title = item?.title, subtitle = item?.subtitle, @@ -82,7 +83,7 @@ fun SeasonCard( imageWidth: Dp = Dp.Unspecified, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, showImageOverlay: Boolean = false, - aspectRatio: Float = (2f / 3f), + aspectRatio: Float = AspectRatios.TALL, ) { val focused by interactionSource.collectIsFocusedAsState() val spaceBetween by animateDpAsState(if (focused) 12.dp else 4.dp) @@ -102,7 +103,6 @@ fun SeasonCard( } else { focusedAfterDelay = false } -// val aspectRatio = dto?.primaryImageAspectRatio?.toFloat() ?: (2f / 3f) val width = imageHeight * aspectRatio val height = imageWidth * (1f / aspectRatio) Column( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt index c7d329a9..346ef4a6 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt @@ -51,9 +51,11 @@ import com.github.damontecres.wholphin.data.model.LocalTrailer import com.github.damontecres.wholphin.data.model.Person import com.github.damontecres.wholphin.data.model.RemoteTrailer import com.github.damontecres.wholphin.data.model.Trailer +import com.github.damontecres.wholphin.data.model.aspectRatioFloat import com.github.damontecres.wholphin.data.model.chooseSource import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.TrailerService +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.cards.ChapterRow import com.github.damontecres.wholphin.ui.cards.ItemRow @@ -486,6 +488,7 @@ fun MovieDetailsContent( item { ChapterRow( chapters = chapters, + aspectRatio = movie.data.aspectRatioFloat ?: AspectRatios.WIDE, onClick = { position = CHAPTER_ROW playOnClick.invoke(it.position) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverviewContent.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverviewContent.kt index 302da4e3..bb98f97c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverviewContent.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverviewContent.kt @@ -42,8 +42,8 @@ import coil3.compose.AsyncImage import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.data.ChosenStreams import com.github.damontecres.wholphin.data.model.BaseItem -import com.github.damontecres.wholphin.data.model.aspectRatioFloat import com.github.damontecres.wholphin.preferences.UserPreferences +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect import com.github.damontecres.wholphin.ui.cards.BannerCard import com.github.damontecres.wholphin.ui.components.ErrorMessage @@ -216,10 +216,8 @@ fun SeriesOverviewContent( ?.data ?.primaryImageAspectRatio ?.toFloat() - ?.coerceAtLeast( - episode.data.aspectRatioFloat ?: (4f / 3f), - ) - ?: (16f / 9), // TODO some episode images don't match the file's aspect ratio + ?.coerceAtLeast(AspectRatios.FOUR_THREE) + ?: (AspectRatios.WIDE), cornerText = cornerText, played = episode?.data?.userData?.played ?: false, playPercent = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt index 24764384..4d7f4566 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt @@ -46,6 +46,7 @@ import coil3.compose.AsyncImage import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.Cards import com.github.damontecres.wholphin.ui.cards.BannerCard import com.github.damontecres.wholphin.ui.cards.ItemRow @@ -353,11 +354,10 @@ fun HomePageContent( .fillMaxWidth() .animateItem(), cardContent = { index, item, cardModifier, onClick, onLongClick -> - // TODO better aspect ration handling? BannerCard( name = item?.data?.seriesName ?: item?.name, imageUrl = item?.imageUrl, - aspectRatio = (2f / 3f), + aspectRatio = AspectRatios.TALL, cornerText = item?.data?.indexNumber?.let { "E$it" } ?: item?.data?.childCount?.let { if (it > 0) it.toString() else null }, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/NextUpEpisode.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/NextUpEpisode.kt index 5596a864..44048a40 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/NextUpEpisode.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/NextUpEpisode.kt @@ -45,6 +45,7 @@ import coil3.compose.AsyncImagePreviewHandler import coil3.compose.LocalAsyncImagePreviewHandler import com.github.damontecres.wholphin.R import com.github.damontecres.wholphin.ui.AppColors +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.PreviewTvSpec import com.github.damontecres.wholphin.ui.theme.WholphinTheme import com.github.damontecres.wholphin.ui.tryRequestFocus @@ -62,7 +63,7 @@ fun NextUpEpisode( onClick: () -> Unit, timeLeft: Duration?, modifier: Modifier = Modifier, - aspectRatio: Float = 16f / 9, + aspectRatio: Float = AspectRatios.WIDE, ) { val interactionSource = remember { MutableInteractionSource() } val focusRequester = remember { FocusRequester() } @@ -202,7 +203,7 @@ private fun NextUpEpisodePreview() { "But it just keeps going and going.", imageUrl = "", onClick = {}, - aspectRatio = 4f / 3, + aspectRatio = AspectRatios.FOUR_THREE, timeLeft = 30.seconds, modifier = Modifier diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackOverlay.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackOverlay.kt index 0181f8e1..df389c7f 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackOverlay.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackOverlay.kt @@ -50,7 +50,9 @@ import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.Chapter import com.github.damontecres.wholphin.data.model.ItemPlayback import com.github.damontecres.wholphin.data.model.Playlist +import com.github.damontecres.wholphin.data.model.aspectRatioFloat import com.github.damontecres.wholphin.ui.AppColors +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.TimeFormatter import com.github.damontecres.wholphin.ui.cards.ChapterCard import com.github.damontecres.wholphin.ui.cards.SeasonCard @@ -75,6 +77,7 @@ private val subtitleTextSize = 18.sp */ @Composable fun PlaybackOverlay( + item: BaseItem?, title: String?, subtitleStreams: List, chapters: List, @@ -236,6 +239,7 @@ fun PlaybackOverlay( name = chapter.name, position = chapter.position, imageUrl = chapter.imageUrl, + aspectRatio = item?.data?.aspectRatioFloat ?: AspectRatios.WIDE, onClick = { playerControls.seekTo(chapter.position.inWholeMilliseconds) controllerViewState.hideControls() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackPage.kt index 75d0cfa2..d531e9e7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackPage.kt @@ -67,6 +67,7 @@ import com.github.damontecres.wholphin.data.model.ItemPlayback import com.github.damontecres.wholphin.data.model.Playlist import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.preferences.skipBackOnResume +import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect import com.github.damontecres.wholphin.ui.components.ErrorMessage import com.github.damontecres.wholphin.ui.components.LoadingPage @@ -320,6 +321,7 @@ fun PlaybackPage( .padding(WindowInsets.systemBars.asPaddingValues()) .fillMaxSize() .background(Color.Transparent), + item = currentPlayback?.item, title = title, subtitle = subtitle, subtitleStreams = subtitleStreams, @@ -476,7 +478,9 @@ fun PlaybackPage( ).joinToString(" - "), description = it.data.overview, imageUrl = it.imageUrl, - aspectRatio = it.data.primaryImageAspectRatio?.toFloat() ?: (16f / 9), + aspectRatio = + it.data.primaryImageAspectRatio?.toFloat() + ?: AspectRatios.WIDE, onClick = { viewModel.reportInteraction() viewModel.playUpNextUp() diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt index f4b4cb60..e9566a1e 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/PlaybackViewModel.kt @@ -73,7 +73,6 @@ import org.jellyfin.sdk.api.client.extensions.trickplayApi import org.jellyfin.sdk.api.client.extensions.userLibraryApi import org.jellyfin.sdk.api.client.extensions.videosApi import org.jellyfin.sdk.api.sockets.subscribe -import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.BaseItemKind import org.jellyfin.sdk.model.api.DeviceProfile import org.jellyfin.sdk.model.api.MediaSegmentDto @@ -138,7 +137,7 @@ class PlaybackViewModel private lateinit var preferences: UserPreferences private lateinit var deviceProfile: DeviceProfile private lateinit var itemId: UUID - private lateinit var dto: BaseItemDto + private lateinit var item: BaseItem private var activityListener: TrackActivityPlaybackListener? = null val nextUp = MutableLiveData() @@ -200,10 +199,11 @@ class PlaybackViewModel } else { queriedItem } + val item = BaseItem.from(base, api) val played = play( - base, + item, destination.positionMs, destination.itemPlayback, destination.forceTranscoding, @@ -224,25 +224,25 @@ class PlaybackViewModel } private suspend fun play( - base: BaseItemDto, + item: BaseItem, positionMs: Long, itemPlayback: ItemPlayback? = null, forceTranscoding: Boolean = false, ): Boolean = withContext(Dispatchers.IO) { - Timber.i("Playing ${base.id}") + Timber.i("Playing ${item.id}") autoSkippedSegments.clear() - if (base.type !in supportItemKinds) { + if (item.type !in supportItemKinds) { showToast( context, - "Unsupported type '${base.type}', skipping...", + "Unsupported type '${item.type}', skipping...", Toast.LENGTH_SHORT, ) return@withContext false } - val isLiveTv = base.type == BaseItemKind.TV_CHANNEL + val isLiveTv = item.type == BaseItemKind.TV_CHANNEL - dto = base + val base = item.data val title = if (base.type == BaseItemKind.EPISODE) { base.seriesName @@ -354,7 +354,7 @@ class PlaybackViewModel this@PlaybackViewModel.subtitleStreams.value = subtitleStreams changeStreams( - base, + item, itemPlaybackToUse, audioIndex, subtitleIndex, @@ -374,7 +374,7 @@ class PlaybackViewModel @OptIn(UnstableApi::class) private suspend fun changeStreams( - item: BaseItemDto, + item: BaseItem, currentItemPlayback: ItemPlayback = this@PlaybackViewModel.currentItemPlayback.value!!, audioIndex: Int?, subtitleIndex: Int?, @@ -495,7 +495,8 @@ class PlaybackViewModel val playback = CurrentPlayback( - listOf(), + item = item, + tracks = listOf(), playMethod = transcodeType, playSessionId = response.playSessionId, liveStreamId = source.liveStreamId, @@ -563,7 +564,7 @@ class PlaybackViewModel } } val trickPlayInfo = - item.trickplay + item.data.trickplay ?.get(source.id) ?.values ?.firstOrNull() @@ -577,7 +578,7 @@ class PlaybackViewModel fun changeAudioStream(index: Int) { viewModelScope.launchIO { changeStreams( - dto, + item, currentItemPlayback.value!!, index, currentItemPlayback.value?.subtitleIndex, @@ -590,7 +591,7 @@ class PlaybackViewModel fun changeSubtitleStream(index: Int?): Job = viewModelScope.launchIO { changeStreams( - dto, + item, currentItemPlayback.value!!, currentItemPlayback.value?.audioIndex, index, @@ -600,7 +601,7 @@ class PlaybackViewModel } fun getTrickplayUrl(index: Int): String? { - val itemId = dto.id + val itemId = item.id val mediaSourceId = currentItemPlayback.value?.sourceId val trickPlayInfo = trickplay.value ?: return null return api.trickplayApi.getTrickplayTileImageUrl( @@ -732,7 +733,7 @@ class PlaybackViewModel viewModelScope.launchIO { cancelUpNextEpisode() val item = it.getAndAdvance() - val played = play(item.data, 0) + val played = play(item, 0) if (!played) { playUpNextUp() } @@ -747,7 +748,7 @@ class PlaybackViewModel viewModelScope.launchIO { cancelUpNextEpisode() val item = it.getPreviousAndReverse() - val played = play(item.data, 0) + val played = play(item, 0) if (!played) { playPrevious() } @@ -765,7 +766,7 @@ class PlaybackViewModel viewModelScope.launchIO { val toPlay = playlist.advanceTo(item.id) if (toPlay != null) { - val played = play(toPlay.data, 0) + val played = play(toPlay, 0) if (!played) { playUpNextUp() } @@ -799,7 +800,7 @@ class PlaybackViewModel PlayMethod.DIRECT_STREAM, PlayMethod.DIRECT_PLAY -> { Timber.w("Playback error during ${it.playMethod}, falling back to transcoding") changeStreams( - dto, + item, currentItemPlayback.value!!, currentItemPlayback.value?.audioIndex, currentItemPlayback.value?.subtitleIndex, @@ -918,8 +919,12 @@ class PlaybackViewModel while (maxAttempts > 0 && subtitleCount == newCount) { maxAttempts-- delay(1500) - dto = api.userLibraryApi.getItem(itemId = dto.id).content - val mediaSource = chooseSource(dto, it) + item = + BaseItem.from( + api.userLibraryApi.getItem(itemId = item.id).content, + api, + ) + val mediaSource = chooseSource(item.data, it) if (mediaSource == null) { // This shouldn't happen, but just in case showToast( @@ -976,7 +981,7 @@ class PlaybackViewModel audioIndex += 1 } changeStreams( - dto, + item, currentItemPlayback.value!!, audioIndex, newStream.index, @@ -1006,6 +1011,7 @@ class PlaybackViewModel } data class CurrentPlayback( + val item: BaseItem, val tracks: List, val playMethod: PlayMethod, val playSessionId: String?,