由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'AVPlayerItem类的实例0x1702076f0已取消分配,而键值观察者仍在其中注册 . 当前观察信息:(( . <)NSKeyValueObservance 0x174846360:Observer:0x174846210,Key path:loadedTimeRanges,Options:Context:0x0,Property:0x1748462d0>)'
这是我将 currentItem.loadedTimeRanges 观察者添加到AVPlayer后收到的错误
player = AVPlayer(url: videoUrl!)
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = postVideoView.frame
playerLayer.frame.size.width = UIScreen.main.bounds.width
self.postVideoView.layer.addSublayer(playerLayer)
player?.play()
player?.addObserver(self, forKeyPath: "currentItem.loadedTimeRanges", options: .new, context: nil)
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: nil, using: { (_) in
DispatchQueue.main.async {
self.player?.seek(to: kCMTimeZero)
self.player?.play()
}
})
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//this is when the player is ready and rendering frames
if keyPath == "currentItem.loadedTimeRanges" {
if let duration = player?.currentItem?.duration {
let seconds = CMTimeGetSeconds(duration)
let secondsText = Int(seconds) % 60
let minutesText = String(format: "%02d", Int(seconds) / 60)
videoLengthLabel.text = "\(minutesText):\(secondsText)"
}
}
}
2 回答
你在哪里打电话
removeObserver
?目前看起来你的顶级代码是否会创建一个新玩家并添加一个观察者 . 如果调用两次,则第一个实例上的观察者仍然存在 . 因此,我希望以下行位于顶部:如果它没有被调用两次,那么代码中的其他地方是否会重新分配或取消分配
self.player
?如果是这样,你应该首先调用removeObserver
.您每次都要向NotificationCenter添加一个新的观察者 . 这应该只在被添加另一个之前被调用一次或
removeObserver
.您需要确保不要多次添加和删除观察者 . 所以最好的方法就是声明一个bool变量让我们说
var isObserverAdded = false.
添加观察者时,如果未添加则检查此标志
删除观察者时检查标志是否已添加
如果使用上面的检查,那么你永远不会得到错误 .