AVPlayer addObserver 消息已收到但未处理

时间:2021-03-22 17:25:03

标签: swift avplayer

我一直在尝试添加一个观察者来收听 AVPlayer 的“timeControlStatus”,主要是直接取自 Apple 的示例; https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/observing_playback_state

我创建了一个名为 Play 的独立类,我从 ViewController 调用下面的内容

Play().playMusic(url: url!)

课堂播放()

import Foundation
import AVFoundation

var player: AVPlayer! = nil
var playerItemContext = 0

class Play: AVPlayer {
  
    func playMusic(url : URL) {
        
        let asset = AVAsset(url: url)
        let playerItem = AVPlayerItem(asset: asset)
        if player == nil {
                player = AVPlayer(playerItem: playerItem)
            if player.status.rawValue == 0 {
                player.play()
               player.addObserver(player, forKeyPath: "timeControlStatus", options: [.old, .new], context: &playerItemContext)
                }
                } else {
                player.replaceCurrentItem(with: playerItem)
                player.play()
                }
    }
  
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {


        // Only handle observations
        guard context == &playerItemContext else {
            super.observeValue(forKeyPath: keyPath,
                               of: object,
                               change: change,
                               context: context)
            return
        }
        if keyPath == "timeControlStatus" { print("Result") }
    }
}

上面总是崩溃;

<AVPlayer: 0x6000030a4770>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: timeControlStatus
Observed object: <AVPlayer: 0x6000030a4770>
Change: {
    kind = 1;
    new = 1;
    old = 1;
}
Context: 0x1003f3e98'

如果我删除“addObserver”,代码会按预期运行并播放音频文件,奇怪的是,如果将所有观察者代码从 Play 类移动到 ViewContoller 是否有效?什么给?。

1 个答案:

答案 0 :(得分:0)

区别仅在于当您将代码移动到视图控制器时,视图控制器仍然存在。它是一个稳定的对象,存在于视图控制器层次结构中。所以它的寿命足以做一些工作。

但另一方面,在这一行:

Play().playMusic(url: url!)

... Play 实例被创建并立即再次消失,就像一个量子虚拟粒子。当播放进行时,它的寿命不够长。因此崩溃:你让观察者过早地消失了。

如果您希望 Play 实例持久化,则需要将其分配给某个长期存在的变量,例如视图控制器的属性。