应用程序到达前台时会更新AVPlayer状态

时间:2015-11-27 08:09:42

标签: ios swift avfoundation avplayer

我正在使用AVPlayer在我的iOS应用中构建音乐播放器。我听这样的AVPlayer.status属性的更改,知道音频何时可以播放:

player.currentItem!.addObserver(self, forKeyPath: "status", options: .New, context: nil)

当状态为.ReadyToPlay时,我会自动开始播放:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if (keyPath == "status") {
            if let currentItem = self.player?.currentItem {
                let status = currentItem.status
                if (status == .ReadyToPlay) {                    
                    self.play()
                }
            }
        }        
    }
}

效果很好。但问题是,如果我开始在我的应用中播放音乐,暂停音乐,然后离开应用并开始播放音乐,例如Spotify,AVPlayer的状态属性似乎已更改为下次我的应用程序到达前台时会再次.ReadyToPlay,这会导致观察者开火,从而导致音乐再次开始播放。

我认为当应用再次获得焦点时,AVPlayer实例会发生某些事情,这会导致status属性发生变化/刷新。

如何防止此行为?

1 个答案:

答案 0 :(得分:3)

这似乎是预期的行为。如果您想确保仅在AVPlayerItem状态更改时第一次开始播放,请在致电play()后移除观察者。

这里有一点需要注意的是,当玩家更改currentItem时,您应该已经移除了观察者,因此您需要使用额外的标记来跟踪您是否正在观察现有的currentItem

玩家的所有者会跟踪状态

var isObservingCurrentItem = false

添加观察者时更新/检查该状态

if currentItem = player.currentItem where isObservingCurrentItem {
    currentItem.removeObserver(self, forKeyPath:"status")
}

player.currentItem!.addObserver(self, forKeyPath: "status", options: .New, context: nil)
isObservingCurrentItem = true

然后,一旦玩家准备好玩,你就可以安全地移除观察者

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

    if let object = object,
        keyPath = keyPath,
        currentItem = self.player?.currentItem,
        status = currentItem.status
        where status == .ReadyToPlay {
            self.play()
            object.removeObserver(self, forKeyPath:keyPath)
            isObservingCurrentItem = false
    }
}