开发者

Handle streaming events with AVPlayer

开发者 https://www.devze.com 2023-03-13 19:03 出处:网络
I\'m building an app which plays an audio stream (from a webradio). I\'m using AVPlayer for it. I\'d like to know how you would handle AVPlayer\'s "buffering" when the connection is slow o开

I'm building an app which plays an audio stream (from a webradio).

I'm using AVPlayer for it.

  1. I'd like to know how you would handle AVPlayer's "buffering" when the connection is slow o开发者_Python百科r when the user just clicked "play". I want to detect that AVPlayer is "buffering" to display an UIActivityIndicatorView.

  2. Same question while running in the background. What should I do if buffering in this case?


For the first question

You can refer to my answer on this topic ios avplayer trigger streaming is out of buffer

For the second

Here is how I solved this same problem:

Inside where you handle the event for buffer empty add this code:

    if (object == playerItem && [keyPath isEqualToString:@"playbackBufferEmpty"])
    {
        if (playerItem.playbackBufferEmpty) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"message" object:@"Buffering..."];
            
            if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
            {
                task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
                }];
            }
        }
    }

Now you will have to stop this background task after your buffer is ready to go again:

if (object == playerItem && [keyPath isEqualToString:@"playbackLikelyToKeepUp"])
{
    if (playerItem.playbackLikelyToKeepUp)
    {
        [player play];
        
        if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
        {
            [[UIApplication sharedApplication] endBackgroundTask:task];
            task = 0;
        }
    }
}

ps: task is declared on my .h file as UIBackgroundTaskIdentifier task;


I have found the solution to this problem.

if (self.avPlayer.currentItem.playbackLikelyToKeepUp == NO) 
{
    // Show activity indicator
}


For Swift 3

This works fine for me, maybe it can help, call self?.bufferState() inside addPeriodicTimeObserver

    private func bufferState() {
    if let currentItem = self.avPlayer.currentItem {
        if currentItem.status == AVPlayerItemStatus.readyToPlay {
            if currentItem.isPlaybackLikelyToKeepUp {
                print("Playing ")
            } else if currentItem.isPlaybackBufferEmpty {
                print("Buffer empty - show loader")
            }  else if currentItem.isPlaybackBufferFull {
                print("Buffer full - hide loader")
            } else {
                print("Buffering ")
            }
        } else if currentItem.status == AVPlayerItemStatus.failed {
            print("Failed ")
        } else if currentItem.status == AVPlayerItemStatus.unknown {
            print("Unknown ")
        }
    } else {
        print("avPlayer.currentItem is nil")
    }
}


Try this:

AVPlayerItem* mPlayerItem;

if(context == AVPlayerDemoPlaybackViewControllerCurrentItemBufferEmptyContext) 
{
    if (object == self.mPlayerItem && [path isEqualToString:@"playbackBufferEmpty"]) 
    {
        if (self.mPlayerItem.playbackBufferEmpty)
        {
            playBufferEmpty = TRUE;
            [indicator startAnimating];
            [vidStreaminglabel setText:@"Buffering..."];
            [vidStreaminglabel setHidden:NO];
        }
    }
}

else if(context == AVPlayerDemoPlaybackViewControllerCurrentItemPlayBackBufferFullContext)
{
    if (object == mPlayerItem && [path isEqualToString:@"playbackBufferFull"]){
        if (self.mPlayerItem.playbackBufferFull) {
            [mPlayer play];
        }
    }
}

else if (context == AVPlayerDemoPlaybackViewControllerCurrentItemPlayBackLikelyToKeepUpContext)
{
    if (object == mPlayerItem && [path isEqualToString:@"playbackLikelyToKeepUp"])
    {
         if(self.mPlayerItem.playbackLikelyToKeepUp)
         {
             // Autoplay after buffer 
             if(!(mRestoreAfterScrubbingRate != 0.f || [self.mPlayer rate] != 0.f))
             {
                 if (self.presentingViewController) {
                     [mPlayer play];
                 }

                 playBufferEmpty = FALSE;
                 [indicator stopAnimating];
                 [vidStreaminglabel setHidden:YES];
             }
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号