diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 02815c1f..d1c73001 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -454,11 +454,12 @@ final class PlayerModel: ObservableObject { } fileprivate func updateNowPlayingInfo() { + let duration: Int? = currentItem.video.live ? nil : Int(currentItem.videoDuration ?? 0) let nowPlayingInfo: [String: AnyObject] = [ MPMediaItemPropertyTitle: currentItem.video.title as AnyObject, MPMediaItemPropertyArtist: currentItem.video.author as AnyObject, MPMediaItemPropertyArtwork: currentArtwork as AnyObject, - MPMediaItemPropertyPlaybackDuration: (currentItem.video.live ? nil : Int(currentItem.videoDuration ?? 0)) as AnyObject, + MPMediaItemPropertyPlaybackDuration: duration as AnyObject, MPNowPlayingInfoPropertyIsLiveStream: currentItem.video.live as AnyObject, MPNowPlayingInfoPropertyElapsedPlaybackTime: player.currentTime().seconds as AnyObject, MPNowPlayingInfoPropertyPlaybackQueueCount: queue.count as AnyObject, diff --git a/Model/Player/PlayerQueue.swift b/Model/Player/PlayerQueue.swift index 1b0267dc..35bd7737 100644 --- a/Model/Player/PlayerQueue.swift +++ b/Model/Player/PlayerQueue.swift @@ -66,10 +66,19 @@ extension PlayerModel { } private func preferredStream(_ streams: [Stream]) -> Stream? { + let quality = Defaults[.quality] + var streams = streams + if let id = Defaults[.playerInstanceID] { - return streams.first { $0.instance.id == id } - } else { - return streams.first + streams = streams.filter { $0.instance.id == id } + } + + switch quality { + case .best: + return streams.first { $0.kind == .hls } ?? streams.first + default: + let sorted = streams.filter { $0.kind != .hls }.sorted { $0.resolution > $1.resolution } + return sorted.first(where: { $0.resolution.height <= quality.value.height }) } } diff --git a/Model/Stream.swift b/Model/Stream.swift index 5a2fa206..65fe2a37 100644 --- a/Model/Stream.swift +++ b/Model/Stream.swift @@ -4,28 +4,6 @@ import Foundation // swiftlint:disable:next final_class class Stream: Equatable, Hashable, Identifiable { - enum ResolutionSetting: String, Defaults.Serializable, CaseIterable { - case hd720pFirstThenBest, hd1080p, hd720p, sd480p, sd360p, sd240p, sd144p - - var value: Stream.Resolution { - switch self { - case .hd720pFirstThenBest: - return .hd720p - default: - return Stream.Resolution(rawValue: rawValue)! - } - } - - var description: String { - switch self { - case .hd720pFirstThenBest: - return "Default: adaptive" - default: - return value.name - } - } - } - enum Resolution: String, CaseIterable, Comparable, Defaults.Serializable { case hd1440p60, hd1440p, hd1080p60, hd1080p, hd720p60, hd720p, sd480p, sd360p, sd240p, sd144p, unknown diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index c9ed85ea..8a25a06c 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -1,18 +1,6 @@ import Defaults import Foundation -enum PlayerSidebarSetting: String, CaseIterable, Defaults.Serializable { - case always, whenFits, never - - static var defaultValue: Self { - #if os(macOS) - .always - #else - .whenFits - #endif - } -} - extension Defaults.Keys { static let invidiousInstanceID = "default-invidious-instance" static let pipedInstanceID = "default-piped-instance" @@ -54,7 +42,7 @@ extension Defaults.Keys { static let channelOnThumbnail = Key("channelOnThumbnail", default: true) static let timeOnThumbnail = Key("timeOnThumbnail", default: true) - static let quality = Key("quality", default: .hd720pFirstThenBest) + static let quality = Key("quality", default: .best) static let playerSidebar = Key("playerSidebar", default: PlayerSidebarSetting.defaultValue) static let playerInstanceID = Key("playerInstance") static let showKeywords = Key("showKeywords", default: false) @@ -68,3 +56,37 @@ extension Defaults.Keys { static let trendingCategory = Key("trendingCategory", default: .default) static let trendingCountry = Key("trendingCountry", default: .us) } + +enum ResolutionSetting: String, CaseIterable, Defaults.Serializable { + case best, hd720p, sd480p, sd360p, sd240p, sd144p + + var value: Stream.Resolution { + switch self { + case .best: + return .hd720p + default: + return Stream.Resolution(rawValue: rawValue)! + } + } + + var description: String { + switch self { + case .best: + return "Best available" + default: + return value.name + } + } +} + +enum PlayerSidebarSetting: String, CaseIterable, Defaults.Serializable { + case always, whenFits, never + + static var defaultValue: Self { + #if os(macOS) + .always + #else + .whenFits + #endif + } +} diff --git a/Shared/Settings/PlaybackSettings.swift b/Shared/Settings/PlaybackSettings.swift index 727a0190..e6b68cc1 100644 --- a/Shared/Settings/PlaybackSettings.swift +++ b/Shared/Settings/PlaybackSettings.swift @@ -67,7 +67,7 @@ struct PlaybackSettings: View { private var qualityPicker: some View { Picker("Quality", selection: $quality) { - ForEach(Stream.ResolutionSetting.allCases, id: \.self) { resolution in + ForEach(ResolutionSetting.allCases, id: \.self) { resolution in Text(resolution.description).tag(resolution) } }