简体   繁体   English

使用 AVPlayer 处理流事件

[英]Handle streaming events with AVPlayer

I'm building an app which plays an audio stream (from a webradio).我正在构建一个播放音频流的应用程序(来自网络广播)。

I'm using AVPlayer for it.我正在使用AVPlayer

  1. I'd like to know how you would handle AVPlayer's "buffering" when the connection is slow or when the user just clicked "play".我想知道当连接速度较慢或用户只是单击“播放”时,您将如何处理AVPlayer's “缓冲”。 I want to detect that AVPlayer is "buffering" to display an UIActivityIndicatorView .我想检测AVPlayer正在“缓冲”以显示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你可以参考我关于这个主题的回答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; ps:任务在我的 .h 文件中声明为UIBackgroundTaskIdentifier task;

I have found the solution to this problem.我已经找到了解决这个问题的方法。

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

For Swift 3对于 Swift 3

This works fine for me, maybe it can help, call self?.bufferState() inside addPeriodicTimeObserver这对我来说很好用,也许它可以帮助,在addPeriodicTimeObserver调用self?.bufferState()

    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];
             }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM