diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index 6092e82f..7528bbf3 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -216,8 +216,8 @@ final class MPVBackend: PlayerBackend { } } - func setRate(_: Float) { - // TODO: Implement rate change + func setRate(_ rate: Float) { + client.setDoubleAsync("speed", Double(rate)) } func closeItem() {} diff --git a/Model/Player/Backends/MPVClient.swift b/Model/Player/Backends/MPVClient.swift index 402dbe18..972a68ae 100644 --- a/Model/Player/Backends/MPVClient.swift +++ b/Model/Player/Backends/MPVClient.swift @@ -225,6 +225,11 @@ final class MPVClient: ObservableObject { mpv_set_property_async(mpv, 0, name, MPV_FORMAT_FLAG, &data) } + func setDoubleAsync(_ name: String, _ value: Double) { + var data = value + mpv_set_property_async(mpv, 0, name, MPV_FORMAT_DOUBLE, &data) + } + private func getDouble(_ name: String) -> Double { var data = Double() mpv_get_property(mpv, name, MPV_FORMAT_DOUBLE, &data) diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index c5279973..44446ab8 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -338,6 +338,7 @@ final class PlayerModel: ObservableObject { } inactiveBackends().forEach { $0.pause() } + backend.setRate(currentRate) let fromBackend: PlayerBackend = from == .appleAVPlayer ? avPlayerBackend : mpvBackend let toBackend: PlayerBackend = to == .appleAVPlayer ? avPlayerBackend : mpvBackend diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 91ee53b5..c61eb547 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -122,8 +122,10 @@ enum ResolutionSetting: String, CaseIterable, Defaults.Serializable { switch self { case .best: return "Best available quality" - case .hd2160p: + case .hd2160p60: return "4K, 60fps" + case .hd2160p: + return "4K" default: return value.name } diff --git a/Shared/Player/Controls/PlayerControls.swift b/Shared/Player/Controls/PlayerControls.swift index 189b8cc3..f2ff331f 100644 --- a/Shared/Player/Controls/PlayerControls.swift +++ b/Shared/Player/Controls/PlayerControls.swift @@ -176,8 +176,10 @@ struct PlayerControls: View { HStack { #if !os(tvOS) fullscreenButton + rateButton + + Spacer() #endif - Spacer() // button("Music Mode", systemImage: "music.note") } } @@ -194,6 +196,41 @@ struct PlayerControls: View { #endif } + private var rateButton: some View { + #if os(macOS) + ratePicker + .labelsHidden() + .frame(maxWidth: 70) + #else + Menu { + ratePicker + .frame(width: 45, height: 30) + #if os(iOS) + .background(VisualEffectBlur(blurStyle: .systemThinMaterial)) + #endif + .mask(RoundedRectangle(cornerRadius: 3)) + } label: { + Text(player.rateLabel(player.currentRate)) + .foregroundColor(.primary) + .frame(maxWidth: .infinity) + } + + #endif + } + + var ratePicker: some View { + Picker("Rate", selection: rateBinding) { + ForEach(PlayerModel.availableRates, id: \.self) { rate in + Text(player.rateLabel(rate)).tag(rate) + } + } + .transaction { t in t.animation = .none } + } + + private var rateBinding: Binding { + .init(get: { player.currentRate }, set: { rate in player.currentRate = rate }) + } + var mediumButtonsBar: some View { HStack { #if !os(tvOS)