How can I check if my AVPlayer is buffering?

后端 未结 10 1060
后悔当初
后悔当初 2020-12-01 06:02

I want to detect if my AVPlayer is buffering for the current location, so that I can show a loader or something. But I can\'t seem to find anything in the documentation for

相关标签:
10条回答
  • 2020-12-01 06:59

    Updated for Swift 4.2

        var player : AVPlayer? = nil
    
        let videoUrl = URL(string: "https://wolverine.raywenderlich.com/content/ios/tutorials/video_streaming/foxVillage.mp4")
        self.player = AVPlayer(url: videoUrl!)
        self.player?.addPeriodicTimeObserver(forInterval: CMTimeMake(value: 1, timescale: 600), queue: DispatchQueue.main, using: { time in
    
            if self.player?.currentItem?.status == AVPlayerItem.Status.readyToPlay {
    
                if let isPlaybackLikelyToKeepUp = self.player?.currentItem?.isPlaybackLikelyToKeepUp {
                    //do what ever you want with isPlaybackLikelyToKeepUp value, for example, show or hide a activity indicator.
    
                    //MBProgressHUD.hide(for: self.view, animated: true)
                }
            }
        })
    
    0 讨论(0)
  • 2020-12-01 07:01

    The accepted answer didn't work for me, I used the code below to show the loader efficiently.

    Swift 3

    //properties 
    var observer:Any!
    var player:AVPlayer!
    
    
    self.observer = self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 600), queue: DispatchQueue.main) {
        [weak self] time in
    
        if self?.player.currentItem?.status == AVPlayerItemStatus.readyToPlay {
    
            if let isPlaybackLikelyToKeepUp = self?.player.currentItem?.isPlaybackLikelyToKeepUp {
                //do what ever you want with isPlaybackLikelyToKeepUp value, for example, show or hide a activity indicator.
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 07:01

    Swift 4 observations:

    var playerItem: AVPlayerItem?
    var playbackLikelyToKeepUpKeyPathObserver: NSKeyValueObservation?
    var playbackBufferEmptyObserver: NSKeyValueObservation?
    var playbackBufferFullObserver: NSKeyValueObservation?
    
    private func observeBuffering() {
        let playbackBufferEmptyKeyPath = \AVPlayerItem.playbackBufferEmpty
        playbackBufferEmptyObserver = playerItem?.observe(playbackBufferEmptyKeyPath, options: [.new]) { [weak self] (_, _) in
            // show buffering
        }
    
        let playbackLikelyToKeepUpKeyPath = \AVPlayerItem.playbackLikelyToKeepUp
        playbackLikelyToKeepUpKeyPathObserver = playerItem?.observe(playbackLikelyToKeepUpKeyPath, options: [.new]) { [weak self] (_, _) in
            // hide buffering
        }
    
        let playbackBufferFullKeyPath = \AVPlayerItem.playbackBufferFull
        playbackBufferFullObserver = playerItem?.observe(playbackBufferFullKeyPath, options: [.new]) { [weak self] (_, _) in
            // hide buffering
        }
    }
    

    Observers need to be removed after we are done observing.

    To remove these three observers just set playbackBufferEmptyObserver, playbackLikelyToKeepUpKeyPathObserver and playbackBufferFullObserver to nil.

    No need to remove them manually (this is specific for observe<Value>(_ keyPath:, options:, changeHandler:) method.

    0 讨论(0)
  • 2020-12-01 07:01

    Solution for Xamarin inspired by 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 讨论(0)
提交回复
热议问题