使用AVPlayer处理流媒体事件

19

我正在开发一个播放音频流的应用(来自网络电台)。

我使用 AVPlayer 进行开发。

  1. 我想知道在连接缓慢或用户刚点击“播放”时如何处理 AVPlayer 的“缓冲”。我想检测 AVPlayer 是否正在“缓冲”,以显示 UIActivityIndicatorView

  2. 在后台运行时也是同样的问题。如果在这种情况下出现缓冲,我应该怎么办?

4个回答

27

对于第一个问题

您可以参考我在此主题上的回答ios avplayer trigger streaming is out of buffer

对于第二个问题

这是我解决同样问题的方法:

在处理缓冲区空时的事件处理程序中添加以下代码:

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

现在,当您的缓冲区准备好继续使用时,您将需要停止此后台任务:

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

备注:在我的 .h 文件中,任务被声明为 UIBackgroundTaskIdentifier task;


为什么你需要在这里使用后台任务?我看不出它的联系。 - z8000
5
当您的应用程序在后台并且由于某种原因您的流已停止时,iOS 将终止播放器,您将无法在重新开始接收流后继续播放。因此,我们可以通过这个方法欺骗 iOS 让它认为您的播放器仍在工作。 - sciasxp
1
你的任务块里需要什么吗?还是只是为了让循环在应用程序委托上运行? - quantumpotato

10
我已经找到了解决这个问题的方法。
if (self.avPlayer.currentItem.playbackLikelyToKeepUp == NO) 
{
    // Show activity indicator
}

3
你用了什么方法来实现这个? - Ruben Martinez Jr.
Ruben Martinez Jr - 使用计时器进行检查(1秒最佳),当KeepUp == YES时,timer.invalidate()。 - Nikola Lukic

2

针对Swift 3

这对我来说很好用,也许可以帮助你。在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")
    }
}

0

试试这个:

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

2
什么是上下文,它来自哪里?您能否包括方法声明和/或调用? - Julian F. Weinert
请给出适当的解释,不要浪费他人的时间!! - Sumit singh

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