Add more playback rates for MPV

This commit is contained in:
Arkadiusz Fal 2022-11-10 23:19:34 +01:00
parent a44cce462a
commit 01d8e28d7c
6 changed files with 25 additions and 5 deletions

View File

@ -21,6 +21,14 @@ final class AVPlayerBackend: PlayerBackend {
var stream: Stream? var stream: Stream?
var video: Video? var video: Video?
var suggestedPlaybackRates: [Double] {
[0.5, 0.67, 0.8, 1, 1.25, 1.5, 2]
}
func canPlayAtRate(_ rate: Double) -> Bool {
suggestedPlaybackRates.contains(rate)
}
var currentTime: CMTime? { var currentTime: CMTime? {
avPlayer.currentTime() avPlayer.currentTime()
} }

View File

@ -92,6 +92,14 @@ final class MPVBackend: PlayerBackend {
internal var controlsUpdates = false internal var controlsUpdates = false
private var timeObserverThrottle = Throttle(interval: 2) private var timeObserverThrottle = Throttle(interval: 2)
var suggestedPlaybackRates: [Double] {
[0.1, 0.25, 0.3, 0.33, 0.5, 0.67, 0.8, 1, 1.25, 1.5, 1.75, 2, 3, 4]
}
func canPlayAtRate(_ rate: Double) -> Bool {
rate > 0 && rate <= 100
}
var tracks: Int { var tracks: Int {
client?.tracksCount ?? -1 client?.tracksCount ?? -1
} }

View File

@ -6,6 +6,7 @@ import Foundation
#endif #endif
protocol PlayerBackend { protocol PlayerBackend {
var suggestedPlaybackRates: [Double] { get }
var model: PlayerModel! { get } var model: PlayerModel! { get }
var controls: PlayerControlsModel! { get } var controls: PlayerControlsModel! { get }
var playerTime: PlayerTimeModel! { get } var playerTime: PlayerTimeModel! { get }
@ -30,6 +31,7 @@ protocol PlayerBackend {
func bestPlayable(_ streams: [Stream], maxResolution: ResolutionSetting) -> Stream? func bestPlayable(_ streams: [Stream], maxResolution: ResolutionSetting) -> Stream?
func canPlay(_ stream: Stream) -> Bool func canPlay(_ stream: Stream) -> Bool
func canPlayAtRate(_ rate: Double) -> Bool
func playStream( func playStream(
_ stream: Stream, _ stream: Stream,

View File

@ -47,7 +47,6 @@ final class PlayerModel: ObservableObject {
static var shared: PlayerModel! static var shared: PlayerModel!
static let availableRates: [Double] = [0.5, 0.67, 0.8, 1, 1.25, 1.5, 2]
let logger = Logger(label: "stream.yattee.app") let logger = Logger(label: "stream.yattee.app")
var avPlayerView = AppleAVPlayerView() var avPlayerView = AppleAVPlayerView()
@ -499,6 +498,9 @@ final class PlayerModel: ObservableObject {
let fromBackend: PlayerBackend = from == .appleAVPlayer ? avPlayerBackend : mpvBackend let fromBackend: PlayerBackend = from == .appleAVPlayer ? avPlayerBackend : mpvBackend
let toBackend: PlayerBackend = to == .appleAVPlayer ? avPlayerBackend : mpvBackend let toBackend: PlayerBackend = to == .appleAVPlayer ? avPlayerBackend : mpvBackend
if !self.backend.canPlayAtRate(currentRate) {
currentRate = self.backend.suggestedPlaybackRates.last { $0 < currentRate } ?? 1.0
}
self.backend.didChangeTo() self.backend.didChangeTo()
if wasPlaying { if wasPlaying {

View File

@ -59,7 +59,7 @@ extension PlayerModel {
} }
private var rateMenuActions: [UIAction] { private var rateMenuActions: [UIAction] {
PlayerModel.availableRates.map { rate in PlayerModel.shared.backend.suggestedPlaybackRates.map { rate in
let image = currentRate == rate ? UIImage(systemName: "checkmark") : nil let image = currentRate == rate ? UIImage(systemName: "checkmark") : nil
return UIAction(title: rateLabel(rate), image: image) { _ in return UIAction(title: rateLabel(rate), image: image) { _ in

View File

@ -180,7 +180,7 @@ struct ControlsOverlay: View {
var ratePicker: some View { var ratePicker: some View {
Picker("Rate", selection: $player.currentRate) { Picker("Rate", selection: $player.currentRate) {
ForEach(PlayerModel.availableRates, id: \.self) { rate in ForEach(player.backend.suggestedPlaybackRates, id: \.self) { rate in
Text(player.rateLabel(rate)).tag(rate) Text(player.rateLabel(rate)).tag(rate)
} }
} }
@ -188,7 +188,7 @@ struct ControlsOverlay: View {
} }
private var increaseRateButton: some View { private var increaseRateButton: some View {
let increasedRate = PlayerModel.availableRates.first { $0 > player.currentRate } let increasedRate = player.backend.suggestedPlaybackRates.first { $0 > player.currentRate }
return Button { return Button {
if let rate = increasedRate { if let rate = increasedRate {
player.currentRate = rate player.currentRate = rate
@ -211,7 +211,7 @@ struct ControlsOverlay: View {
} }
private var decreaseRateButton: some View { private var decreaseRateButton: some View {
let decreasedRate = PlayerModel.availableRates.last { $0 < player.currentRate } let decreasedRate = player.backend.suggestedPlaybackRates.last { $0 < player.currentRate }
return Button { return Button {
if let rate = decreasedRate { if let rate = decreasedRate {