观察AVPlayer:-observeValueForKeyPath:ofObject:change:context:收到消息但未处理

时间:2017-09-01 08:41:48

标签: ios swift swift3 key-value-observing kvocontroller

您好我试图在AVPlayerItem中观察AVPlayerUIViewController

但是我在做这件事时遇到了一些麻烦。我已经搜索了很多并找到了很多例子,但这些都不适合我。

这是我的ViewController

class VideoAudioViewController: UIViewController {
    var audioPlayer: AVPlayer!
    var playerItem: AVPlayerItem!
    private var audio: Audio

    private let ITEM_STATUS_PATH = #keyPath(AVPlayerItem.status)
    private let PLAYER_STATUS_PATH = #keyPath(AVPlayer.status)
    private let PLAYER_RATE_PATH = #keyPath(AVPlayer.rate)

    init(for audio: Audio) {
        self.audio = audio
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Play audio
        playerItem = AVPlayerItem(url: audio.url)
        playerItem.addObserver(self, forKeyPath: ITEM_STATUS_PATH, options: [.old, .new], context: nil)
        audioPlayer = AVPlayer(playerItem: playerItem)
        audioPlayer!.play()
//            audioPlayer!.
        var audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setCategory(AVAudioSessionCategoryPlayback)
        } catch {
            print("error")
        }

        NotificationCenter.default.addObserver(
            self, selector: #selector(handleInterruption), name: .AVAudioSessionInterruption, object: audioSession)
        audioPlayer.addObserver(self, forKeyPath: PLAYER_STATUS_PATH, options: [.old, .new], context: nil)
        audioPlayer.addObserver(self, forKeyPath: PLAYER_RATE_PATH, options: [.old, .new], context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)  {
        if keyPath == "status" {
            switch (audioPlayer.status) {
            case AVPlayerStatus.readyToPlay:
                print("player status ready to play")
                audioPlayer.play()
                break
            case AVPlayerStatus.failed:
                print("player status failed")
                break
            default:
                break
            }
            return
        } else if keyPath == "rate" {
            if audioPlayer.rate != 0 {
                playPauseButton.setImage(#imageLiteral(resourceName: "ic_pause_circle_outline_white"), for: .normal)
            } else {
                playPauseButton.setImage(#imageLiteral(resourceName: "ic_play_circle_outline_white"), for: .normal)
            }
        } else if keyPath == "status" {
            switch (playerItem.status) {
            case AVPlayerItemStatus.readyToPlay:
                print("player item ready to play")
                break
            case AVPlayerItemStatus.failed:
                print("player item failed")
                break
            default:
                break
            }
            return
        }
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }

    // MARK: - AVAudioPlayer delegate
    func handleInterruption(_ notification: Notification) {
        guard let info = notification.userInfo,
              let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
              let type = AVAudioSessionInterruptionType(rawValue: typeValue) else {
            return
        }
        if type == .began {
            playPauseButton.setImage(#imageLiteral(resourceName: "ic_play_circle_outline_white"), for: .normal)
        }
        else if type == .ended {
//            guard let optionsValue =
//            userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
//                return
//            }
//            let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
//            if options.contains(.shouldResume) {
                // Interruption Ended - playback should resume
                audioPlayer?.play()
//            }
        }
    }

}

我的问题是:

Terminati

ng app due to uncaught exception 'NSInternalInconsistencyException', reason: '<TheSimpleClub_Nachhilfe.VideoAudioViewController: 0x7fa6ee2b0c10>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: rate
Observed object: <AVPlayer: 0x60000021c8c0>
Change: {
    kind = 1;
    new = 1;
    old = 1;
}
Context: 0

x0'

此行中出现错误:

super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)

我该怎么做才能解决这个问题?

0 个答案:

没有答案