Я работаю в SwiftUI и имею тип AudioPlayer, который является подклассом AVPlayer; он публикует timeControllerStatus AVPlayer (?) (.playing, .paused и другие?). Вместо того, чтобы создавать подклассы AVPlayer, я хотел бы передать AVPlayer и уведомить меня, используя .onReceive в каком-то View. Вот текущий функциональный тип, который у меня есть:
import AVKit
import Combine
class AudioPlayer: AVPlayer, ObservableObject {
@Published var buffering: Bool = false
override init() {
super.init()
registerObservers()
}
private func registerObservers() {
self.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "timeControlStatus", let change = change, let newValue = change[NSKeyValueChangeKey.newKey] as? Int, let oldValue = change[NSKeyValueChangeKey.oldKey] as? Int {
let oldStatus = AVPlayer.TimeControlStatus(rawValue: oldValue)
let newStatus = AVPlayer.TimeControlStatus(rawValue: newValue)
if newStatus != oldStatus {
DispatchQueue.main.async {[weak self] in
if newStatus == .playing || newStatus == .paused {
self?.buffering = false
} else {
self?.buffering = true
}
}
}
}
}
}
А вот пример класса, подобного тому, который я хотел бы (взят из учебника Chris Ma sh по SwiftUI & AVPlayer ):
import Combine
import AVFoundation
class PlayerItemObserver {
let publisher = PassthroughSubject<Bool, Never>()
private var itemObservation: NSKeyValueObservation?
init(player: AVPlayer) {
// Observe the current item changing
itemObservation = player.observe(\.currentItem) { [weak self] player, change in
guard let self = self else { return }
// Publish whether the player has an item or not
self.publisher.send(player.currentItem != nil)
}
}
deinit {
if let observer = itemObservation {
observer.invalidate()
}
}
}
Ваша помощь очень ценится.