From 240ee591eff2d0c70501bff998f3703f899d4e4c Mon Sep 17 00:00:00 2001 From: Maxr1998 Date: Fri, 14 Apr 2023 00:59:15 +0200 Subject: [PATCH] Fix subtitle selection for encoded subtitles --- .../mobile/player/TrackSelectionHelper.kt | 17 ++++++++++++++- .../mobile/player/queue/QueueManager.kt | 21 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/jellyfin/mobile/player/TrackSelectionHelper.kt b/app/src/main/java/org/jellyfin/mobile/player/TrackSelectionHelper.kt index 1ab55080..ec271c7a 100644 --- a/app/src/main/java/org/jellyfin/mobile/player/TrackSelectionHelper.kt +++ b/app/src/main/java/org/jellyfin/mobile/player/TrackSelectionHelper.kt @@ -86,6 +86,15 @@ class TrackSelectionHelper( val selectedMediaStream = mediaSource.mediaStreams.getOrNull(mediaStreamIndex) require(selectedMediaStream == null || selectedMediaStream.type == MediaStreamType.SUBTITLE) + // If the selected subtitle stream requires encoding or the current subtitle is baked into the stream, + // we need to restart playback + if ( + selectedMediaStream?.deliveryMethod == SubtitleDeliveryMethod.ENCODE || + mediaSource.selectedSubtitleStream?.deliveryMethod == SubtitleDeliveryMethod.ENCODE + ) { + return viewModel.mediaQueueManager.selectSubtitleStreamAndRestartPlayback(selectedMediaStream) + } + return selectSubtitleTrack(mediaSource, selectedMediaStream, initial = false).also { success -> if (success) viewModel.logTracks() } @@ -115,6 +124,11 @@ class TrackSelectionHelper( val player = viewModel.playerOrNull ?: return false when (subtitleStream.deliveryMethod) { + SubtitleDeliveryMethod.ENCODE -> { + // Normally handled in selectSubtitleTrack(int) by restarting playback, + // initial selection is always considered successful + return true + } SubtitleDeliveryMethod.EMBED -> { // For embedded subtitles, we can match by the index of this stream in all embedded streams. val embeddedStreamIndex = mediaSource.getEmbeddedStreamIndex(subtitleStream) @@ -147,6 +161,7 @@ class TrackSelectionHelper( else -> -1 } selectSubtitleTrack(newSubtitleIndex) - return mediaSource.selectedSubtitleStream != null + // Media source may have changed by now + return mediaSourceOrNull?.selectedSubtitleStream != null } } diff --git a/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt b/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt index 9df21dec..bf229d14 100644 --- a/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt +++ b/app/src/main/java/org/jellyfin/mobile/player/queue/QueueManager.kt @@ -280,6 +280,27 @@ class QueueManager( return true } + /** + * Switch to the specified [subtitle stream][stream] and restart playback, + * for example because the selected subtitle has to be encoded into the video. + * + * @param stream The subtitle stream to select, or null to disable subtitles. + * @return true if playback was restarted with the new selection. + */ + suspend fun selectSubtitleStreamAndRestartPlayback(stream: MediaStream?): Boolean { + require(stream == null || stream.type == MediaStreamType.SUBTITLE) + val currentPlayOptions = currentPlayOptions ?: return false + val currentPlayState = viewModel.getStateAndPause() ?: return false + + val playOptions = currentPlayOptions.copy( + startPositionTicks = currentPlayState.position * Constants.TICKS_PER_MILLISECOND, + subtitleStreamIndex = stream?.index ?: -1, // -1 disables subtitles, null would select the default subtitle + ) + + startPlayback(playOptions, currentPlayState.playWhenReady) + return true + } + sealed class QueueItem { class Loaded( val jellyfinMediaSource: JellyfinMediaSource,