ios 使用 AVPlayer 处理流事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6366005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handle streaming events with AVPlayer
提问by Quentin Hayot
I'm building an app wich 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". I want to detect that AVPlayer
is "buffering" to display an UIActivityIndicatorView
.
1)我想知道你会如何处理AVPlayer's
“缓冲”,当连接速度慢,或者当用户刚刚点击“播放”。我想检测它AVPlayer
是“缓冲”以显示UIActivityIndicatorView
.
2) Same question while running in the background. What should I do if buffering in this case?
2)在后台运行时出现同样的问题。如果在这种情况下进行缓冲,我该怎么办?
Thanks !
谢谢 !
回答by sciasxp
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;
回答by Nir
I have found the solution to this problem.
我已经找到了解决这个问题的方法。
if (self.avPlayer.currentItem.playbackLikelyToKeepUp == NO)
{
// Show activity indicator
}
回答by DoubleK
For Swift 3
对于 Swift 3
This works fine for me, maybe it can help, call self?.bufferState()
inside addPeriodicTimeObserver
这个作品对我很好,也许它可以帮助,电话self?.bufferState()
里面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")
}
}
回答by NSPratik
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];
}
}
}
}