检测文件流已完成并准备好使用 avplayer 播放

Posted

技术标签:

【中文标题】检测文件流已完成并准备好使用 avplayer 播放【英文标题】:Detect file streaming finished and ready to play with avplayer 【发布时间】:2018-12-08 13:44:59 【问题描述】:

我正在使用 avplayer 从远程服务器播放音频文件。当我播放这个时,首先从 url 播放 avplayer 流,然后播放文件。现在我只想检测文件流何时完成并开始播放。

这是我的代码:

try AVAudiosession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)

player = AVPlayer(url: down_url)
player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
player.volume = 1.0
player.play()


override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
    if keyPath == "rate" 
        if player.rate > 0 
            print("player started")
        
    

我使用此代码进行检测,但它仅在 avplayer 开始流式传输时打印“播放器启动”一次。但我无法检测到 avplayer 何时开始播放。

【问题讨论】:

【参考方案1】:

注册为玩家物品状态属性的观察者

playerItem.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: &playerItemContext)

这个方法会被调用

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 

    // Only handle observations for the playerItemContext
    guard context == &playerItemContext else 
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        return
    


    // Observer for Player status
    if keyPath == #keyPath(AVPlayerItem.status) 
        let status: AVPlayerItem.Status
        if let statusNumber = change?[.newKey] as? NSNumber 
            status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
         else 
            status = .unknown
        

        // Switch over status value
        switch status 
        case .readyToPlay:
            // Player item is ready to play.
            player.play()
            playerControlsView.setPlayerControlsReady()
        case .failed:
            // Player item failed. See error.
            print("Fail")
        case .unknown:
            // Player item is not yet ready.
            print("unknown")
        
    


添加观察者以监控播放器何时完成播放

NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)

当播放器结束播放时调用此方法

@objc func playerDidFinishPlaying(note: NSNotification)
        print("Finished Playing")

当你完成播放器时不要忘记移除观察者

NotificationCenter.default.removeObserver(self)

【讨论】:

以上是关于检测文件流已完成并准备好使用 avplayer 播放的主要内容,如果未能解决你的问题,请参考以下文章

在加载资产后立即在AVPlayer中寻找某个位置

CKEDITOR 脚本何时加载并准备好使用?

Netty 4.0:检测,如果 Websocket 握手完成

Doctrine 2.0 准备好使用了吗?

AVPlayer 暂停后无法继续播放

准备好使用 Vue.js 访问子组件中的 api 数据