diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index a77806c6..3fd47092 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -219,10 +219,17 @@ final class MPVBackend: PlayerBackend { var captions: Captions? if Defaults[.captionsAutoShow] == true { - let captionsLanguageCode = Defaults[.captionsDefaultLanguageCode] - if !captionsLanguageCode.isEmpty { - captions = video.captions.first { $0.code == captionsLanguageCode } ?? - video.captions.first { $0.code.contains(captionsLanguageCode) } + let captionsDefaultLanguageCode = Defaults[.captionsDefaultLanguageCode], + captionsFallbackLanguageCode = Defaults[.captionsFallbackLanguageCode] + + // Try to get captions with the default language code first + captions = video.captions.first { $0.code == captionsDefaultLanguageCode } ?? + video.captions.first { $0.code.contains(captionsDefaultLanguageCode) } + + // If there are still no captions, try to get captions with the fallback language code + if captions.isNil && !captionsFallbackLanguageCode.isEmpty { + captions = video.captions.first { $0.code == captionsFallbackLanguageCode } ?? + video.captions.first { $0.code.contains(captionsFallbackLanguageCode) } } } else { captions = nil diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 0529ad27..821c67d4 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -304,6 +304,7 @@ extension Defaults.Keys { static let captionsAutoShow = Key("captionsAutoShow", default: false) static let captionsLanguageCode = Key("captionsLanguageCode") static let captionsDefaultLanguageCode = Key("captionsDefaultLanguageCode", default: LanguageCodes.English.rawValue) + static let captionsFallbackLanguageCode = Key("captionsDefaultFallbackCode", default: LanguageCodes.English.rawValue) static let lastUsedPlaylistID = Key("lastPlaylistID") static let lastAccountIsPublic = Key("lastAccountIsPublic", default: false) diff --git a/Shared/Settings/PlayerSettings.swift b/Shared/Settings/PlayerSettings.swift index 4329a862..55e3cc5e 100644 --- a/Shared/Settings/PlayerSettings.swift +++ b/Shared/Settings/PlayerSettings.swift @@ -40,6 +40,7 @@ struct PlayerSettings: View { @Default(.captionsAutoShow) private var captionsAutoShow @Default(.captionsDefaultLanguageCode) private var captionsDefaultLanguageCode + @Default(.captionsFallbackLanguageCode) private var captionsFallbackLanguageCode @ObservedObject private var accounts = AccountsModel.shared @@ -50,7 +51,8 @@ struct PlayerSettings: View { #endif #if os(tvOS) - @State private var isShowingLanguagePicker = false + @State private var isShowingDefaultLanguagePicker = false + @State private var isShowingFallbackLanguagePicker = false #endif var body: some View { @@ -107,18 +109,33 @@ struct PlayerSettings: View { showCaptionsAutoShowToggle #if !os(tvOS) captionDefaultLanguagePicker + captionFallbackLanguagePicker #else - Button(action: { isShowingLanguagePicker = true }) { + Button(action: { isShowingDefaultLanguagePicker = true }) { HStack { Text("Default language") Spacer() Text("\(LanguageCodes(rawValue: captionsDefaultLanguageCode)!.description.capitalized) (\(captionsDefaultLanguageCode))").foregroundColor(.secondary) } } - .frame(maxWidth: .infinity).sheet(isPresented: $isShowingLanguagePicker) { - LanguagePickerTVOS( + .frame(maxWidth: .infinity).sheet(isPresented: $isShowingDefaultLanguagePicker) { + defaultLanguagePickerTVOS( selectedLanguage: $captionsDefaultLanguageCode, - isShowing: $isShowingLanguagePicker + isShowing: $isShowingDefaultLanguagePicker + ) + } + + Button(action: { isShowingFallbackLanguagePicker = true }) { + HStack { + Text("Fallback language") + Spacer() + Text("\(LanguageCodes(rawValue: captionsFallbackLanguageCode)!.description.capitalized) (\(captionsFallbackLanguageCode))").foregroundColor(.secondary) + } + } + .frame(maxWidth: .infinity).sheet(isPresented: $isShowingDefaultLanguagePicker) { + fallbackLanguagePickerTVOS( + selectedLanguage: $captionsFallbackLanguageCode, + isShowing: $isShowingFallbackLanguagePicker ) } #endif @@ -325,8 +342,19 @@ struct PlayerSettings: View { .labelsHidden() #endif } + + private var captionFallbackLanguagePicker: some View { + Picker("Fallback language", selection: $captionsFallbackLanguageCode) { + ForEach(LanguageCodes.allCases, id: \.self) { language in + Text("\(language.description.capitalized) (\(language.rawValue))").tag(language.rawValue) + } + } + #if os(macOS) + .labelsHidden() + #endif + } #else - struct LanguagePickerTVOS: View { + struct defaultLanguagePickerTVOS: View { @Binding var selectedLanguage: String @Binding var isShowing: Bool @@ -344,6 +372,25 @@ struct PlayerSettings: View { } } } + + struct fallbackLanguagePickerTVOS: View { + @Binding var selectedLanguage: String + @Binding var isShowing: Bool + + var body: some View { + NavigationView { + List(LanguageCodes.allCases, id: \.self) { language in + Button(action: { + selectedLanguage = language.rawValue + isShowing = false + }) { + Text("\(language.description.capitalized) (\(language.rawValue))") + } + } + .navigationTitle("Select Fallback Language") + } + } + } #endif #if !os(tvOS)