Goal:
I'm ultimately trying to read an external video file (.mp4, .mpg...); within an instance of AVPlayerViewController.
But I'm having all sorts of KVO problems.
- AVPlayerViewController's KVO observer is always firing, even though I didn't register it as shown in the console here (source: see the observeForKeyPath().print(key path) in the code-list below):
playerController.status playerController.contentDimensions playerController.playingOnExternalScreen playerController.externalPlaybackType playerController.allowsExternalPlayback playerController.hasEnabledVideo playerController.hasEnabledAudio bounds videoScaled playerController.playingOnExternalScreen view.viewWindowState bounds playerController.playing
- My KVO observer ("timedMetadata") isn't registering. Apparently:
self.playerItem!.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
isn't working:
a) The 'observeValueForKeyPath()' isn't firing for this observer; and
b) I get the following runtime error (after immediately removing the observer as a test):
...reason: 'Cannot remove an observer... for the key path "timedMetadata" from ... because it is not registered as an observer.'
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
}
// ...
}
All I want to do is to load a video URL and play it.
Any advice if short of a remedy is welcomed.