ios - 在 SwiftUI 中监听 AVPlayer timeControlStatus 的变化
问题描述
所以尝试在 SwiftUI 中实现作为 AVPlayer 的简单观察者。我已经添加了被触发的观察者,但还没有弄清楚如何/在哪里observeValue
根据苹果文档实现:https ://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/responding_to_playback_state_changes
到目前为止,我的 AVPlayer 类如下:
class Player: AVPlayer, ObservableObject {
@Published var isPlaying: Bool = false
static var shared = AVPlayer()
static var episodeId: Int?
static func playItem(at itemURL: String, episodeId: Int) {
let url = URL(string: itemURL)
Player.shared = AVPlayer(url: url!)
Player.episodeId = episodeId
Player.shared.addObserver(self.shared, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
}
}
所以问题是我应该在哪里实现它才能工作:
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
if Player.shared.timeControlStatus == .playing {
// Set @Published isPlaying to true
}
}
解决方案
它可以像下面这样(static
在这种情况下不需要使用它,无论如何你将需要实例来使用@ObservedObject
)
当然它不是最终Player
的,但它的发展方向应该是明确的:
class Player: AVPlayer, ObservableObject {
@Published var isPlaying: Bool = false
private var playerContext = 0
var player: AVPlayer? = nil
var episodeId: Int?
func playItem(at itemURL: String, episodeId: Int) {
guard let url = URL(string: itemURL) else { return }
// cleanup for previous player
self.player?.removeObserver(self, forKeyPath: "timeControlStatus")
// setup new player
let newPlayer = AVPlayer(url: url)
newPlayer.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: &playerContext)
self.player = newPlayer
self.episodeId = episodeId
}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard context == &playerContext else { // give super to handle own cases
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if self.player?.timeControlStatus == .playing {
self.isPlaying = true
}
}
}
推荐阅读
- ionic-framework - 如何在带电容器的 Ionic 5 项目中使用 Pushwoosh
- arrays - 处理:有没有办法将我的形状放入一个循环中并使我的代码更短?
- c# - 基于任务的行为正在阻塞父线程
- spring-boot - AWS Postgres RDS 数据库连接到 Spring Boot
- python - 损失函数内的Tensorflow变量初始化
- django - 类型字符变化的值太长(3)Django模型
- python - FastAPI 没有引发 HTTPException
- jquery - Angular 7 - 工具提示上的多行字符串
- javascript - 如何使用 React-native-range-slider 在触摸结束时设置状态
- powershell - Teradata bteq 控制台未在 powershell transcipt 中传输