【问题标题】:Issue with "func observeValueForKeyPath(keyPath : NSString, object : AnyObject, change : NSDictionary, context : Void)" in SwiftSwift 中的“func observeValueForKeyPath(keyPath : NSString, object : AnyObject, change : NSDictionary, context : Void)”问题
【发布时间】:2015-06-23 18:06:54
【问题描述】:

我已经为这样的 AVPlayer 添加了一个观察者

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

又叫

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

问题是永远不会调用observeValueForKeyPath

完整代码

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

【问题讨论】:

    标签: ios swift avplayer swift2


    【解决方案1】:

    你如何观察播放器项目。可能是您观察不正确。下面是一个简单的图解,说明如何正确观察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)
        }
    }
    

    当开始或改变歌曲时,它会打印出以下内容,

    Unknown
    Ready to play
    

    【讨论】:

    • 音频播放正常
    • 非常感谢。我错过了一点。现在在你的帮助下,它完成了。
    • 你能解释一下ObservatingKeyPathNSKeyValueObservingOptions.New.initial是什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多