ios swift avplayer swift2

ios - Problema con "func observeValueForKeyPath(keyPath: NSString, objeto: AnyObject, change: NSDictionary, context: Void)" en Swift



avplayer swift2 (1)

¿Cómo observas el elemento del jugador? Es posible que lo estés observando incorrectamente. Aquí hay unas ilustraciones simples para mostrar cómo observar correctamente el estado de AVPlayer,

class TestViewController: UIViewController { private var player: AVPlayer! private var playingIndex = 0 private var songs = ["UpTown.mp3", "TurnMeOn.mp3"] private let ObservatingKeyPath = "currentItem.status" private let PlayerStatusObservingContext = UnsafeMutablePointer<Int>(bitPattern: 1) override func viewDidLoad() { super.viewDidLoad() createPlayer() setupGestures() playNext() } func createPlayer() { player = AVPlayer() player.addObserver(self, forKeyPath: ObservatingKeyPath, options: NSKeyValueObservingOptions.New, context: PlayerStatusObservingContext) } func setupGestures() { let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "playNext") view.addGestureRecognizer(tapGestureRecognizer) } func playNext() { let url = NSBundle.mainBundle().URLForResource(songs[playingIndex], withExtension: nil) let playerItem = AVPlayerItem(URL: url!) player.replaceCurrentItemWithPlayerItem(playerItem) player.play() playingIndex = (++playingIndex % 2) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [NSObject : AnyObject]?, context: UnsafeMutablePointer<Void>) { if context == PlayerStatusObservingContext { if let change = change as? [String: Int] { let newChange = change[NSKeyValueChangeNewKey]! switch newChange { case AVPlayerItemStatus.ReadyToPlay.rawValue: print("Ready to play") case AVPlayerItemStatus.Unknown.rawValue: print("Unknown") default: print("Other status") } } return } super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } }

E imprime lo siguiente al iniciar o cambiar la canción,

Unknown Ready to play

He agregado un observador para un AVPlayer como este

self.audioPlayer.addObserver(self, forKeyPath: "currentItem.status", options: [NSKeyValueObservingOptions.New, NSKeyValueObservingOptions.Initial], context: nil)

Y llamado

func observeValueForKeyPath(keyPath : NSString, object : AnyObject, change : NSDictionary, context : Void) { if object as! AVPlayer == self.audioPlayer && keyPath.isEqualToString("currentItem.status") { let playerStatus = self.audioPlayer.currentItem!.status.rawValue as Int if playerStatus == AVPlayerStatus.Failed.rawValue { self.replaceCurrentItem(self.fileName) } else if playerStatus == AVPlayerStatus.ReadyToPlay.rawValue { self.playAudio() self.updateDurationPeriodcally() self.updateInfo() } else if playerStatus == AVPlayerStatus.Unknown.rawValue { print("/(self.audioPlayer.currentItem!.error)") } } }

El problema es que observeValueForKeyPath nunca se llama observeValueForKeyPath .

Código entero

func loadPlayer (urlString : NSString) { let url : NSURL = NSURL(string: urlString as String)! let length = (url.absoluteString).characters.count as Int if length == 0 { return } let asset = AVURLAsset(URL: url, options: nil) let anItem = AVPlayerItem(asset: asset) self.audioPlayer = AVPlayer(playerItem: anItem) self.audioPlayer.volume = 1.0 self.audioPlayer.play() addObserver(self, forKeyPath: ObservatingKeyPath, options: NSKeyValueObservingOptions.New, context: PlayerStatusObservingContext) self.audioPlayer.addObserver(self, forKeyPath: "currentItem.status", options: [NSKeyValueObservingOptions.New, NSKeyValueObservingOptions.Initial], context: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "itemDidFinishPlaying:", name:AVPlayerItemDidPlayToEndTimeNotification, object: nil) }