From 28e6e349b3fc302ebd9ed304f281b77c30e2bc0a Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:29:09 +0200 Subject: [PATCH] fix(android): restore ExoPlayer audio for tunneled decoded PCM --- .../edde746/plezy/exoplayer/ExoPlayerCore.kt | 46 +++++++++++-------- lib/i18n/bg.i18n.json | 2 + lib/i18n/da.i18n.json | 2 + lib/i18n/de.i18n.json | 2 + lib/i18n/en.i18n.json | 2 + lib/i18n/es.i18n.json | 2 + lib/i18n/fr.i18n.json | 2 + lib/i18n/it.i18n.json | 2 + lib/i18n/ja.i18n.json | 2 + lib/i18n/ko.i18n.json | 2 + lib/i18n/nb.i18n.json | 2 + lib/i18n/nl.i18n.json | 2 + lib/i18n/pl.i18n.json | 2 + lib/i18n/pt.i18n.json | 2 + lib/i18n/ru.i18n.json | 2 + lib/i18n/strings.g.dart | 2 +- lib/i18n/strings_bg.g.dart | 12 +++-- lib/i18n/strings_da.g.dart | 12 +++-- lib/i18n/strings_de.g.dart | 12 +++-- lib/i18n/strings_en.g.dart | 16 +++++-- lib/i18n/strings_es.g.dart | 12 +++-- lib/i18n/strings_fr.g.dart | 12 +++-- lib/i18n/strings_it.g.dart | 12 +++-- lib/i18n/strings_ja.g.dart | 12 +++-- lib/i18n/strings_ko.g.dart | 12 +++-- lib/i18n/strings_nb.g.dart | 12 +++-- lib/i18n/strings_nl.g.dart | 12 +++-- lib/i18n/strings_pl.g.dart | 12 +++-- lib/i18n/strings_pt.g.dart | 12 +++-- lib/i18n/strings_ru.g.dart | 12 +++-- lib/i18n/strings_sv.g.dart | 12 +++-- lib/i18n/strings_zh.g.dart | 12 +++-- lib/i18n/sv.i18n.json | 2 + lib/i18n/zh.i18n.json | 2 + .../settings/playback_settings_screen.dart | 8 ++++ lib/services/settings_service.dart | 8 +++- test/services/settings_service_test.dart | 13 ++++++ 37 files changed, 220 insertions(+), 85 deletions(-) diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt index 739f50a5..a852549f 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt @@ -204,7 +204,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { private var tunnelingUserEnabled: Boolean = true private var tunnelingDisabledForAudioCodec: Boolean = false private var tunnelingDisabledForVideoCodec: Boolean = false - private var tunnelingDisabledForDecodedTrueHdPcm: Boolean = false + private var tunnelingDisabledForDecodedPcm: Boolean = false private var tunnelingDisabledForAudioRecovery: Boolean = false // Tunneled playback never fires the VideoFrameMetadataListener (media3 releases @@ -212,7 +212,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { // ASS subs would freeze. Correctness over tunneling while an ASS track is active. private var tunnelingDisabledForAssSubtitles: Boolean = false private val tunnelingDisabledForCodec: Boolean - get() = tunnelingDisabledForAudioCodec || tunnelingDisabledForVideoCodec || tunnelingDisabledForDecodedTrueHdPcm || tunnelingDisabledForAudioRecovery + get() = tunnelingDisabledForAudioCodec || tunnelingDisabledForVideoCodec || tunnelingDisabledForDecodedPcm || tunnelingDisabledForAudioRecovery private var currentTunneledPlayback: Boolean = false // Loudness normalization (#1289): audiofx effects only process non-tunneled @@ -247,7 +247,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { private var lastAudioSinkError: String? = null private var loggedEwasteEac3Workaround: Boolean = false private var lastTrueHdDirectOutputLogKey: String? = null - private var loggedDecodedTrueHdTunnelingGuard: Boolean = false + private var loggedDecodedPcmTunnelingGuard: Boolean = false private var firstFrameRendered: Boolean = false var delegate: ExoPlayerDelegate? = null var debugLoggingEnabled: Boolean = false @@ -2380,7 +2380,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { currentTunneledPlayback = shouldTunnel val speed = exoPlayer?.playbackParameters?.speed ?: 1f val audioDelayActive = (renderersFactory?.audioDelayUs?.get() ?: 0L) != 0L - emitLog("info", "tunneling", "Toggling tunneling=$shouldTunnel (reason=$reason, user=$tunnelingUserEnabled, speed=$speed, audioCodecDisabled=$tunnelingDisabledForAudioCodec, videoCodecDisabled=$tunnelingDisabledForVideoCodec, decodedTrueHdPcmDisabled=$tunnelingDisabledForDecodedTrueHdPcm, audioRecoveryDisabled=$tunnelingDisabledForAudioRecovery, assSubtitlesDisabled=$tunnelingDisabledForAssSubtitles, audioDelay=$audioDelayActive, audioNormalization=$audioNormalizationEnabled)") + emitLog("info", "tunneling", "Toggling tunneling=$shouldTunnel (reason=$reason, user=$tunnelingUserEnabled, speed=$speed, audioCodecDisabled=$tunnelingDisabledForAudioCodec, videoCodecDisabled=$tunnelingDisabledForVideoCodec, decodedPcmDisabled=$tunnelingDisabledForDecodedPcm, audioRecoveryDisabled=$tunnelingDisabledForAudioRecovery, assSubtitlesDisabled=$tunnelingDisabledForAssSubtitles, audioDelay=$audioDelayActive, audioNormalization=$audioNormalizationEnabled)") return true } @@ -2396,8 +2396,11 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { private fun updateAudioCodecForTunneling(format: Format) { val mimeType = format.sampleMimeType ?: return - if (mimeType != MimeTypes.AUDIO_TRUEHD) { - tunnelingDisabledForDecodedTrueHdPcm = false + // The decoded-PCM guard only applies to passthrough-type codecs that can be + // force-decoded; clear it when the selected codec can't have set it. (onAudioTrackInitialized + // re-sets/clears it for passthrough codecs based on the actual output encoding.) + if (!isPassthroughAudioMimeType(mimeType)) { + tunnelingDisabledForDecodedPcm = false } val newDisabled = !hasHardwareAudioDecoder(mimeType) @@ -2533,17 +2536,22 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { "AudioTrack initialized: input=${audioFormat?.let { formatAudioSummary(it) } ?: "unknown"}, " + "decoder=${audioDecoderInitName ?: "direct/bypass"}, ${describeAudioTrackConfig(audioTrackConfig)}" ) - if (audioFormat?.sampleMimeType == MimeTypes.AUDIO_TRUEHD) { + // A passthrough-type codec (AC3/EAC3/DTS/TrueHD…) force-decoded to PCM must not + // stay on a tunneled AudioTrack: some Amlogic/AOSP boxes deliver the PCM frames + // but render silence (#1458). Generalizes the original TrueHD-only guard to every + // codec the passthrough block (and #1289 normalization) can force-decode. + val passthroughSrcMime = audioFormat?.sampleMimeType?.takeIf { isPassthroughAudioMimeType(it) } + if (passthroughSrcMime != null) { if (audioTrackConfig.tunneling && isPcmEncoding(audioTrackConfig.encoding)) { - if (!loggedDecodedTrueHdTunnelingGuard) { - loggedDecodedTrueHdTunnelingGuard = true - emitLog("warn", "audio", "Decoded TrueHD PCM initialized with tunneling=true; forcing tunneling off") + if (!loggedDecodedPcmTunnelingGuard) { + loggedDecodedPcmTunnelingGuard = true + emitLog("warn", "audio", "Decoded $passthroughSrcMime PCM initialized with tunneling=true; forcing tunneling off") } - tunnelingDisabledForDecodedTrueHdPcm = true - updateTunnelingState("decoded TrueHD PCM tunneling guard", forceSelector = true) - } else if (!isPcmEncoding(audioTrackConfig.encoding) && tunnelingDisabledForDecodedTrueHdPcm) { - tunnelingDisabledForDecodedTrueHdPcm = false - updateTunnelingState("encoded TrueHD output initialized", forceSelector = true) + tunnelingDisabledForDecodedPcm = true + updateTunnelingState("decoded PCM tunneling guard", forceSelector = true) + } else if (!isPcmEncoding(audioTrackConfig.encoding) && tunnelingDisabledForDecodedPcm) { + tunnelingDisabledForDecodedPcm = false + updateTunnelingState("encoded passthrough output initialized", forceSelector = true) } } // Re-key the normalization effect to the actual output channel count @@ -2735,7 +2743,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { loggedNativeDvFirstFrame = false loggedDvPlaybackPathKey = null lastDvPlaybackInfo = null - loggedDecodedTrueHdTunnelingGuard = false + loggedDecodedPcmTunnelingGuard = false updateAudioDecoderPolicy("open") currentMediaUri = uri currentHeaders = headers @@ -2781,7 +2789,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { } tunnelingDisabledForAudioCodec = false tunnelingDisabledForVideoCodec = false - tunnelingDisabledForDecodedTrueHdPcm = false + tunnelingDisabledForDecodedPcm = false tunnelingDisabledForAudioRecovery = false tunnelingDisabledForAssSubtitles = false currentTunneledPlayback = false @@ -3508,7 +3516,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { if (player.playbackParameters.speed != 1f) return "Off (speed ≠ 1×)" if (audioNormalizationEnabled) return "Off (loudness normalization)" if (tunnelingDisabledForAudioRecovery) return "Off (audio recovery)" - if (tunnelingDisabledForDecodedTrueHdPcm) return "Off (decoded TrueHD PCM)" + if (tunnelingDisabledForDecodedPcm) return "Off (decoded PCM)" if (tunnelingDisabledForVideoCodec) return "Off (video codec unsupported)" if (tunnelingDisabledForAudioCodec) return "Off (no HW audio decoder)" if (tunnelingDisabledForAssSubtitles) return "Off (ASS subtitles active)" @@ -3562,7 +3570,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { loggedDirectAudioRecoveryBlocks.clear() tunnelingDisabledForAudioCodec = false tunnelingDisabledForVideoCodec = false - tunnelingDisabledForDecodedTrueHdPcm = false + tunnelingDisabledForDecodedPcm = false tunnelingDisabledForAudioRecovery = false tunnelingDisabledForAssSubtitles = false currentTunneledPlayback = false diff --git a/lib/i18n/bg.i18n.json b/lib/i18n/bg.i18n.json index 5d1919db..0d7261b2 100644 --- a/lib/i18n/bg.i18n.json +++ b/lib/i18n/bg.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Забавяне при смяна на дисплея", "tunneledPlayback": "Тунелно възпроизвеждане", "tunneledPlaybackDescription": "Използвай видео тунелиране. Изключете, ако HDR възпроизвеждането показва черен екран.", + "audioPassthrough": "Аудио passthrough", + "audioPassthroughDescription": "Изпращай Dolby/DTS звук към ресийвъра или телевизора без прекодиране, запазвайки съраунд звука. Изключете, ако няма звук.", "dvConversionMode": "Dolby Vision конвертиране", "dvConversionModeDescription": "Изберете как ExoPlayer обработва Dolby Vision Profile 7 файлове.", "dvConversionAuto": "Автоматично", diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index 72e7b8c6..a0224f4b 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Forsinkelse ved skærmskift", "tunneledPlayback": "Tunneleret afspilning", "tunneledPlaybackDescription": "Brug videotunneling. Slå fra, hvis HDR-afspilning viser sort video.", + "audioPassthrough": "Lyd-passthrough", + "audioPassthroughDescription": "Send Dolby/DTS-lyd til din receiver eller dit TV uden genkodning, så surroundlyd bevares. Slå fra, hvis du ikke har lyd.", "dvConversionMode": "Dolby Vision-konvertering", "dvConversionModeDescription": "Vælg, hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 73728519..a07d3246 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Verzögerung beim Displaywechsel", "tunneledPlayback": "Tunnelwiedergabe", "tunneledPlaybackDescription": "Video-Tunneling verwenden. Deaktivieren, wenn HDR-Wiedergabe schwarzes Video zeigt.", + "audioPassthrough": "Audio-Durchleitung", + "audioPassthroughDescription": "Dolby/DTS-Audio ohne Neukodierung an deinen Receiver oder Fernseher senden und Surround-Sound erhalten. Deaktivieren, wenn kein Ton zu hören ist.", "dvConversionMode": "Dolby-Vision-Konvertierung", "dvConversionModeDescription": "Wähle, wie ExoPlayer Dolby-Vision-Profil-7-Dateien behandelt.", "dvConversionAuto": "Automatisch", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 9c82b6d4..80cea061 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -268,6 +268,8 @@ "displaySwitchDelay": "Display Switch Delay", "tunneledPlayback": "Tunneled Playback", "tunneledPlaybackDescription": "Use video tunneling. Disable if HDR playback shows black video.", + "audioPassthrough": "Audio Passthrough", + "audioPassthroughDescription": "Send Dolby/DTS audio to your receiver or TV without re-encoding, preserving surround sound. Turn off if you have no sound.", "dvConversionMode": "Dolby Vision Conversion", "dvConversionModeDescription": "Choose how ExoPlayer handles Dolby Vision Profile 7 files.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 1d70f5b3..473d7996 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Retraso de cambio de pantalla", "tunneledPlayback": "Reproducción tunelizada", "tunneledPlaybackDescription": "Usar tunelización de video. Desactívala si HDR muestra video negro.", + "audioPassthrough": "Audio Passthrough", + "audioPassthroughDescription": "Envía el audio Dolby/DTS a tu receptor o TV sin recodificar, conservando el sonido envolvente. Desactívalo si no tienes sonido.", "dvConversionMode": "Conversión de Dolby Vision", "dvConversionModeDescription": "Elige cómo ExoPlayer gestiona archivos Dolby Vision Profile 7.", "dvConversionAuto": "Automático", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index e09af021..590d65ad 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Délai de changement d'affichage", "tunneledPlayback": "Lecture tunnelée", "tunneledPlaybackDescription": "Utiliser le tunneling vidéo. Désactivez si la lecture HDR affiche un écran noir.", + "audioPassthrough": "Audio Pass-Through", + "audioPassthroughDescription": "Envoyez l'audio Dolby/DTS vers votre ampli ou téléviseur sans réencodage, en conservant le son surround. Désactivez si vous n'avez aucun son.", "dvConversionMode": "Conversion Dolby Vision", "dvConversionModeDescription": "Choisissez comment ExoPlayer gère les fichiers Dolby Vision Profile 7.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 22c1d99d..c65e0d7c 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Ritardo cambio display", "tunneledPlayback": "Riproduzione tunnelizzata", "tunneledPlaybackDescription": "Usa tunneling video. Disattiva se la riproduzione HDR mostra video nero.", + "audioPassthrough": "Audio Passthrough", + "audioPassthroughDescription": "Invia l'audio Dolby/DTS al ricevitore o alla TV senza ricodifica, mantenendo il suono surround. Disattiva se non senti audio.", "dvConversionMode": "Conversione Dolby Vision", "dvConversionModeDescription": "Scegli come ExoPlayer gestisce i file Dolby Vision Profile 7.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index b4b34bc1..1f4ab59b 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "ディスプレイ切り替え遅延", "tunneledPlayback": "トンネル再生", "tunneledPlaybackDescription": "動画トンネリングを使用します。HDR再生で画面が黒くなる場合は無効にしてください。", + "audioPassthrough": "オーディオパススルー", + "audioPassthroughDescription": "Dolby/DTS音声を再エンコードせずにレシーバーやテレビに送り、サラウンドを維持します。音が出ない場合は無効にしてください。", "dvConversionMode": "Dolby Vision 変換", "dvConversionModeDescription": "ExoPlayer が Dolby Vision Profile 7 ファイルを処理する方法を選択します。", "dvConversionAuto": "自動", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 82fb7d23..460694a6 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "디스플레이 전환 지연", "tunneledPlayback": "터널 재생", "tunneledPlaybackDescription": "비디오 터널링을 사용합니다. HDR 재생 시 검은 화면이 보이면 비활성화하세요.", + "audioPassthrough": "오디오 패스스루", + "audioPassthroughDescription": "Dolby/DTS 오디오를 재인코딩 없이 리시버나 TV로 전송하여 서라운드 사운드를 유지합니다. 소리가 나지 않으면 비활성화하세요.", "dvConversionMode": "Dolby Vision 변환", "dvConversionModeDescription": "ExoPlayer가 Dolby Vision Profile 7 파일을 처리하는 방식을 선택합니다.", "dvConversionAuto": "자동", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 774b8099..698a7b42 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Forsinkelse ved skjermbytte", "tunneledPlayback": "Tunnelert avspilling", "tunneledPlaybackDescription": "Bruk videotunneling. Slå av hvis HDR-avspilling viser svart video.", + "audioPassthrough": "Lydgjennomgang", + "audioPassthroughDescription": "Send Dolby/DTS-lyd til mottakeren eller TV-en uten omkoding, slik at surroundlyd bevares. Slå av hvis du ikke har lyd.", "dvConversionMode": "Dolby Vision-konvertering", "dvConversionModeDescription": "Velg hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index ef2c4446..584f86ca 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Vertraging bij schermwisseling", "tunneledPlayback": "Getunnelde weergave", "tunneledPlaybackDescription": "Gebruik videotunneling. Schakel uit als HDR-afspelen zwart beeld geeft.", + "audioPassthrough": "Audio-doorvoer", + "audioPassthroughDescription": "Stuur Dolby/DTS-audio zonder hercodering naar je receiver of tv en behoud surroundgeluid. Schakel uit als je geen geluid hebt.", "dvConversionMode": "Dolby Vision-conversie", "dvConversionModeDescription": "Kies hoe ExoPlayer Dolby Vision Profile 7-bestanden verwerkt.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index bd055b63..95120a53 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Opóźnienie przełączania ekranu", "tunneledPlayback": "Tunelowane odtwarzanie", "tunneledPlaybackDescription": "Użyj tunelowania wideo. Wyłącz, jeśli HDR pokazuje czarny obraz.", + "audioPassthrough": "Bezpośrednie audio", + "audioPassthroughDescription": "Wysyłaj dźwięk Dolby/DTS do amplitunera lub telewizora bez ponownego kodowania, zachowując dźwięk przestrzenny. Wyłącz, jeśli nie ma dźwięku.", "dvConversionMode": "Konwersja Dolby Vision", "dvConversionModeDescription": "Wybierz, jak ExoPlayer obsługuje pliki Dolby Vision Profile 7.", "dvConversionAuto": "Automatycznie", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index c71d932e..485f8cd2 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Atraso na Troca de Tela", "tunneledPlayback": "Reprodução Tunelizada", "tunneledPlaybackDescription": "Usar tunelamento de vídeo. Desative se HDR mostrar vídeo preto.", + "audioPassthrough": "Passagem de Áudio", + "audioPassthroughDescription": "Envie áudio Dolby/DTS para o seu receptor ou TV sem recodificar, preservando o som surround. Desative se não tiver som.", "dvConversionMode": "Conversão Dolby Vision", "dvConversionModeDescription": "Escolha como o ExoPlayer lida com arquivos Dolby Vision Profile 7.", "dvConversionAuto": "Automático", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index 989b48f0..e4d9cb91 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Задержка переключения дисплея", "tunneledPlayback": "Туннельное воспроизведение", "tunneledPlaybackDescription": "Использовать видеотуннелирование. Отключите, если HDR показывает черный экран.", + "audioPassthrough": "Сквозной вывод аудио", + "audioPassthroughDescription": "Передавать звук Dolby/DTS на ресивер или телевизор без перекодирования, сохраняя объёмный звук. Отключите, если нет звука.", "dvConversionMode": "Преобразование Dolby Vision", "dvConversionModeDescription": "Выберите, как ExoPlayer обрабатывает файлы Dolby Vision Profile 7.", "dvConversionAuto": "Авто", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 27abf0a3..092b9cdd 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,7 +4,7 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 16 -/// Strings: 20441 (1277 per locale) +/// Strings: 20473 (1279 per locale) // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/i18n/strings_bg.g.dart b/lib/i18n/strings_bg.g.dart index 0188d043..037ea6f4 100644 --- a/lib/i18n/strings_bg.g.dart +++ b/lib/i18n/strings_bg.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsBg extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Забавяне при смяна на дисплея'; @override String get tunneledPlayback => 'Тунелно възпроизвеждане'; @override String get tunneledPlaybackDescription => 'Използвай видео тунелиране. Изключете, ако HDR възпроизвеждането показва черен екран.'; + @override String get audioPassthrough => 'Аудио passthrough'; + @override String get audioPassthroughDescription => 'Изпращай Dolby/DTS звук към ресийвъра или телевизора без прекодиране, запазвайки съраунд звука. Изключете, ако няма звук.'; @override String get dvConversionMode => 'Dolby Vision конвертиране'; @override String get dvConversionModeDescription => 'Изберете как ExoPlayer обработва Dolby Vision Profile 7 файлове.'; @override String get dvConversionAuto => 'Автоматично'; @@ -2178,6 +2180,8 @@ extension on TranslationsBg { 'settings.displaySwitchDelay' => 'Забавяне при смяна на дисплея', 'settings.tunneledPlayback' => 'Тунелно възпроизвеждане', 'settings.tunneledPlaybackDescription' => 'Използвай видео тунелиране. Изключете, ако HDR възпроизвеждането показва черен екран.', + 'settings.audioPassthrough' => 'Аудио passthrough', + 'settings.audioPassthroughDescription' => 'Изпращай Dolby/DTS звук към ресийвъра или телевизора без прекодиране, запазвайки съраунд звука. Изключете, ако няма звук.', 'settings.dvConversionMode' => 'Dolby Vision конвертиране', 'settings.dvConversionModeDescription' => 'Изберете как ExoPlayer обработва Dolby Vision Profile 7 файлове.', 'settings.dvConversionAuto' => 'Автоматично', @@ -2436,10 +2440,10 @@ extension on TranslationsBg { 'messages.serverLimitTitle' => 'Възпроизвеждането е неуспешно', 'messages.serverLimitBody' => 'Грешка на сървъра (HTTP 500). Вероятно лимит за пропускателна способност/транскодиране е отхвърлил тази сесия. Помолете собственика да го коригира.', 'messages.logsUploaded' => 'Логовете са качени', - 'messages.logsUploadFailed' => 'Неуспешно качване на логовете', - 'messages.logId' => 'ID на лога', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Неуспешно качване на логовете', + 'messages.logId' => 'ID на лога', 'subtitlingStyling.text' => 'Текст', 'subtitlingStyling.border' => 'Рамка', 'subtitlingStyling.background' => 'Фон', @@ -2950,10 +2954,10 @@ extension on TranslationsBg { 'companionRemote.pairing.connectionTimedOut' => 'Връзката изтече. Използвайте една и съща мрежа на двете устройства.', 'companionRemote.pairing.sessionNotFound' => 'Устройството не е намерено. Уверете се, че Plezy работи на хоста.', 'companionRemote.pairing.authFailed' => 'Удостоверяването е неуспешно. Двете устройства трябва да използват същия Plex акаунт.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Неуспешно свързване: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Искате ли да прекъснете връзката с дистанционната сесия?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Неуспешно свързване: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Искате ли да прекъснете връзката с дистанционната сесия?', 'companionRemote.remote.reconnecting' => 'Повторно свързване...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Опит ${current} от 5', 'companionRemote.remote.retryNow' => 'Опитай сега', diff --git a/lib/i18n/strings_da.g.dart b/lib/i18n/strings_da.g.dart index eeac4fc1..454eab55 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsDa extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Forsinkelse ved skærmskift'; @override String get tunneledPlayback => 'Tunneleret afspilning'; @override String get tunneledPlaybackDescription => 'Brug videotunneling. Slå fra, hvis HDR-afspilning viser sort video.'; + @override String get audioPassthrough => 'Lyd-passthrough'; + @override String get audioPassthroughDescription => 'Send Dolby/DTS-lyd til din receiver eller dit TV uden genkodning, så surroundlyd bevares. Slå fra, hvis du ikke har lyd.'; @override String get dvConversionMode => 'Dolby Vision-konvertering'; @override String get dvConversionModeDescription => 'Vælg, hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsDa { 'settings.displaySwitchDelay' => 'Forsinkelse ved skærmskift', 'settings.tunneledPlayback' => 'Tunneleret afspilning', 'settings.tunneledPlaybackDescription' => 'Brug videotunneling. Slå fra, hvis HDR-afspilning viser sort video.', + 'settings.audioPassthrough' => 'Lyd-passthrough', + 'settings.audioPassthroughDescription' => 'Send Dolby/DTS-lyd til din receiver eller dit TV uden genkodning, så surroundlyd bevares. Slå fra, hvis du ikke har lyd.', 'settings.dvConversionMode' => 'Dolby Vision-konvertering', 'settings.dvConversionModeDescription' => 'Vælg, hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsDa { 'messages.serverLimitTitle' => 'Afspilning mislykkedes', 'messages.serverLimitBody' => 'Serverfejl (HTTP 500). En båndbredde-/transkodningsgrænse afviste nok sessionen. Bed ejeren om at justere den.', 'messages.logsUploaded' => 'Logs uploadet', - 'messages.logsUploadFailed' => 'Kunne ikke uploade logs', - 'messages.logId' => 'Log-ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Kunne ikke uploade logs', + 'messages.logId' => 'Log-ID', 'subtitlingStyling.text' => 'Tekst', 'subtitlingStyling.border' => 'Kant', 'subtitlingStyling.background' => 'Baggrund', @@ -2950,10 +2954,10 @@ extension on TranslationsDa { 'companionRemote.pairing.connectionTimedOut' => 'Forbindelsen fik timeout. Brug samme netværk på begge enheder.', 'companionRemote.pairing.sessionNotFound' => 'Enhed ikke fundet. Sørg for, at Plezy kører på værten.', 'companionRemote.pairing.authFailed' => 'Godkendelse mislykkedes. Begge enheder skal bruge samme Plex-konto.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunne ikke oprette forbindelse: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Vil du afbryde fra fjernsessionen?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunne ikke oprette forbindelse: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Vil du afbryde fra fjernsessionen?', 'companionRemote.remote.reconnecting' => 'Genopretter forbindelse...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Forsøg ${current} af 5', 'companionRemote.remote.retryNow' => 'Prøv igen nu', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 333e81a5..6c73c5bb 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsDe extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Verzögerung beim Displaywechsel'; @override String get tunneledPlayback => 'Tunnelwiedergabe'; @override String get tunneledPlaybackDescription => 'Video-Tunneling verwenden. Deaktivieren, wenn HDR-Wiedergabe schwarzes Video zeigt.'; + @override String get audioPassthrough => 'Audio-Durchleitung'; + @override String get audioPassthroughDescription => 'Dolby/DTS-Audio ohne Neukodierung an deinen Receiver oder Fernseher senden und Surround-Sound erhalten. Deaktivieren, wenn kein Ton zu hören ist.'; @override String get dvConversionMode => 'Dolby-Vision-Konvertierung'; @override String get dvConversionModeDescription => 'Wähle, wie ExoPlayer Dolby-Vision-Profil-7-Dateien behandelt.'; @override String get dvConversionAuto => 'Automatisch'; @@ -2178,6 +2180,8 @@ extension on TranslationsDe { 'settings.displaySwitchDelay' => 'Verzögerung beim Displaywechsel', 'settings.tunneledPlayback' => 'Tunnelwiedergabe', 'settings.tunneledPlaybackDescription' => 'Video-Tunneling verwenden. Deaktivieren, wenn HDR-Wiedergabe schwarzes Video zeigt.', + 'settings.audioPassthrough' => 'Audio-Durchleitung', + 'settings.audioPassthroughDescription' => 'Dolby/DTS-Audio ohne Neukodierung an deinen Receiver oder Fernseher senden und Surround-Sound erhalten. Deaktivieren, wenn kein Ton zu hören ist.', 'settings.dvConversionMode' => 'Dolby-Vision-Konvertierung', 'settings.dvConversionModeDescription' => 'Wähle, wie ExoPlayer Dolby-Vision-Profil-7-Dateien behandelt.', 'settings.dvConversionAuto' => 'Automatisch', @@ -2436,10 +2440,10 @@ extension on TranslationsDe { 'messages.serverLimitTitle' => 'Wiedergabe fehlgeschlagen', 'messages.serverLimitBody' => 'Serverfehler (HTTP 500). Ein Bandbreiten-/Transcoding-Limit lehnte diese Sitzung wohl ab. Bitte den Besitzer um Anpassung.', 'messages.logsUploaded' => 'Protokolle hochgeladen', - 'messages.logsUploadFailed' => 'Protokolle konnten nicht hochgeladen werden', - 'messages.logId' => 'Protokoll-ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Protokolle konnten nicht hochgeladen werden', + 'messages.logId' => 'Protokoll-ID', 'subtitlingStyling.text' => 'Text', 'subtitlingStyling.border' => 'Rahmen', 'subtitlingStyling.background' => 'Hintergrund', @@ -2950,10 +2954,10 @@ extension on TranslationsDe { 'companionRemote.pairing.connectionTimedOut' => 'Verbindung hat Zeitlimit überschritten. Nutze auf beiden Geräten dasselbe Netzwerk.', 'companionRemote.pairing.sessionNotFound' => 'Gerät nicht gefunden. Stelle sicher, dass Plezy auf dem Host läuft.', 'companionRemote.pairing.authFailed' => 'Authentifizierung fehlgeschlagen. Beide Geräte benötigen dasselbe Plex-Konto.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Verbindung fehlgeschlagen: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Möchtest du die Verbindung zur Fernsteuerungssitzung trennen?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Verbindung fehlgeschlagen: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Möchtest du die Verbindung zur Fernsteuerungssitzung trennen?', 'companionRemote.remote.reconnecting' => 'Verbindung wird wiederhergestellt...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Versuch ${current} von 5', 'companionRemote.remote.retryNow' => 'Jetzt wiederholen', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 5a45e782..d0d2ec68 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -915,6 +915,12 @@ class TranslationsSettingsEn { /// en: 'Use video tunneling. Disable if HDR playback shows black video.' String get tunneledPlaybackDescription => 'Use video tunneling. Disable if HDR playback shows black video.'; + /// en: 'Audio Passthrough' + String get audioPassthrough => 'Audio Passthrough'; + + /// en: 'Send Dolby/DTS audio to your receiver or TV without re-encoding, preserving surround sound. Turn off if you have no sound.' + String get audioPassthroughDescription => 'Send Dolby/DTS audio to your receiver or TV without re-encoding, preserving surround sound. Turn off if you have no sound.'; + /// en: 'Dolby Vision Conversion' String get dvConversionMode => 'Dolby Vision Conversion'; @@ -4771,6 +4777,8 @@ extension on Translations { 'settings.displaySwitchDelay' => 'Display Switch Delay', 'settings.tunneledPlayback' => 'Tunneled Playback', 'settings.tunneledPlaybackDescription' => 'Use video tunneling. Disable if HDR playback shows black video.', + 'settings.audioPassthrough' => 'Audio Passthrough', + 'settings.audioPassthroughDescription' => 'Send Dolby/DTS audio to your receiver or TV without re-encoding, preserving surround sound. Turn off if you have no sound.', 'settings.dvConversionMode' => 'Dolby Vision Conversion', 'settings.dvConversionModeDescription' => 'Choose how ExoPlayer handles Dolby Vision Profile 7 files.', 'settings.dvConversionAuto' => 'Auto', @@ -5023,10 +5031,10 @@ extension on Translations { 'messages.noResultsFound' => 'No results found', 'messages.sleepTimerSet' => ({required Object label}) => 'Sleep timer set for ${label}', 'messages.noItemsAvailable' => 'No items available', - 'messages.failedToCreatePlayQueueNoItems' => 'Failed to create play queue - no items', - 'messages.failedPlayback' => ({required Object action, required Object error}) => 'Failed to ${action}: ${error}', _ => null, } ?? switch (path) { + 'messages.failedToCreatePlayQueueNoItems' => 'Failed to create play queue - no items', + 'messages.failedPlayback' => ({required Object action, required Object error}) => 'Failed to ${action}: ${error}', 'messages.switchingToCompatiblePlayer' => 'Switching to compatible player...', 'messages.serverLimitTitle' => 'Playback failed', 'messages.serverLimitBody' => 'Server error (HTTP 500). A bandwidth/transcoding limit likely rejected this session. Ask the owner to adjust it.', @@ -5537,10 +5545,10 @@ extension on Translations { 'companionRemote.pairing.connecting' => 'Connecting...', 'companionRemote.pairing.searchingForDevices' => 'Looking for devices...', 'companionRemote.pairing.noDevicesFound' => 'No devices found on your network', - 'companionRemote.pairing.noDevicesHint' => 'Open Plezy on desktop and use the same WiFi', - 'companionRemote.pairing.availableDevices' => 'Available Devices', _ => null, } ?? switch (path) { + 'companionRemote.pairing.noDevicesHint' => 'Open Plezy on desktop and use the same WiFi', + 'companionRemote.pairing.availableDevices' => 'Available Devices', 'companionRemote.pairing.manualConnection' => 'Manual Connection', 'companionRemote.pairing.cryptoInitFailed' => 'Couldn\'t start secure connection. Sign in to Plex first.', 'companionRemote.pairing.validationHostRequired' => 'Please enter host address', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index aa92073c..fff76343 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsEs extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Retraso de cambio de pantalla'; @override String get tunneledPlayback => 'Reproducción tunelizada'; @override String get tunneledPlaybackDescription => 'Usar tunelización de video. Desactívala si HDR muestra video negro.'; + @override String get audioPassthrough => 'Audio Passthrough'; + @override String get audioPassthroughDescription => 'Envía el audio Dolby/DTS a tu receptor o TV sin recodificar, conservando el sonido envolvente. Desactívalo si no tienes sonido.'; @override String get dvConversionMode => 'Conversión de Dolby Vision'; @override String get dvConversionModeDescription => 'Elige cómo ExoPlayer gestiona archivos Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Automático'; @@ -2178,6 +2180,8 @@ extension on TranslationsEs { 'settings.displaySwitchDelay' => 'Retraso de cambio de pantalla', 'settings.tunneledPlayback' => 'Reproducción tunelizada', 'settings.tunneledPlaybackDescription' => 'Usar tunelización de video. Desactívala si HDR muestra video negro.', + 'settings.audioPassthrough' => 'Audio Passthrough', + 'settings.audioPassthroughDescription' => 'Envía el audio Dolby/DTS a tu receptor o TV sin recodificar, conservando el sonido envolvente. Desactívalo si no tienes sonido.', 'settings.dvConversionMode' => 'Conversión de Dolby Vision', 'settings.dvConversionModeDescription' => 'Elige cómo ExoPlayer gestiona archivos Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Automático', @@ -2436,10 +2440,10 @@ extension on TranslationsEs { 'messages.serverLimitTitle' => 'Error de reproducción', 'messages.serverLimitBody' => 'Error del servidor (HTTP 500). Un límite de ancho de banda/transcodificación probablemente rechazó esta sesión. Pide al propietario que lo ajuste.', 'messages.logsUploaded' => 'Registros subidos', - 'messages.logsUploadFailed' => 'Error al subir registros', - 'messages.logId' => 'ID de registro', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Error al subir registros', + 'messages.logId' => 'ID de registro', 'subtitlingStyling.text' => 'Texto', 'subtitlingStyling.border' => 'Borde', 'subtitlingStyling.background' => 'Fondo', @@ -2950,10 +2954,10 @@ extension on TranslationsEs { 'companionRemote.pairing.connectionTimedOut' => 'Tiempo de conexión agotado. Usa la misma red en ambos dispositivos.', 'companionRemote.pairing.sessionNotFound' => 'Dispositivo no encontrado. Asegúrate de que Plezy esté en ejecución en el host.', 'companionRemote.pairing.authFailed' => 'Autenticación fallida. Ambos dispositivos necesitan la misma cuenta Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Error al conectar: ${error}', - 'companionRemote.remote.disconnectConfirm' => '¿Quieres desconectarte de la sesión remota?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Error al conectar: ${error}', + 'companionRemote.remote.disconnectConfirm' => '¿Quieres desconectarte de la sesión remota?', 'companionRemote.remote.reconnecting' => 'Reconectando...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Intento ${current} de 5', 'companionRemote.remote.retryNow' => 'Reintentar ahora', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 92de6494..841abb99 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsFr extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Délai de changement d\'affichage'; @override String get tunneledPlayback => 'Lecture tunnelée'; @override String get tunneledPlaybackDescription => 'Utiliser le tunneling vidéo. Désactivez si la lecture HDR affiche un écran noir.'; + @override String get audioPassthrough => 'Audio Pass-Through'; + @override String get audioPassthroughDescription => 'Envoyez l\'audio Dolby/DTS vers votre ampli ou téléviseur sans réencodage, en conservant le son surround. Désactivez si vous n\'avez aucun son.'; @override String get dvConversionMode => 'Conversion Dolby Vision'; @override String get dvConversionModeDescription => 'Choisissez comment ExoPlayer gère les fichiers Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsFr { 'settings.displaySwitchDelay' => 'Délai de changement d\'affichage', 'settings.tunneledPlayback' => 'Lecture tunnelée', 'settings.tunneledPlaybackDescription' => 'Utiliser le tunneling vidéo. Désactivez si la lecture HDR affiche un écran noir.', + 'settings.audioPassthrough' => 'Audio Pass-Through', + 'settings.audioPassthroughDescription' => 'Envoyez l\'audio Dolby/DTS vers votre ampli ou téléviseur sans réencodage, en conservant le son surround. Désactivez si vous n\'avez aucun son.', 'settings.dvConversionMode' => 'Conversion Dolby Vision', 'settings.dvConversionModeDescription' => 'Choisissez comment ExoPlayer gère les fichiers Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsFr { 'messages.serverLimitTitle' => 'Échec de la lecture', 'messages.serverLimitBody' => 'Erreur serveur (HTTP 500). Une limite de bande passante/transcodage a probablement rejeté cette session. Demandez au propriétaire de l\'ajuster.', 'messages.logsUploaded' => 'Logs envoyés', - 'messages.logsUploadFailed' => 'Échec de l\'envoi des logs', - 'messages.logId' => 'ID du log', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Échec de l\'envoi des logs', + 'messages.logId' => 'ID du log', 'subtitlingStyling.text' => 'Texte', 'subtitlingStyling.border' => 'Bordure', 'subtitlingStyling.background' => 'Arrière-plan', @@ -2950,10 +2954,10 @@ extension on TranslationsFr { 'companionRemote.pairing.connectionTimedOut' => 'Connexion expirée. Utilisez le même réseau sur les deux appareils.', 'companionRemote.pairing.sessionNotFound' => 'Appareil introuvable. Assurez-vous que Plezy fonctionne sur l\'hôte.', 'companionRemote.pairing.authFailed' => 'Échec de l\'authentification. Les deux appareils doivent utiliser le même compte Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Échec de la connexion : ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Voulez-vous vous déconnecter de la session distante ?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Échec de la connexion : ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Voulez-vous vous déconnecter de la session distante ?', 'companionRemote.remote.reconnecting' => 'Reconnexion...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Tentative ${current} sur 5', 'companionRemote.remote.retryNow' => 'Réessayer maintenant', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index da222c09..f4d15b32 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsIt extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Ritardo cambio display'; @override String get tunneledPlayback => 'Riproduzione tunnelizzata'; @override String get tunneledPlaybackDescription => 'Usa tunneling video. Disattiva se la riproduzione HDR mostra video nero.'; + @override String get audioPassthrough => 'Audio Passthrough'; + @override String get audioPassthroughDescription => 'Invia l\'audio Dolby/DTS al ricevitore o alla TV senza ricodifica, mantenendo il suono surround. Disattiva se non senti audio.'; @override String get dvConversionMode => 'Conversione Dolby Vision'; @override String get dvConversionModeDescription => 'Scegli come ExoPlayer gestisce i file Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsIt { 'settings.displaySwitchDelay' => 'Ritardo cambio display', 'settings.tunneledPlayback' => 'Riproduzione tunnelizzata', 'settings.tunneledPlaybackDescription' => 'Usa tunneling video. Disattiva se la riproduzione HDR mostra video nero.', + 'settings.audioPassthrough' => 'Audio Passthrough', + 'settings.audioPassthroughDescription' => 'Invia l\'audio Dolby/DTS al ricevitore o alla TV senza ricodifica, mantenendo il suono surround. Disattiva se non senti audio.', 'settings.dvConversionMode' => 'Conversione Dolby Vision', 'settings.dvConversionModeDescription' => 'Scegli come ExoPlayer gestisce i file Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsIt { 'messages.serverLimitTitle' => 'Riproduzione non riuscita', 'messages.serverLimitBody' => 'Errore server (HTTP 500). Un limite di banda/transcodifica probabilmente ha rifiutato questa sessione. Chiedi al proprietario di modificarlo.', 'messages.logsUploaded' => 'Log caricati', - 'messages.logsUploadFailed' => 'Caricamento log fallito', - 'messages.logId' => 'ID log', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Caricamento log fallito', + 'messages.logId' => 'ID log', 'subtitlingStyling.text' => 'Testo', 'subtitlingStyling.border' => 'Bordo', 'subtitlingStyling.background' => 'Sfondo', @@ -2950,10 +2954,10 @@ extension on TranslationsIt { 'companionRemote.pairing.connectionTimedOut' => 'Connessione scaduta. Usa la stessa rete su entrambi i dispositivi.', 'companionRemote.pairing.sessionNotFound' => 'Dispositivo non trovato. Assicurati che Plezy sia in esecuzione sull\'host.', 'companionRemote.pairing.authFailed' => 'Autenticazione non riuscita. Entrambi i dispositivi devono usare lo stesso account Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Connessione fallita: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Vuoi disconnetterti dalla sessione remota?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Connessione fallita: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Vuoi disconnetterti dalla sessione remota?', 'companionRemote.remote.reconnecting' => 'Riconnessione...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Tentativo ${current} di 5', 'companionRemote.remote.retryNow' => 'Riprova ora', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index 7586d7d6..e497da3a 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsJa extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'ディスプレイ切り替え遅延'; @override String get tunneledPlayback => 'トンネル再生'; @override String get tunneledPlaybackDescription => '動画トンネリングを使用します。HDR再生で画面が黒くなる場合は無効にしてください。'; + @override String get audioPassthrough => 'オーディオパススルー'; + @override String get audioPassthroughDescription => 'Dolby/DTS音声を再エンコードせずにレシーバーやテレビに送り、サラウンドを維持します。音が出ない場合は無効にしてください。'; @override String get dvConversionMode => 'Dolby Vision 変換'; @override String get dvConversionModeDescription => 'ExoPlayer が Dolby Vision Profile 7 ファイルを処理する方法を選択します。'; @override String get dvConversionAuto => '自動'; @@ -2178,6 +2180,8 @@ extension on TranslationsJa { 'settings.displaySwitchDelay' => 'ディスプレイ切り替え遅延', 'settings.tunneledPlayback' => 'トンネル再生', 'settings.tunneledPlaybackDescription' => '動画トンネリングを使用します。HDR再生で画面が黒くなる場合は無効にしてください。', + 'settings.audioPassthrough' => 'オーディオパススルー', + 'settings.audioPassthroughDescription' => 'Dolby/DTS音声を再エンコードせずにレシーバーやテレビに送り、サラウンドを維持します。音が出ない場合は無効にしてください。', 'settings.dvConversionMode' => 'Dolby Vision 変換', 'settings.dvConversionModeDescription' => 'ExoPlayer が Dolby Vision Profile 7 ファイルを処理する方法を選択します。', 'settings.dvConversionAuto' => '自動', @@ -2436,10 +2440,10 @@ extension on TranslationsJa { 'messages.serverLimitTitle' => '再生に失敗しました', 'messages.serverLimitBody' => 'サーバーエラー(HTTP 500)。帯域幅/トランスコード制限により拒否された可能性があります。所有者に調整を依頼してください。', 'messages.logsUploaded' => 'ログをアップロードしました', - 'messages.logsUploadFailed' => 'ログのアップロードに失敗しました', - 'messages.logId' => 'ログID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'ログのアップロードに失敗しました', + 'messages.logId' => 'ログID', 'subtitlingStyling.text' => 'テキスト', 'subtitlingStyling.border' => '枠線', 'subtitlingStyling.background' => '背景', @@ -2950,10 +2954,10 @@ extension on TranslationsJa { 'companionRemote.pairing.connectionTimedOut' => '接続がタイムアウトしました。両方のデバイスで同じネットワークを使用してください。', 'companionRemote.pairing.sessionNotFound' => 'デバイスが見つかりません。ホストでPlezyが実行中か確認してください。', 'companionRemote.pairing.authFailed' => '認証に失敗しました。両方のデバイスで同じPlexアカウントが必要です。', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '接続に失敗しました: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'リモートセッションから切断しますか?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '接続に失敗しました: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'リモートセッションから切断しますか?', 'companionRemote.remote.reconnecting' => '再接続中...', 'companionRemote.remote.attemptOf' => ({required Object current}) => '試行 ${current}/5', 'companionRemote.remote.retryNow' => '今すぐ再試行', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index f0b39c35..f6f704cf 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsKo extends TranslationsSettingsEn { @override String get displaySwitchDelay => '디스플레이 전환 지연'; @override String get tunneledPlayback => '터널 재생'; @override String get tunneledPlaybackDescription => '비디오 터널링을 사용합니다. HDR 재생 시 검은 화면이 보이면 비활성화하세요.'; + @override String get audioPassthrough => '오디오 패스스루'; + @override String get audioPassthroughDescription => 'Dolby/DTS 오디오를 재인코딩 없이 리시버나 TV로 전송하여 서라운드 사운드를 유지합니다. 소리가 나지 않으면 비활성화하세요.'; @override String get dvConversionMode => 'Dolby Vision 변환'; @override String get dvConversionModeDescription => 'ExoPlayer가 Dolby Vision Profile 7 파일을 처리하는 방식을 선택합니다.'; @override String get dvConversionAuto => '자동'; @@ -2178,6 +2180,8 @@ extension on TranslationsKo { 'settings.displaySwitchDelay' => '디스플레이 전환 지연', 'settings.tunneledPlayback' => '터널 재생', 'settings.tunneledPlaybackDescription' => '비디오 터널링을 사용합니다. HDR 재생 시 검은 화면이 보이면 비활성화하세요.', + 'settings.audioPassthrough' => '오디오 패스스루', + 'settings.audioPassthroughDescription' => 'Dolby/DTS 오디오를 재인코딩 없이 리시버나 TV로 전송하여 서라운드 사운드를 유지합니다. 소리가 나지 않으면 비활성화하세요.', 'settings.dvConversionMode' => 'Dolby Vision 변환', 'settings.dvConversionModeDescription' => 'ExoPlayer가 Dolby Vision Profile 7 파일을 처리하는 방식을 선택합니다.', 'settings.dvConversionAuto' => '자동', @@ -2436,10 +2440,10 @@ extension on TranslationsKo { 'messages.serverLimitTitle' => '재생 실패', 'messages.serverLimitBody' => '서버 오류(HTTP 500). 대역폭/트랜스코딩 제한으로 세션이 거부된 것 같습니다. 소유자에게 조정을 요청하세요.', 'messages.logsUploaded' => '로그 업로드 완료', - 'messages.logsUploadFailed' => '로그 업로드 실패', - 'messages.logId' => '로그 ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => '로그 업로드 실패', + 'messages.logId' => '로그 ID', 'subtitlingStyling.text' => '텍스트', 'subtitlingStyling.border' => '테두리', 'subtitlingStyling.background' => '배경', @@ -2950,10 +2954,10 @@ extension on TranslationsKo { 'companionRemote.pairing.connectionTimedOut' => '연결 시간이 초과되었습니다. 두 기기에서 같은 네트워크를 사용하세요.', 'companionRemote.pairing.sessionNotFound' => '기기를 찾을 수 없습니다. 호스트에서 Plezy가 실행 중인지 확인하세요.', 'companionRemote.pairing.authFailed' => '인증에 실패했습니다. 두 기기 모두 같은 Plex 계정이 필요합니다.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '연결 실패: ${error}', - 'companionRemote.remote.disconnectConfirm' => '원격 세션 연결을 해제하시겠습니까?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '연결 실패: ${error}', + 'companionRemote.remote.disconnectConfirm' => '원격 세션 연결을 해제하시겠습니까?', 'companionRemote.remote.reconnecting' => '재연결 중...', 'companionRemote.remote.attemptOf' => ({required Object current}) => '${current}/5 시도 중', 'companionRemote.remote.retryNow' => '지금 재시도', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index b607daa1..8b36900c 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsNb extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Forsinkelse ved skjermbytte'; @override String get tunneledPlayback => 'Tunnelert avspilling'; @override String get tunneledPlaybackDescription => 'Bruk videotunneling. Slå av hvis HDR-avspilling viser svart video.'; + @override String get audioPassthrough => 'Lydgjennomgang'; + @override String get audioPassthroughDescription => 'Send Dolby/DTS-lyd til mottakeren eller TV-en uten omkoding, slik at surroundlyd bevares. Slå av hvis du ikke har lyd.'; @override String get dvConversionMode => 'Dolby Vision-konvertering'; @override String get dvConversionModeDescription => 'Velg hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsNb { 'settings.displaySwitchDelay' => 'Forsinkelse ved skjermbytte', 'settings.tunneledPlayback' => 'Tunnelert avspilling', 'settings.tunneledPlaybackDescription' => 'Bruk videotunneling. Slå av hvis HDR-avspilling viser svart video.', + 'settings.audioPassthrough' => 'Lydgjennomgang', + 'settings.audioPassthroughDescription' => 'Send Dolby/DTS-lyd til mottakeren eller TV-en uten omkoding, slik at surroundlyd bevares. Slå av hvis du ikke har lyd.', 'settings.dvConversionMode' => 'Dolby Vision-konvertering', 'settings.dvConversionModeDescription' => 'Velg hvordan ExoPlayer håndterer Dolby Vision Profile 7-filer.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsNb { 'messages.serverLimitTitle' => 'Avspilling mislyktes', 'messages.serverLimitBody' => 'Serverfeil (HTTP 500). En båndbredde-/transkodingsgrense avviste trolig økten. Be eieren justere den.', 'messages.logsUploaded' => 'Logger lastet opp', - 'messages.logsUploadFailed' => 'Kunne ikke laste opp logger', - 'messages.logId' => 'Logg-ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Kunne ikke laste opp logger', + 'messages.logId' => 'Logg-ID', 'subtitlingStyling.text' => 'Tekst', 'subtitlingStyling.border' => 'Kantlinje', 'subtitlingStyling.background' => 'Bakgrunn', @@ -2950,10 +2954,10 @@ extension on TranslationsNb { 'companionRemote.pairing.connectionTimedOut' => 'Tilkoblingen fikk tidsavbrudd. Bruk samme nettverk på begge enheter.', 'companionRemote.pairing.sessionNotFound' => 'Enhet ikke funnet. Sørg for at Plezy kjører på verten.', 'companionRemote.pairing.authFailed' => 'Autentisering mislyktes. Begge enheter må bruke samme Plex-konto.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunne ikke koble til: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Vil du koble fra fjernøkten?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunne ikke koble til: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Vil du koble fra fjernøkten?', 'companionRemote.remote.reconnecting' => 'Kobler til på nytt...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Forsøk ${current} av 5', 'companionRemote.remote.retryNow' => 'Prøv nå', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 47bb1eea..583242e5 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsNl extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Vertraging bij schermwisseling'; @override String get tunneledPlayback => 'Getunnelde weergave'; @override String get tunneledPlaybackDescription => 'Gebruik videotunneling. Schakel uit als HDR-afspelen zwart beeld geeft.'; + @override String get audioPassthrough => 'Audio-doorvoer'; + @override String get audioPassthroughDescription => 'Stuur Dolby/DTS-audio zonder hercodering naar je receiver of tv en behoud surroundgeluid. Schakel uit als je geen geluid hebt.'; @override String get dvConversionMode => 'Dolby Vision-conversie'; @override String get dvConversionModeDescription => 'Kies hoe ExoPlayer Dolby Vision Profile 7-bestanden verwerkt.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsNl { 'settings.displaySwitchDelay' => 'Vertraging bij schermwisseling', 'settings.tunneledPlayback' => 'Getunnelde weergave', 'settings.tunneledPlaybackDescription' => 'Gebruik videotunneling. Schakel uit als HDR-afspelen zwart beeld geeft.', + 'settings.audioPassthrough' => 'Audio-doorvoer', + 'settings.audioPassthroughDescription' => 'Stuur Dolby/DTS-audio zonder hercodering naar je receiver of tv en behoud surroundgeluid. Schakel uit als je geen geluid hebt.', 'settings.dvConversionMode' => 'Dolby Vision-conversie', 'settings.dvConversionModeDescription' => 'Kies hoe ExoPlayer Dolby Vision Profile 7-bestanden verwerkt.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsNl { 'messages.serverLimitTitle' => 'Afspelen mislukt', 'messages.serverLimitBody' => 'Serverfout (HTTP 500). Waarschijnlijk weigerde een bandbreedte-/transcodeerlimiet deze sessie. Vraag de eigenaar dit aan te passen.', 'messages.logsUploaded' => 'Logs geüpload', - 'messages.logsUploadFailed' => 'Uploaden van logs mislukt', - 'messages.logId' => 'Log-ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Uploaden van logs mislukt', + 'messages.logId' => 'Log-ID', 'subtitlingStyling.text' => 'Tekst', 'subtitlingStyling.border' => 'Rand', 'subtitlingStyling.background' => 'Achtergrond', @@ -2950,10 +2954,10 @@ extension on TranslationsNl { 'companionRemote.pairing.connectionTimedOut' => 'Verbinding verlopen. Gebruik hetzelfde netwerk op beide apparaten.', 'companionRemote.pairing.sessionNotFound' => 'Apparaat niet gevonden. Zorg dat Plezy op de host draait.', 'companionRemote.pairing.authFailed' => 'Authenticatie mislukt. Beide apparaten hebben hetzelfde Plex-account nodig.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kan niet verbinden: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Wil je de verbinding met de externe sessie verbreken?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kan niet verbinden: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Wil je de verbinding met de externe sessie verbreken?', 'companionRemote.remote.reconnecting' => 'Opnieuw verbinden...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Poging ${current} van 5', 'companionRemote.remote.retryNow' => 'Nu opnieuw proberen', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index 58ad3c99..9253133b 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsPl extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Opóźnienie przełączania ekranu'; @override String get tunneledPlayback => 'Tunelowane odtwarzanie'; @override String get tunneledPlaybackDescription => 'Użyj tunelowania wideo. Wyłącz, jeśli HDR pokazuje czarny obraz.'; + @override String get audioPassthrough => 'Bezpośrednie audio'; + @override String get audioPassthroughDescription => 'Wysyłaj dźwięk Dolby/DTS do amplitunera lub telewizora bez ponownego kodowania, zachowując dźwięk przestrzenny. Wyłącz, jeśli nie ma dźwięku.'; @override String get dvConversionMode => 'Konwersja Dolby Vision'; @override String get dvConversionModeDescription => 'Wybierz, jak ExoPlayer obsługuje pliki Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Automatycznie'; @@ -2178,6 +2180,8 @@ extension on TranslationsPl { 'settings.displaySwitchDelay' => 'Opóźnienie przełączania ekranu', 'settings.tunneledPlayback' => 'Tunelowane odtwarzanie', 'settings.tunneledPlaybackDescription' => 'Użyj tunelowania wideo. Wyłącz, jeśli HDR pokazuje czarny obraz.', + 'settings.audioPassthrough' => 'Bezpośrednie audio', + 'settings.audioPassthroughDescription' => 'Wysyłaj dźwięk Dolby/DTS do amplitunera lub telewizora bez ponownego kodowania, zachowując dźwięk przestrzenny. Wyłącz, jeśli nie ma dźwięku.', 'settings.dvConversionMode' => 'Konwersja Dolby Vision', 'settings.dvConversionModeDescription' => 'Wybierz, jak ExoPlayer obsługuje pliki Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Automatycznie', @@ -2436,10 +2440,10 @@ extension on TranslationsPl { 'messages.serverLimitTitle' => 'Odtwarzanie nie powiodło się', 'messages.serverLimitBody' => 'Błąd serwera (HTTP 500). Limit przepustowości/transkodowania prawdopodobnie odrzucił tę sesję. Poproś właściciela o zmianę.', 'messages.logsUploaded' => 'Logi przesłane', - 'messages.logsUploadFailed' => 'Nie udało się przesłać logów', - 'messages.logId' => 'ID logu', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Nie udało się przesłać logów', + 'messages.logId' => 'ID logu', 'subtitlingStyling.text' => 'Tekst', 'subtitlingStyling.border' => 'Obramowanie', 'subtitlingStyling.background' => 'Tło', @@ -2950,10 +2954,10 @@ extension on TranslationsPl { 'companionRemote.pairing.connectionTimedOut' => 'Limit czasu połączenia. Użyj tej samej sieci na obu urządzeniach.', 'companionRemote.pairing.sessionNotFound' => 'Nie znaleziono urządzenia. Upewnij się, że Plezy działa na hoście.', 'companionRemote.pairing.authFailed' => 'Uwierzytelnianie nie powiodło się. Oba urządzenia muszą używać tego samego konta Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Nie udało się połączyć: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Czy chcesz się rozłączyć od sesji zdalnej?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Nie udało się połączyć: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Czy chcesz się rozłączyć od sesji zdalnej?', 'companionRemote.remote.reconnecting' => 'Ponowne łączenie...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Próba ${current} z 5', 'companionRemote.remote.retryNow' => 'Ponów teraz', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index 1e7498e5..5ec150c9 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsPt extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Atraso na Troca de Tela'; @override String get tunneledPlayback => 'Reprodução Tunelizada'; @override String get tunneledPlaybackDescription => 'Usar tunelamento de vídeo. Desative se HDR mostrar vídeo preto.'; + @override String get audioPassthrough => 'Passagem de Áudio'; + @override String get audioPassthroughDescription => 'Envie áudio Dolby/DTS para o seu receptor ou TV sem recodificar, preservando o som surround. Desative se não tiver som.'; @override String get dvConversionMode => 'Conversão Dolby Vision'; @override String get dvConversionModeDescription => 'Escolha como o ExoPlayer lida com arquivos Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Automático'; @@ -2178,6 +2180,8 @@ extension on TranslationsPt { 'settings.displaySwitchDelay' => 'Atraso na Troca de Tela', 'settings.tunneledPlayback' => 'Reprodução Tunelizada', 'settings.tunneledPlaybackDescription' => 'Usar tunelamento de vídeo. Desative se HDR mostrar vídeo preto.', + 'settings.audioPassthrough' => 'Passagem de Áudio', + 'settings.audioPassthroughDescription' => 'Envie áudio Dolby/DTS para o seu receptor ou TV sem recodificar, preservando o som surround. Desative se não tiver som.', 'settings.dvConversionMode' => 'Conversão Dolby Vision', 'settings.dvConversionModeDescription' => 'Escolha como o ExoPlayer lida com arquivos Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Automático', @@ -2436,10 +2440,10 @@ extension on TranslationsPt { 'messages.serverLimitTitle' => 'Falha na reprodução', 'messages.serverLimitBody' => 'Erro do servidor (HTTP 500). Um limite de largura de banda/transcodificação provavelmente rejeitou esta sessão. Peça ao dono para ajustar.', 'messages.logsUploaded' => 'Logs enviados', - 'messages.logsUploadFailed' => 'Falha ao enviar logs', - 'messages.logId' => 'ID do Log', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Falha ao enviar logs', + 'messages.logId' => 'ID do Log', 'subtitlingStyling.text' => 'Texto', 'subtitlingStyling.border' => 'Borda', 'subtitlingStyling.background' => 'Fundo', @@ -2950,10 +2954,10 @@ extension on TranslationsPt { 'companionRemote.pairing.connectionTimedOut' => 'Conexão expirou. Use a mesma rede nos dois dispositivos.', 'companionRemote.pairing.sessionNotFound' => 'Dispositivo não encontrado. Verifique se Plezy está rodando no host.', 'companionRemote.pairing.authFailed' => 'Falha na autenticação. Ambos os dispositivos precisam da mesma conta Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Falha ao conectar: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Deseja desconectar da sessão remota?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Falha ao conectar: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Deseja desconectar da sessão remota?', 'companionRemote.remote.reconnecting' => 'Reconectando...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Tentativa ${current} de 5', 'companionRemote.remote.retryNow' => 'Tentar Agora', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 42e0a4be..772a65b6 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsRu extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Задержка переключения дисплея'; @override String get tunneledPlayback => 'Туннельное воспроизведение'; @override String get tunneledPlaybackDescription => 'Использовать видеотуннелирование. Отключите, если HDR показывает черный экран.'; + @override String get audioPassthrough => 'Сквозной вывод аудио'; + @override String get audioPassthroughDescription => 'Передавать звук Dolby/DTS на ресивер или телевизор без перекодирования, сохраняя объёмный звук. Отключите, если нет звука.'; @override String get dvConversionMode => 'Преобразование Dolby Vision'; @override String get dvConversionModeDescription => 'Выберите, как ExoPlayer обрабатывает файлы Dolby Vision Profile 7.'; @override String get dvConversionAuto => 'Авто'; @@ -2178,6 +2180,8 @@ extension on TranslationsRu { 'settings.displaySwitchDelay' => 'Задержка переключения дисплея', 'settings.tunneledPlayback' => 'Туннельное воспроизведение', 'settings.tunneledPlaybackDescription' => 'Использовать видеотуннелирование. Отключите, если HDR показывает черный экран.', + 'settings.audioPassthrough' => 'Сквозной вывод аудио', + 'settings.audioPassthroughDescription' => 'Передавать звук Dolby/DTS на ресивер или телевизор без перекодирования, сохраняя объёмный звук. Отключите, если нет звука.', 'settings.dvConversionMode' => 'Преобразование Dolby Vision', 'settings.dvConversionModeDescription' => 'Выберите, как ExoPlayer обрабатывает файлы Dolby Vision Profile 7.', 'settings.dvConversionAuto' => 'Авто', @@ -2436,10 +2440,10 @@ extension on TranslationsRu { 'messages.serverLimitTitle' => 'Ошибка воспроизведения', 'messages.serverLimitBody' => 'Ошибка сервера (HTTP 500). Лимит пропускной способности/транскодирования, вероятно, отклонил сессию. Попросите владельца изменить настройки.', 'messages.logsUploaded' => 'Логи загружены', - 'messages.logsUploadFailed' => 'Не удалось загрузить логи', - 'messages.logId' => 'ID лога', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Не удалось загрузить логи', + 'messages.logId' => 'ID лога', 'subtitlingStyling.text' => 'Текст', 'subtitlingStyling.border' => 'Обводка', 'subtitlingStyling.background' => 'Фон', @@ -2950,10 +2954,10 @@ extension on TranslationsRu { 'companionRemote.pairing.connectionTimedOut' => 'Время подключения истекло. Используйте одну сеть на обоих устройствах.', 'companionRemote.pairing.sessionNotFound' => 'Устройство не найдено. Убедитесь, что Plezy запущен на хосте.', 'companionRemote.pairing.authFailed' => 'Аутентификация не удалась. На обоих устройствах нужен один аккаунт Plex.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Не удалось подключиться: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Отключиться от удалённой сессии?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Не удалось подключиться: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Отключиться от удалённой сессии?', 'companionRemote.remote.reconnecting' => 'Переподключение...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Попытка ${current} из 5', 'companionRemote.remote.retryNow' => 'Повторить сейчас', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 57d50dd7..c8c6a555 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsSv extends TranslationsSettingsEn { @override String get displaySwitchDelay => 'Fördröjning vid skärmbyte'; @override String get tunneledPlayback => 'Tunneluppspelning'; @override String get tunneledPlaybackDescription => 'Använd videotunnling. Inaktivera om HDR-uppspelning visar svart video.'; + @override String get audioPassthrough => 'Ljudgenomkoppling'; + @override String get audioPassthroughDescription => 'Skicka Dolby/DTS-ljud till din receiver eller TV utan omkodning och bevara surroundljudet. Stäng av om du inte har något ljud.'; @override String get dvConversionMode => 'Dolby Vision-konvertering'; @override String get dvConversionModeDescription => 'Välj hur ExoPlayer hanterar Dolby Vision Profile 7-filer.'; @override String get dvConversionAuto => 'Auto'; @@ -2178,6 +2180,8 @@ extension on TranslationsSv { 'settings.displaySwitchDelay' => 'Fördröjning vid skärmbyte', 'settings.tunneledPlayback' => 'Tunneluppspelning', 'settings.tunneledPlaybackDescription' => 'Använd videotunnling. Inaktivera om HDR-uppspelning visar svart video.', + 'settings.audioPassthrough' => 'Ljudgenomkoppling', + 'settings.audioPassthroughDescription' => 'Skicka Dolby/DTS-ljud till din receiver eller TV utan omkodning och bevara surroundljudet. Stäng av om du inte har något ljud.', 'settings.dvConversionMode' => 'Dolby Vision-konvertering', 'settings.dvConversionModeDescription' => 'Välj hur ExoPlayer hanterar Dolby Vision Profile 7-filer.', 'settings.dvConversionAuto' => 'Auto', @@ -2436,10 +2440,10 @@ extension on TranslationsSv { 'messages.serverLimitTitle' => 'Uppspelningen misslyckades', 'messages.serverLimitBody' => 'Serverfel (HTTP 500). En bandbredds-/transkodningsgräns avvisade troligen sessionen. Be ägaren justera den.', 'messages.logsUploaded' => 'Loggar uppladdade', - 'messages.logsUploadFailed' => 'Uppladdning av loggar misslyckades', - 'messages.logId' => 'Logg-ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => 'Uppladdning av loggar misslyckades', + 'messages.logId' => 'Logg-ID', 'subtitlingStyling.text' => 'Text', 'subtitlingStyling.border' => 'Kantlinje', 'subtitlingStyling.background' => 'Bakgrund', @@ -2950,10 +2954,10 @@ extension on TranslationsSv { 'companionRemote.pairing.connectionTimedOut' => 'Anslutningen tog för lång tid. Använd samma nätverk på båda enheter.', 'companionRemote.pairing.sessionNotFound' => 'Enhet hittades inte. Kontrollera att Plezy körs på värden.', 'companionRemote.pairing.authFailed' => 'Autentisering misslyckades. Båda enheter behöver samma Plex-konto.', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunde inte ansluta: ${error}', - 'companionRemote.remote.disconnectConfirm' => 'Vill du koppla från fjärrsessionen?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => 'Kunde inte ansluta: ${error}', + 'companionRemote.remote.disconnectConfirm' => 'Vill du koppla från fjärrsessionen?', 'companionRemote.remote.reconnecting' => 'Återansluter...', 'companionRemote.remote.attemptOf' => ({required Object current}) => 'Försök ${current} av 5', 'companionRemote.remote.retryNow' => 'Försök nu', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index f91a4ff5..b790be2b 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -391,6 +391,8 @@ class _TranslationsSettingsZh extends TranslationsSettingsEn { @override String get displaySwitchDelay => '显示切换延迟'; @override String get tunneledPlayback => '通道化播放'; @override String get tunneledPlaybackDescription => '使用视频隧道。若 HDR 播放出现黑屏,请禁用。'; + @override String get audioPassthrough => '音频直通'; + @override String get audioPassthroughDescription => '将 Dolby/DTS 音频不经重新编码直接发送到功放或电视,保留环绕声。如果没有声音,请关闭。'; @override String get dvConversionMode => 'Dolby Vision 转换'; @override String get dvConversionModeDescription => '选择 ExoPlayer 如何处理 Dolby Vision Profile 7 文件。'; @override String get dvConversionAuto => '自动'; @@ -2178,6 +2180,8 @@ extension on TranslationsZh { 'settings.displaySwitchDelay' => '显示切换延迟', 'settings.tunneledPlayback' => '通道化播放', 'settings.tunneledPlaybackDescription' => '使用视频隧道。若 HDR 播放出现黑屏,请禁用。', + 'settings.audioPassthrough' => '音频直通', + 'settings.audioPassthroughDescription' => '将 Dolby/DTS 音频不经重新编码直接发送到功放或电视,保留环绕声。如果没有声音,请关闭。', 'settings.dvConversionMode' => 'Dolby Vision 转换', 'settings.dvConversionModeDescription' => '选择 ExoPlayer 如何处理 Dolby Vision Profile 7 文件。', 'settings.dvConversionAuto' => '自动', @@ -2436,10 +2440,10 @@ extension on TranslationsZh { 'messages.serverLimitTitle' => '播放失败', 'messages.serverLimitBody' => '服务器错误 (HTTP 500)。带宽/转码限制可能拒绝了此会话。请让所有者调整。', 'messages.logsUploaded' => '日志已上传', - 'messages.logsUploadFailed' => '上传日志失败', - 'messages.logId' => '日志 ID', _ => null, } ?? switch (path) { + 'messages.logsUploadFailed' => '上传日志失败', + 'messages.logId' => '日志 ID', 'subtitlingStyling.text' => '文本', 'subtitlingStyling.border' => '边框', 'subtitlingStyling.background' => '背景', @@ -2950,10 +2954,10 @@ extension on TranslationsZh { 'companionRemote.pairing.connectionTimedOut' => '连接超时。请在两台设备上使用同一网络。', 'companionRemote.pairing.sessionNotFound' => '未找到设备。请确认 Plezy 正在主机上运行。', 'companionRemote.pairing.authFailed' => '认证失败。两台设备需要使用同一 Plex 账号。', - 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '连接失败:${error}', - 'companionRemote.remote.disconnectConfirm' => '是否要断开远程会话的连接?', _ => null, } ?? switch (path) { + 'companionRemote.pairing.failedToConnect' => ({required Object error}) => '连接失败:${error}', + 'companionRemote.remote.disconnectConfirm' => '是否要断开远程会话的连接?', 'companionRemote.remote.reconnecting' => '重新连接中...', 'companionRemote.remote.attemptOf' => ({required Object current}) => '第 ${current} 次尝试,共 5 次', 'companionRemote.remote.retryNow' => '立即重试', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index e3b4c080..03042259 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "Fördröjning vid skärmbyte", "tunneledPlayback": "Tunneluppspelning", "tunneledPlaybackDescription": "Använd videotunnling. Inaktivera om HDR-uppspelning visar svart video.", + "audioPassthrough": "Ljudgenomkoppling", + "audioPassthroughDescription": "Skicka Dolby/DTS-ljud till din receiver eller TV utan omkodning och bevara surroundljudet. Stäng av om du inte har något ljud.", "dvConversionMode": "Dolby Vision-konvertering", "dvConversionModeDescription": "Välj hur ExoPlayer hanterar Dolby Vision Profile 7-filer.", "dvConversionAuto": "Auto", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 3707f0e7..30b33d17 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -262,6 +262,8 @@ "displaySwitchDelay": "显示切换延迟", "tunneledPlayback": "通道化播放", "tunneledPlaybackDescription": "使用视频隧道。若 HDR 播放出现黑屏,请禁用。", + "audioPassthrough": "音频直通", + "audioPassthroughDescription": "将 Dolby/DTS 音频不经重新编码直接发送到功放或电视,保留环绕声。如果没有声音,请关闭。", "dvConversionMode": "Dolby Vision 转换", "dvConversionModeDescription": "选择 ExoPlayer 如何处理 Dolby Vision Profile 7 文件。", "dvConversionAuto": "自动", diff --git a/lib/screens/settings/playback_settings_screen.dart b/lib/screens/settings/playback_settings_screen.dart index cf3049c9..3e47ad5b 100644 --- a/lib/screens/settings/playback_settings_screen.dart +++ b/lib/screens/settings/playback_settings_screen.dart @@ -59,6 +59,7 @@ class _PlaybackSettingsScreenState extends State { if (Platform.isWindows) _matchDynamicRangeTile(), _displaySwitchDelayTile(), _tunneledPlaybackTile(), + if (PlatformDetector.supportsAudioPassthrough()) _audioPassthroughTile(), _dvConversionModeTile(), _bufferSizeTile(), _defaultQualityTile(), @@ -275,6 +276,13 @@ class _PlaybackSettingsScreenState extends State { subtitle: t.settings.matchDynamicRangeDescription, ); + Widget _audioPassthroughTile() => SettingSwitchTile( + pref: SettingsService.audioPassthrough, + icon: Symbols.surround_sound_rounded, + title: t.settings.audioPassthrough, + subtitle: t.settings.audioPassthroughDescription, + ); + Widget _displaySwitchDelayTile() => SettingsBuilder( prefs: const [ SettingsService.matchRefreshRate, diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index f1f58999..66593382 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -195,8 +195,14 @@ class _AudioPassthroughPref extends Pref { @override bool readFrom(BaseSharedPreferencesService svc) { + final stored = svc.prefs.getBool(key); + if (stored != null) return stored; + // Android TV on ExoPlayer defaults to bitstreaming AC3/EAC3/DTS to the TV/AVR + // (Media3 picks bitstream vs PCM via AudioCapabilities), preserving surround. + // Scoped to ExoPlayer — the mpv backend force-sets audio-spdif with no decode + // fallback. (#1458) // TODO: Default Apple TV to on once EAC3 passthrough is hardware-verified. - return svc.prefs.getBool(key) ?? false; + return Platform.isAndroid && PlatformDetector.isTV() && svc.read(SettingsService.useExoPlayer); } @override diff --git a/test/services/settings_service_test.dart b/test/services/settings_service_test.dart index 66accfde..6c3fff93 100644 --- a/test/services/settings_service_test.dart +++ b/test/services/settings_service_test.dart @@ -110,6 +110,19 @@ void main() { expect(PlatformDetector.supportsAudioPassthrough(), isFalse); }); + test('audio passthrough defaults off on a non-Android-TV host and honors explicit writes', () async { + final settings = await SettingsService.getInstance(); + // The Android-TV-on-ExoPlayer default-on branch depends on Platform.isAndroid, + // which is false (and unmockable) on the test host, so the default is off here. + expect(settings.read(SettingsService.audioPassthrough), isFalse); + + await settings.write(SettingsService.audioPassthrough, true); + expect(settings.read(SettingsService.audioPassthrough), isTrue); + + await settings.write(SettingsService.audioPassthrough, false); + expect(settings.read(SettingsService.audioPassthrough), isFalse); + }); + test('forces external player off on Apple TV even when stored enabled', () async { final settings = await SettingsService.getInstance(); await settings.write(SettingsService.useExternalPlayer, true);