目标:
我最终试图读取外部视频文件(.mp4、.mpg ...);在 AVPlayerViewController 的一个实例中。
但是我遇到了各种各样的 KVO 问题。
- AVPlayerViewController 的 KVO 观察者总是在触发,即使我没有像这里的控制台中显示的那样注册它(来源:参见下面代码列表中的 observeForKeyPath().print(key path)):
playerController.status playerController.contentDimensions playerController.playingOnExternalScreen playerController.externalPlaybackType playerController.allowsExternalPlayback playerController.hasEnabledVideo playerController.hasEnabledAudio bounds videoScaled playerController.playingOnExternalScreen view.viewWindowState bounds playerController.playing
- 我的 KVO 观察者(“timedMetadata”)没有注册。显然:
self.playerItem!.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
不工作:
a) 'observeValueForKeyPath()' 没有为这个观察者触发;b)我收到以下运行时
错误(在立即删除观察者作为测试之后):
...原因:'无法删除观察者...对于关键路径“timedMetadata”来自...,因为它没有注册为观察者。'
class EditShowVideoViewController:AVPlayerViewController {
var playerItem:AVPlayerItem?
override func viewDidLoad() {
self.view.hidden = true
if let url = NSURL(string: gEditMediumTuple!.medium as! String) {
let asset = AVURLAsset(URL: url)
let requestedKeys = Array(arrayLiteral: "tracks", "playable")
asset.loadValuesAsynchronouslyForKeys(requestedKeys, completionHandler: { () in
// do something
dispatch_async(dispatch_get_main_queue(), {
self.playerItem = AVPlayerItem(asset: asset)
self.playerItem!.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
self.removeObserver(self, forKeyPath:"timedMetadata") //...still runtime error.
})
})
} else {
showAlert(sender: self.parentViewController!, withTitle: "No Video", withMessage: "No video is found.", alertPurpose: .noVideo)
}
}
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?, change: [String : AnyObject]?,
context: UnsafeMutablePointer<()>) {
print(keyPath!)
guard keyPath == "readyForDisplay" else {return}
guard let obj = object as? AVPlayerViewController else {return}
guard let ok = change?[NSKeyValueChangeNewKey] as? Bool else {return}
guard ok else {return}
dispatch_async(dispatch_get_main_queue(), {
self.finishConstructingInterface(obj)
})
self.removeObserver(self, forKeyPath:"timedMetadata")
}
func finishConstructingInterface (vc:AVPlayerViewController) {
self.removeObserver(self, forKeyPath:"readyForDisplay")
self.view.hidden = false
}
// ...
}
我想要做的就是加载一个视频 URL 并播放它。
如果缺乏补救措施,欢迎提出任何建议。