swift中的AVPlayer状态监听器

Posted

技术标签:

【中文标题】swift中的AVPlayer状态监听器【英文标题】:AVPlayer state listener in swift 【发布时间】:2017-02-03 13:25:06 【问题描述】:

我想知道如何获取我的播放器 (AVPlayer) 的状态(缓冲、播放、停止、错误)并根据这些状态更新用户界面(包括锁定屏幕上的播放器)。具体应该怎么做?

我的标签可能包含: “正在缓冲...”、“正在播放”、“已停止”或“错误”。

基本上,我有以下几点:

媒体播放器

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


【问题讨论】:

【参考方案1】:

我认为您可以使用AVPlayertimeControlStatus 属性。根据to the doc,它可以是pausedwaitingToPlayAtSpecifiedRate,基本上就是你所说的bufferingplaying

如果你真的需要error状态,你可以观察errorproperty或者statusproperty是否设置为failed

对这些属性进行简单的 KVO 观察器就可以解决问题。

【讨论】:

【参考方案2】:

可以从使用 AVPlayer 的“状态”属性开始。它是一个包含以下值的枚举(直接取自文档):

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

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

    'failed':表示由于错误,播放器无法再播放 AVPlayerItem 实例。

至于如何判断内容是否正在播放,您可以使用布尔检查,因为您似乎已部分实现。对于暂停和停止,您可以只保留加载的文件以暂停,并删除文件以停止,这样您就可以区分两者。

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

【讨论】:

我按照你的说法试过了,但我总是得到“readyToPlay”(1)/:你能告诉我我该怎么做吗?使用 KVO (#3):developer.apple.com/library/content/documentation/Swift/…

以上是关于swift中的AVPlayer状态监听器的主要内容,如果未能解决你的问题,请参考以下文章

iOS 开发 AVPlayer 深入浅出

AVFoundation学习笔记:视频播放相关

在 Swift 中以编程方式设置动作监听器

监听蓝牙外设按钮事件 iOS Swift

react监听仓库数据变化

如何在 Swift iOS 中监听来自服务器的网络数据?