我一直在尝试添加一个观察者来收听 AVPlayer 的“timeControlStatus”,主要是直接取自 Apple 的示例; https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/observing_playback_state
我创建了一个名为 Play 的独立类,我从 ViewController 调用下面的内容
Play().playMusic(url: url!)
课堂播放()
import Foundation
import AVFoundation
var player: AVPlayer! = nil
var playerItemContext = 0
class Play: AVPlayer {
func playMusic(url : URL) {
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
if player == nil {
player = AVPlayer(playerItem: playerItem)
if player.status.rawValue == 0 {
player.play()
player.addObserver(player, forKeyPath: "timeControlStatus", options: [.old, .new], context: &playerItemContext)
}
} else {
player.replaceCurrentItem(with: playerItem)
player.play()
}
}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
// Only handle observations
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if keyPath == "timeControlStatus" { print("Result") }
}
}
上面总是崩溃;
<AVPlayer: 0x6000030a4770>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: timeControlStatus
Observed object: <AVPlayer: 0x6000030a4770>
Change: {
kind = 1;
new = 1;
old = 1;
}
Context: 0x1003f3e98'
如果我删除“addObserver”,代码会按预期运行并播放音频文件,奇怪的是,如果将所有观察者代码从 Play 类移动到 ViewContoller 是否有效?什么给?。
答案 0 :(得分:0)
区别仅在于当您将代码移动到视图控制器时,视图控制器仍然存在。它是一个稳定的对象,存在于视图控制器层次结构中。所以它的寿命足以做一些工作。
但另一方面,在这一行:
Play().playMusic(url: url!)
... Play 实例被创建并立即再次消失,就像一个量子虚拟粒子。当播放进行时,它的寿命不够长。因此崩溃:你让观察者过早地消失了。
如果您希望 Play 实例持久化,则需要将其分配给某个长期存在的变量,例如视图控制器的属性。