mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 18:54:11 +00:00
Playback rate menu
This commit is contained in:
@@ -11,6 +11,7 @@ import SwiftUI
|
||||
import SwiftyJSON
|
||||
|
||||
final class PlayerModel: ObservableObject {
|
||||
static let availableRates: [Float] = [0.5, 0.67, 0.8, 1, 1.25, 1.5, 2]
|
||||
let logger = Logger(label: "net.arekf.Pearvidious.ps")
|
||||
|
||||
private(set) var player = AVPlayer()
|
||||
@@ -23,7 +24,7 @@ final class PlayerModel: ObservableObject {
|
||||
@Published var presentingPlayer = false
|
||||
|
||||
@Published var stream: Stream?
|
||||
@Published var currentRate: Float?
|
||||
@Published var currentRate: Float = 1.0 { didSet { player.rate = currentRate } }
|
||||
|
||||
@Published var availableStreams = [Stream]() { didSet { rebuildTVMenu() } }
|
||||
@Published var streamSelection: Stream? { didSet { rebuildTVMenu() } }
|
||||
@@ -418,6 +419,10 @@ final class PlayerModel: ObservableObject {
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
|
||||
if player.timeControlStatus == .playing, player.rate != self.currentRate {
|
||||
player.rate = self.currentRate
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
if player.timeControlStatus == .playing {
|
||||
ScreenSaverManager.shared.disable(reason: "Yattee is playing video")
|
||||
@@ -469,4 +474,12 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
currentArtwork = MPMediaItemArtwork(boundsSize: image!.size) { _ in image! }
|
||||
}
|
||||
|
||||
func rateLabel(_ rate: Float) -> String {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.minimumFractionDigits = 0
|
||||
formatter.maximumFractionDigits = 2
|
||||
|
||||
return "\(formatter.string(from: NSNumber(value: rate))!)×"
|
||||
}
|
||||
}
|
||||
|
@@ -42,12 +42,33 @@ extension PlayerModel {
|
||||
self.restoreLastSkippedSegment()
|
||||
}
|
||||
}
|
||||
|
||||
private var rateMenu: UIMenu {
|
||||
UIMenu(title: "Playback rate", image: UIImage(systemName: rateMenuSystemImage), children: rateMenuActions)
|
||||
}
|
||||
|
||||
private var rateMenuSystemImage: String {
|
||||
[0.0, 1.0].contains(currentRate) ? "speedometer" : (currentRate < 1.0 ? "tortoise.fill" : "hare.fill")
|
||||
}
|
||||
|
||||
private var rateMenuActions: [UIAction] {
|
||||
PlayerModel.availableRates.map { rate in
|
||||
let image = currentRate == Float(rate) ? UIImage(systemName: "checkmark") : nil
|
||||
|
||||
return UIAction(title: rateLabel(rate), image: image) { _ in
|
||||
DispatchQueue.main.async {
|
||||
self.currentRate = rate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
func rebuildTVMenu() {
|
||||
#if os(tvOS)
|
||||
avPlayerViewController?.transportBarCustomMenuItems = [
|
||||
restoreLastSkippedSegmentAction,
|
||||
rateMenu,
|
||||
streamsMenu
|
||||
].compactMap { $0 }
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user