如何检查我的AVPlayer是否正在缓冲?

42

我希望能检测到我的 AVPlayer 是否在当前位置进行缓冲,以便我可以显示加载器或者其他提示。但是我在 AVPlayer 的文档中找不到相关信息。

15个回答

1
请注意:
在回调块中使用弱引用self以防止创建保留循环。
func playRemote(url: URL) {
            showSpinner()
            let playerItem = AVPlayerItem(url: url)
            avPlayer = AVPlayer(playerItem: playerItem)
            avPlayer.rate = 1.0
            avPlayer.play()
            self.avPlayer.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1,
     timescale: 600), queue: DispatchQueue.main, using: { [weak self] time in
                if self?.avPlayer.currentItem?.status == AVPlayerItem.Status.readyToPlay {
                    if let isPlaybackLikelyToKeepUp = self?.avPlayer.currentItem?.isPlaybackLikelyToKeepUp { 
                        self?.removeSpinner()
                    }
                }
            })
        }
}

1

这是针对Xamarin的解决方案,受到Marco's answer的启发。

// KVO registrations
private void Initialize()
{
    playbackBufferEmptyObserver?.Dispose();
    playbackBufferEmptyObserver = (NSObject)playerItem.AddObserver("playbackBufferEmpty",
        NSKeyValueObservingOptions.New,
        AVPlayerItem_BufferUpdated);

    playbackLikelyToKeepUpObserver?.Dispose();
    playbackLikelyToKeepUpObserver = (NSObject)playerItem.AddObserver("playbackLikelyToKeepUp",
        NSKeyValueObservingOptions.New,
        AVPlayerItem_BufferUpdated);

    playbackBufferFullObserver?.Dispose();
    playbackBufferFullObserver = (NSObject)playerItem.AddObserver("playbackBufferFull",
        NSKeyValueObservingOptions.New,
        AVPlayerItem_BufferUpdated);
}

private void AVPlayerItem_BufferUpdated(NSObservedChange e)
{
    ReportVideoBuffering();
}

private void ReportVideoBuffering()
{
    // currentPlayerItem is the current AVPlayerItem of AVPlayer
    var isBuffering = !currentPlayerItem.PlaybackLikelyToKeepUp;
    // NOTE don't make "buffering" as one of your PlayerState.
    // Treat it as a separate property instead. Learned this the hard way.
    Buffering?.Invoke(this, new BufferingEventArgs(isBuffering));
}

0
这是一个简单的方法,适用于Swift 5
这将在您的播放器停顿时添加loadingIndicator。
NotificationCenter.default.addObserver(self, selector:
#selector(playerStalled(_:)), name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: self.player?.currentItem)

@objc func playerStalled(_ notification: Notification){
    self.loadingIndicator.isHidden = false
    self.playPauseButton.isHidden = true
}

当缓冲区为空时,这将显示加载指示器:

if let isPlayBackBufferEmpty = self.player?.currentItem?.isPlaybackBufferEmpty{
    if isPlayBackBufferEmpty{
        self.loadingIndicator.isHidden = false
        self.playPauseButton.isHidden = true
    }
}

当播放器准备好播放时,这将隐藏加载程序:

if self.playerItem?.status == AVPlayerItem.Status.readyToPlay{
    if let isPlaybackLikelyToKeepUp = self.player?.currentItem?.isPlaybackLikelyToKeepUp {
        if isPlaybackLikelyToKeepUp{
            self.loadingIndicator.isHidden = true
            self.playPauseButton.isHidden = false
        }
    }
}

以上通知没有被调用,你能帮忙吗? - Kedar Sukerkar

0
您可以像这样检查播放器是否正在缓冲/加载:
let playerObserver = self.player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.main, using: { [weak self] time in
        if self?.player.timeControlStatus == .playing {
            debugPrint("#player - info: isPlaying")
            self?.playButton.isSelected = true
        } else if self?.player.timeControlStatus == .paused {
            debugPrint("#player - info: isPaused")
            self?.playButton.isSelected = false
        } else if self?.player.timeControlStatus == .waitingToPlayAtSpecifiedRate {
            debugPrint("#player - info: isWaiting") //Buffering
        }
    })

0
对于 RXswift 的粉丝们,你可以通过给 Reactive 类添加一个扩展来检查 AVPlayer 的缓冲状态:
extension Reactive where Base: AVPlayerItem {
    public var playbackBufferEmpty: Observable<Bool> {
        return self.observe(Bool.self, #keyPath(AVPlayerItem.isPlaybackBufferEmpty))
            .map { $0 ?? false }
    }
}

然后按照以下方式使用:

   avPlayerItem.rx.playbackBufferEmpty
   .subscribe(onNext: {isLoading in

      //Do whatever you want

    }).disposed(by: disposeBag)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接