From d3a3a2093af1fc031c9a4f4ae4418e774c1326c5 Mon Sep 17 00:00:00 2001 From: damontecres <154766448+damontecres@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:15:47 -0500 Subject: [PATCH] Fix a couple issues with transcoding (#261) If playing with transcoding, changing tracks during playback will continue to transcode instead of possibly switching to direct play. Also support embedded subtitles that are being delivered externally. Fixes #256 Fixes #257 --- .../wholphin/ui/playback/PlaybackViewModel.kt | 12 +++++++----- .../wholphin/ui/playback/TrackSelectionUtils.kt | 13 +++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) 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 e4966499..17d5f4c2 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 @@ -141,6 +141,7 @@ class PlaybackViewModel private lateinit var deviceProfile: DeviceProfile internal lateinit var itemId: UUID internal lateinit var item: BaseItem + internal var forceTranscoding: Boolean = false private var activityListener: TrackActivityPlaybackListener? = null val nextUp = MutableLiveData() @@ -177,6 +178,7 @@ class PlaybackViewModel nextUp.value = null this.preferences = preferences this.deviceProfile = deviceProfile + this.forceTranscoding = destination.forceTranscoding val itemId = destination.itemId this.itemId = itemId val item = destination.item @@ -245,7 +247,7 @@ class PlaybackViewModel item: BaseItem, positionMs: Long, itemPlayback: ItemPlayback? = null, - forceTranscoding: Boolean = false, + forceTranscoding: Boolean = this.forceTranscoding, ): Boolean = withContext(Dispatchers.IO) { Timber.i("Playing ${item.id}") @@ -371,8 +373,8 @@ class PlaybackViewModel subtitleIndex: Int?, positionMs: Long = 0, userInitiated: Boolean, - enableDirectPlay: Boolean = true, - enableDirectStream: Boolean = true, + enableDirectPlay: Boolean = !this.forceTranscoding, + enableDirectStream: Boolean = !this.forceTranscoding, ) = withContext(Dispatchers.IO) { val itemId = item.id val playerBackend = preferences.appPreferences.playbackPreferences.playerBackend @@ -458,7 +460,7 @@ class PlaybackViewModel audioStreamIndex = audioIndex, subtitleStreamIndex = subtitleIndex, mediaSourceId = currentItemPlayback.sourceId?.toServerString(), - alwaysBurnInSubtitleWhenTranscoding = null, + alwaysBurnInSubtitleWhenTranscoding = false, maxStreamingBitrate = maxBitrate.toInt(), enableDirectPlay = enableDirectPlay, enableDirectStream = enableDirectStream, @@ -595,7 +597,7 @@ class PlaybackViewModel player, playerBackend, source.supportsDirectPlay, - audioIndex, + audioIndex.takeIf { transcodeType == PlayMethod.DIRECT_PLAY }, subtitleIndex, source, ) diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/TrackSelectionUtils.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/TrackSelectionUtils.kt index 7df74f6b..9bfde0ed 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/playback/TrackSelectionUtils.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/playback/TrackSelectionUtils.kt @@ -10,6 +10,7 @@ import com.github.damontecres.wholphin.preferences.PlayerBackend import org.jellyfin.sdk.model.api.MediaSourceInfo import org.jellyfin.sdk.model.api.MediaStream import org.jellyfin.sdk.model.api.MediaStreamType +import org.jellyfin.sdk.model.api.SubtitleDeliveryMethod import timber.log.Timber object TrackSelectionUtils { @@ -211,12 +212,16 @@ val MediaSourceInfo.audioStreamCount: Int ?.count { it.type == MediaStreamType.AUDIO } ?: 0 /** - * Returns the [MediaStream] for the given subtitle index iff it is external + * Returns the [MediaStream] for the given subtitle index iff it is delivered external */ -fun MediaSourceInfo.findExternalSubtitle(subtitleIndex: Int?): MediaStream? = +fun MediaSourceInfo.findExternalSubtitle(subtitleIndex: Int?): MediaStream? = mediaStreams?.findExternalSubtitle(subtitleIndex) + +fun List.findExternalSubtitle(subtitleIndex: Int?): MediaStream? = subtitleIndex?.let { - mediaStreams - ?.firstOrNull { it.type == MediaStreamType.SUBTITLE && it.isExternal && it.index == subtitleIndex } + firstOrNull { + it.type == MediaStreamType.SUBTITLE && it.deliveryMethod == SubtitleDeliveryMethod.EXTERNAL && + it.index == subtitleIndex + } } data class TrackSelectionResult(