处理 AVPlayer 停顿
Posted
技术标签:
【中文标题】处理 AVPlayer 停顿【英文标题】:Handling AVPlayer stalls 【发布时间】:2013-12-26 12:02:57 【问题描述】:我正试图捕捉AVPlayer
无法继续播放的时刻,以防没有更多可用媒体(网络太慢、信号丢失等)。如文档和不同示例中所述,我使用KVO
来检测:
item = [[AVPlayerItem alloc] initWithURL:audioURL];
player = [AVPlayer playerWithPlayerItem:item];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onItemNotification:) name:AVPlayerItemPlaybackStalledNotification object:item];
[item addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[item addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
...
- (void) onItemNotification:(NSNotification*)not
NSLog(@"Item notification: %@", not.name);
...
- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
NSLog(@"Observe keyPath %@", keyPath);
我正在开始播放,然后关闭WiFi
。不幸的是,“playbackBufferEmpty
”和“AVPlayerItemPlaybackStalledNotification
”都没有出现。在播放停止的那一刻,我只收到一个AVPlayerItemTimeJumpedNotification
,仅此而已。
但是,当我收到这些通知时,至少有 2 次。但是我不知道每次播放停止时如何获取它们。
我做错了吗?
【问题讨论】:
【参考方案1】:首先尝试断开您的路由器与互联网的连接,您将收到playbackBufferEmpty 通知。 要处理网络切换,您需要实现 Reachability
【讨论】:
可达性和播放停顿结合了两个不同的东西。【参考方案2】:播放器有两种情况会卡住:它永远不会启动或缓冲数据用完。我使用以下方法来处理这两种情况:
当你创建一个 AVPlayer 实例时:
[_player addObserver:self forKeyPath:@"rate" options:0 context:nil];
[_player.currentItem addObserver:self forKeyPath:@"status" options:0 context:nil];
这是处理程序:
-(void)observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context
if ([keyPath isEqualToString:@"status"])
if (_player.status == AVPlayerStatusFailed)
//Failed to start.
//Description from the docs:
// Indicates that the player can no longer play AVPlayerItem instances because of an error. The error is described by
// the value of the player's error property.
else if ([keyPath isEqualToString:@"rate"])
if (_player.rate == 0 && //playback rate is 0
CMTIME_COMPARE_INLINE(_player.currentItem.currentTime, >, kCMTimeZero) && //video has started
CMTIME_COMPARE_INLINE(_player.currentItem.currentTime, <, _player.currentItem.duration) && //video hasn't reached the end
_isPlaying) //instance variable to track playback state
//Video stalled. Possible connection loss or connection is too slow.
完成后别忘了移除观察者:
[_player.currentItem removeObserver:self forKeyPath:@"status"];
[_player removeObserver:self forKeyPath:@"rate"];
在此处查看我的答案,了解我如何处理停滞的视频:AVPlayer stops playing and doesn't resume again
【讨论】:
“_isPlaying”如何获得?以上是关于处理 AVPlayer 停顿的主要内容,如果未能解决你的问题,请参考以下文章