AVPlayer状态监听器在swift中

时间:2017-02-03 13:25:07

标签: ios swift swift3 avfoundation avplayer

我想知道如何获取播放器的状态(AVPlayer)(缓冲,播放,停止,错误)并根据这些状态(包括锁定屏幕上的播放器)更新ui。我该怎么办呢?

我有一个标签可能包含: “缓冲......”,“播放”,“停止”或“错误”。

基本上,我有以下内容:

的MediaPlayer

import Foundation
import AVFoundation

class MediaPlayer {

    static let sharedInstance = MediaPlayer()
    fileprivate var player = AVPlayer(url: URL(string: "my_hls_stream_url_here")!)
    fileprivate var isPlaying = false

    func play() {
        player.play()
        isPlaying = true
    }

    func pause() {
        player.pause()
        isPlaying = false
    }

    func toggle() {
        if isPlaying == true {
            pause()
        } else {
            play()
        }
    }

    func currentlyPlaying() -> Bool {
        return isPlaying
    }

}

PlayerViewController

class PlayerViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    @IBAction func playStopButtonAction(_ sender: UIButton) {
        MediaPlayer.sharedInstance.toggle()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = "Disconnected"

        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)

            print("Audio session ok\n")
        } catch {
            print("Error: Audio session.\n")
        }

        // Show only play/pause button on the lock screen
        if #available(iOS 9.1, *) {

            let center = MPRemoteCommandCenter.shared()

            [center.previousTrackCommand, center.nextTrackCommand, center.seekForwardCommand, center.seekBackwardCommand, center.skipForwardCommand, center.skipBackwardCommand, center.ratingCommand, center.changePlaybackRateCommand, center.likeCommand, center.dislikeCommand, center.bookmarkCommand, center.changePlaybackPositionCommand].forEach {
                $0.isEnabled = false
            }

            center.togglePlayPauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
                MediaPlayer.sharedInstance.toggle()
                return MPRemoteCommandHandlerStatus.success
            }

            center.playCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
                MediaPlayer.sharedInstance.play()
                return MPRemoteCommandHandlerStatus.success
            }

            center.pauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
                MediaPlayer.sharedInstance.pause()
                return MPRemoteCommandHandlerStatus.success
            }

        } else {
            // Fallback on earlier versions
            print("Error (MPRemoteCommandCenter)")
        }


    }


    override func remoteControlReceived(with event: UIEvent?) {
        guard let event = event else {
            print("No event\n")
            return
        }
        guard event.type == UIEventType.remoteControl else {
            print("Another event received\n")
            return
        }
        switch event.subtype {
        case UIEventSubtype.remoteControlPlay:
            print("'Play' event received\n")
        case UIEventSubtype.remoteControlPause:
            print("'Pause' event received\n")
        case UIEventSubtype.remoteControlTogglePlayPause:
            print("'Toggle' event received\n")
        default:
            print("\(event.subtype)\n")
        }
    }

}

2 个答案:

答案 0 :(得分:0)

我认为您可以使用timeControlStatus的{​​{1}}属性。根据{{​​3}},AVPlayerpaused可以是waitingToPlayAtSpecifiedRatebuffering

如果您确实需要playing州,则可以观察error to the docerror property是否设为status

关于这些属性的简单KVO观察者可以解决这个问题。

答案 1 :(得分:0)

开始的地方可能是使用AVPlayer的“status”属性。它是一个包含以下值的枚举(直接来自文档):

  1. 'unknown':表示尚未知道播放器的状态,因为它尚未尝试加载新的媒体资源进行播放。

  2. 'readyToPlay':表示播放器已准备好播放AVPlayerItem实例。

  3. '失败':表示播放器因错误而无法播放AVPlayerItem实例。

  4. 至于如何判断内容是否实际正在播放,你可以使用布尔检查,因为它似乎已经部分实现了。对于暂停和停止,您可以保持文件加载暂停,并删除文件以便停止,以便区分这两者。

    对于缓冲,如果枚举不是未知 readyToPlay 那么理论上应该意味着有一个文件正在附加但尚未准备好播放(即缓冲)。