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)
}