diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 33dbfdd5..521fe410 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -158,6 +158,7 @@ final class PlayerModel: ObservableObject { }} @Default(.qualityProfiles) var qualityProfiles + @Default(.forceAVPlayerForLiveStreams) var forceAVPlayerForLiveStreams @Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer @Default(.closePiPOnNavigation) var closePiPOnNavigation @Default(.closePiPOnOpeningPlayer) var closePiPOnOpeningPlayer @@ -344,9 +345,10 @@ final class PlayerModel: ObservableObject { var changeBackendHandler: (() -> Void)? - if let backend = qualityProfile?.backend ?? QualityProfilesModel.shared.automaticProfile?.backend, - activeBackend != backend, - backend == .appleAVPlayer || !avPlayerBackend.startPictureInPictureOnPlay + if let backend = (live && forceAVPlayerForLiveStreams) ? PlayerBackendType.appleAVPlayer : + (qualityProfile?.backend ?? QualityProfilesModel.shared.automaticProfile?.backend), + activeBackend != backend, + backend == .appleAVPlayer || !avPlayerBackend.startPictureInPictureOnPlay { changeBackendHandler = { [weak self] in guard let self = self else { return } @@ -446,10 +448,11 @@ final class PlayerModel: ObservableObject { return } - if let qualityProfileBackend = qualityProfile?.backend, qualityProfileBackend != activeBackend, - qualityProfileBackend == .appleAVPlayer || !(avPlayerBackend.startPictureInPictureOnPlay || playingInPictureInPicture) + if let backend = (live && forceAVPlayerForLiveStreams) ? PlayerBackendType.appleAVPlayer : qualityProfile?.backend, + backend != activeBackend, + backend == .appleAVPlayer || !(avPlayerBackend.startPictureInPictureOnPlay || playingInPictureInPicture) { - changeActiveBackend(from: activeBackend, to: qualityProfileBackend) + changeActiveBackend(from: activeBackend, to: backend) } guard let stream = streamByQualityProfile else { @@ -502,6 +505,8 @@ final class PlayerModel: ObservableObject { return } + logger.info("changing backend from \(from.rawValue) to \(to.rawValue)") + pause() if to == .mpv { diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 746e8042..1be2b1a1 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -87,6 +87,7 @@ extension Defaults.Keys { static let batteryNonCellularProfile = Key("batteryNonCellularProfile", default: batteryNonCellularProfileDefault) static let chargingCellularProfile = Key("chargingCellularProfile", default: chargingCellularProfileDefault) static let chargingNonCellularProfile = Key("chargingNonCellularProfile", default: chargingNonCellularProfileDefault) + static let forceAVPlayerForLiveStreams = Key("forceAVPlayerForLiveStreams", default: true) static let playerSidebar = Key("playerSidebar", default: PlayerSidebarSetting.defaultValue) static let playerInstanceID = Key("playerInstance") diff --git a/Shared/Settings/QualitySettings.swift b/Shared/Settings/QualitySettings.swift index 014d785f..afe0d3f2 100644 --- a/Shared/Settings/QualitySettings.swift +++ b/Shared/Settings/QualitySettings.swift @@ -12,9 +12,10 @@ struct QualitySettings: View { @Default(.batteryNonCellularProfile) private var batteryNonCellularProfile @Default(.chargingCellularProfile) private var chargingCellularProfile @Default(.chargingNonCellularProfile) private var chargingNonCellularProfile + @Default(.forceAVPlayerForLiveStreams) private var forceAVPlayerForLiveStreams var body: some View { - VStack { + VStack(alignment: .leading) { #if os(macOS) sections @@ -63,6 +64,8 @@ struct QualitySettings: View { Picker("Default", selection: $chargingNonCellularProfile) { profilePickerOptions } } #endif + + forceAVPlayerForLiveStreamsToggle } .disabled(qualityProfiles.isEmpty) Section(header: SettingsHeader(text: "Profiles"), footer: profilesFooter) { @@ -103,6 +106,10 @@ struct QualitySettings: View { Picker("Charging", selection: $chargingNonCellularProfile) { profilePickerOptions } } + @ViewBuilder var forceAVPlayerForLiveStreamsToggle: some View { + Toggle("Always use AVPlayer for live videos", isOn: $forceAVPlayerForLiveStreams) + } + @ViewBuilder func profileControl(_ qualityProfile: QualityProfile) -> some View { #if os(tvOS) Button {