From ebfc00c016033ae66ce11052f1e41f0c97fc0c94 Mon Sep 17 00:00:00 2001 From: damontecres <154766448+damontecres@users.noreply.github.com> Date: Mon, 15 Dec 2025 12:15:17 -0500 Subject: [PATCH] Always save series audio & subtitle preferences regardless of preferred languages (#473) ## Description This PR adjust the logic for audio & subtitle track selection for TV series. Instead of only saving for future episodes if the newly selected track is a different language than the user's preferred, always save it. Basically this means if you change the audio or subtitle language for an episode, the same audio or subtitle language will be used for future episodes (if available). Also, fixes the "default" subtitle mode to take the user's preferred language into consideration. ## Issues Follow up to https://github.com/damontecres/Wholphin/issues/378 & https://github.com/damontecres/Wholphin/issues/427 Fixes #469 --- .../wholphin/data/ItemPlaybackRepository.kt | 7 +-- .../wholphin/services/StreamChoiceService.kt | 57 +++++++++---------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt index 62e922d4..00bc0fb7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/data/ItemPlaybackRepository.kt @@ -134,9 +134,8 @@ class ItemPlaybackRepository val seriesId = item.data.seriesId if (seriesId != null && trackIndex != TrackIndex.UNSPECIFIED) { if (type == MediaStreamType.AUDIO) { - val audioLang = current.userDto.configuration?.audioLanguagePreference val stream = source.mediaStreams?.first { it.index == trackIndex } - if (stream?.language != null && stream.language != audioLang) { + if (stream?.language != null) { streamChoiceService.updateAudio(item.data, stream.language!!) } } else if (type == MediaStreamType.SUBTITLE) { @@ -147,10 +146,8 @@ class ItemPlaybackRepository subtitlesDisabled = true, ) } else { - val subtitleLang = - current.userDto.configuration?.subtitleLanguagePreference val stream = source.mediaStreams?.first { it.index == trackIndex } - if (stream?.language != null && stream.language != subtitleLang) { + if (stream?.language != null) { streamChoiceService.updateSubtitles( item.data, stream.language!!, diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt index 1af9d11e..e1490ac0 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/StreamChoiceService.kt @@ -114,16 +114,11 @@ class StreamChoiceService if (itemPlayback?.audioIndexEnabled == true) { candidates.firstOrNull { it.index == itemPlayback.audioIndex } } else { - // TODO audio selection based on channel layout or preferences or default - val audioLanguage = - if (prefs.userConfig.audioLanguagePreference.isNotNullOrBlank()) { - // If the user has chosen a preferred language, but changed tracks on the series, use that - // Otherwise, use their preferred language - playbackLanguageChoice?.audioLanguage - ?: prefs.userConfig.audioLanguagePreference - } else { - null - } + val seriesLang = + playbackLanguageChoice?.audioLanguage?.takeIf { it.isNotNullOrBlank() } + // If the user has chosen a different language for the series, prefer that + val audioLanguage = seriesLang ?: prefs.userConfig.audioLanguagePreference + if (audioLanguage.isNotNullOrBlank()) { val sorted = candidates.sortedWith(compareBy { it.language }.thenByDescending { it.channels }) @@ -176,27 +171,21 @@ class StreamChoiceService } else if (itemPlayback?.subtitleIndexEnabled == true) { return candidates.firstOrNull { it.index == itemPlayback.subtitleIndex } } else { + val seriesLang = + playbackLanguageChoice?.subtitleLanguage?.takeIf { it.isNotNullOrBlank() } val subtitleLanguage = - if (prefs.userConfig.subtitleLanguagePreference.isNotNullOrBlank()) { - // If the user has chosen a preferred language, but changed tracks on the series, use that - // Otherwise, use their preferred language - playbackLanguageChoice?.subtitleLanguage - ?: prefs.userConfig.subtitleLanguagePreference - } else { - null - } + (seriesLang ?: prefs.userConfig.subtitleLanguagePreference) + ?.takeIf { it.isNotNullOrBlank() } val subtitleMode = when { - playbackLanguageChoice?.subtitlesDisabled == false && - playbackLanguageChoice.subtitleLanguage != null && - subtitleLanguage.isNotNullOrBlank() -> { - // User has a subtitle language preference, but has chosen a different language for the series - // So override their normal playback mode to always display subtitles + playbackLanguageChoice?.subtitlesDisabled == false && seriesLang != null -> { + // User has chosen a series level subtitle language, so override their normal + // subtitle mode to display that language SubtitlePlaybackMode.ALWAYS } - playbackLanguageChoice?.subtitlesDisabled == true -> { + playbackLanguageChoice?.subtitlesDisabled == true && seriesLang == null -> { // Series level settings disables subtitles SubtitlePlaybackMode.NONE } @@ -234,12 +223,20 @@ class StreamChoiceService } SubtitlePlaybackMode.DEFAULT -> { - // TODO check for language? - ( - candidates.firstOrNull { it.isDefault && it.isForced } - ?: candidates.firstOrNull { it.isDefault } - ?: candidates.firstOrNull { it.isForced } - ) + subtitleLanguage?.let { lang -> + // Find best track that is in the preferred language + ( + candidates.firstOrNull { it.isDefault && it.isForced && it.language == lang } + ?: candidates.firstOrNull { it.isDefault && it.language == lang } + ?: candidates.firstOrNull { it.isForced && it.language == lang } + ) + } + ?: ( + // If none in preferred language, just find the best track + candidates.firstOrNull { it.isDefault && it.isForced } + ?: candidates.firstOrNull { it.isDefault } + ?: candidates.firstOrNull { it.isForced } + ) } SubtitlePlaybackMode.NONE -> {