在 AVPlayer 中播放网络不佳的流

Posted

技术标签:

【中文标题】在 AVPlayer 中播放网络不佳的流【英文标题】:Playing stream with bad internet in AVPlayer 【发布时间】:2014-04-02 13:48:49 【问题描述】:

当 AVPlayer 播放来自网络流的资源时,它会在下载内容结束时暂停。

所以,我的问题是,如何知道它是因为网络不好而停止的?以及如何在下载后播放它,比如说,接下来的 10 秒资产?

【问题讨论】:

【参考方案1】:

您可以在 AVPlayer 获得空缓冲区时添加观察者:

[[self.tracksPlayer currentItem] addObserver:self 
                                  forKeyPath:@"playbackBufferEmpty" 
                                     options:NSKeyValueObservingOptionNew
                                     context:nil];

还有一个观察者,这样您就可以知道 AVPlayer 何时缓冲到足以跟上:

[[self.tracksPlayer currentItem] addObserver:self 
                                  forKeyPath:@"playbackLikelyToKeepUp" 
                                     options:NSKeyValueObservingOptionNew 
                                     context:nil];

然后在您的 KVO 回调中检查它:

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context 

   if (object == [self.tracksPlayer currentItem] && 
      [keyPath isEqualToString:@"playbackBufferEmpty"]) 

      if ([self.tracksPlayer currentItem].playbackBufferEmpty) 
          NSLog(@"Buffer Empty"); 
      
    else if (object == [self.tracksPlayer currentItem] && 
             [keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 

      if ([self.tracksPlayer currentItem].playbackLikelyToKeepUp) 
          NSLog(@"LikelyToKeepUp");
      
   

【讨论】:

Apple 文档说 playbackLikelyToKeepUp 可能是 NO,即使 playbackBufferFullYES。据我了解,playbackLikelyToKeepUp 是基于互联网连接速度,而不是缓冲区中的数据量。 这其实是次要的,可以用也可以不用。虽然我不知道,但谢谢你的信息:) 所以我需要观察loadedTimeRanges 属性并检查它是否加载足够? 也可以观察status属性查看if (self.tracksplayer.status == AVPlayerStatusReadyToPlay)【参考方案2】:

为了快速

1)
let playbackLikelyToKeepUpContext = UnsafeMutablePointer<(Void)>(nil)
 or
let playbackLikelyToKeepUpContext = UnsafeMutablePointer<(Void)>()

2) //Add Observer

  player.addObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp",
                                    options: NSKeyValueObservingOptions.New, context: playbackLikelyToKeepUpContext)
  player.play()

3)

//Add observer
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) 

        guard keyPath != nil else  // a safety precaution
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
            return
        

        if (context == playbackLikelyToKeepUpContext)
        
            if (player.currentItem!.playbackLikelyToKeepUp) 
                player.play()
                Utilities.hideHUD(self.view)
            
            else 
                Utilities.showHUD(self.view)
            
        
    

4) // Remove Observer

override func viewDidDisappear(animated: Bool) 
        player.removeObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp")
    

【讨论】:

【参考方案3】:

Swift 4 改变了 KVO 的方式。我们不是单独添加观察者和函数,而是在一个地方使用闭包(块)。

var observers: [NSKeyValueObservation]?
let playerItem = AVPlayerItem(url: YOUR_URL)

let emptyObserver = playerItem.observe(\.isPlaybackBufferEmpty) 
                        [weak self] (object, observedChange) in
                        // show a progress bar 
                        print("isPlaybackBufferEmpty")
                    

let keepUpObserver = playerItem.observe(\.playbackLikelyToKeepUp) 
                        [weak self] (object, observedChange) in
                        // hide progress bar and keep going 
                        print("playbackLikelyToKeepUp")
                    

self.observers = [emptyObserver, keepUpObserver]

【讨论】:

以上是关于在 AVPlayer 中播放网络不佳的流的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer seekToTime:循环播放短视频时性能不佳

UIView 中的 AVPlayer 视图缺少控件

小米1S无线网连接时老是出现暂时关闭状态不佳的链接

性能不佳的 SQL 查询

AVPlayer播放网络音乐

性能不佳的 ML Kit 条码扫描