使用 AVPlayer 处理流媒体事件

发布于 2024-11-15 10:15:16 字数 283 浏览 3 评论 0原文

我正在构建一个播放音频流(来自网络广播)的应用程序。

我正在使用 AVPlayer 来实现它。

  1. 我想知道当连接速度较慢或用户只是单击“播放”时,您将如何处理 AVPlayer 的“缓冲”。我想检测 AVPlayer 正在“缓冲”以显示 UIActivityIndi​​catorView

  2. 在后台运行时出现同样的问题。这种情况下缓冲怎么办?

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 or 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深府石板幽径 2024-11-22 10:15:16

对于第一个问题

你可以参考我关于这个主题的回答ios avplayer触发器流媒体超出缓冲区

对于第二个,

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

在处理缓冲区空事件的位置添加以下代码:

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

ps:任务在我的 .h 文件中声明为 UIBackgroundTaskIdentifier 任务;

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;

王权女流氓 2024-11-22 10:15:16

我已经找到了这个问题的解决方案。

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

I have found the solution to this problem.

if (self.avPlayer.currentItem.playbackLikelyToKeepUp == NO) 
{
    // Show activity indicator
}
在风中等你 2024-11-22 10:15:16

对于 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")
    }
}

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")
    }
}
故事↓在人 2024-11-22 10:15:16

试试这个:

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

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];
             }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文