如果没有更多可用媒体(网络速度太慢,信号丢失等)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次。但我无法弄清楚每次播放停止时如何获取它们。
我做错了吗?
答案 0 :(得分:2)
首先尝试断开互联网与路由器的连接,然后您将获得playbackBufferEmpty通知。 要处理网络切换,您需要实施Reachability
答案 1 :(得分:1)
有两种情况可以让玩家卡住:它永远不会启动或者用完缓冲数据。我使用以下方法来处理这两种情况:
创建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