AVPlayer 项目缓冲区为空
Posted
技术标签:
【中文标题】AVPlayer 项目缓冲区为空【英文标题】:AVPlayer item buffer empty 【发布时间】:2013-07-30 08:42:47 【问题描述】:我使用播放流内容的 AVPlayer。我想知道缓冲区为空的时间以及准备播放的时间。但是观察者“playbackBufferEmpty”和“playbackLikelyToKeepUp”并不是每次都按需要工作。他们有时工作,但往往不工作。我在 OSX 10.7.5 下只使用 iPad 模拟器 ios 6.1。 以下是我设置和监听观察者的方式:
- (void)playAudioStream:(NSURL *)audioStreamURL
if(_audioPlayer && _audioPlayer.currentItem)
[_audioPlayer removeObserver:self forKeyPath:StatusKey];
[_audioPlayer.currentItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
[_audioPlayer.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:audioStreamURL];
[playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
[playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
_audioPlayer = [AVPlayer playerWithPlayerItem:playerItem];
[_audioPlayer addObserver:self forKeyPath:StatusKey options:NSKeyValueObservingOptionNew context:nil];
//[_audioPlayer replaceCurrentItemWithPlayerItem:playerItem];
//_audioPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[_audioPlayer play];
...
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
if ([keyPath isEqualToString:@"playbackBufferEmpty"] )
if (_audioPlayer.currentItem.playbackBufferEmpty)
...
if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"])
if (_audioPlayer.currentItem.playbackLikelyToKeepUp)
...
请帮助我获取“缓冲区空”和“缓冲区就绪”事件的正确方法(例如,当 Internet 连接中断时)。谢谢!
【问题讨论】:
【参考方案1】:添加观察者时需要使用上下文。这是给你的示例代码。
初始化上下文
static void *playbackLikelyToKeepUpKVOToken = &playbackLikelyToKeepUpKVOToken;
static void *playbackBufferEmpty = &playbackBufferEmpty;
static void *playbackBufferFull = &playbackBufferFull;
添加观察者
[self.playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty" context:playbackBufferEmpty];
[self.playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp" context:playbackLikelyToKeepUpKVOToken];
[self.playerItem removeObserver:self forKeyPath:@"playbackBufferFull" context:playbackBufferFull];
手柄
if (context == playbackLikelyToKeepUpKVOToken)
if (self.playerItem.playbackLikelyToKeepUp)
NSLog(@"recieve playbackLikelyToKeepUp");
else if (context == playbackBufferEmpty)
if (self.playerItem.playbackBufferEmpty)
NSLog(@"recieve playbackBufferEmpty");
else if(context == playbackBufferFull)
NSLog(@"recieve playbackBufferFull");
else
[super observeValueForKeyPath:path ofObject:object change:change context:context];
【讨论】:
【参考方案2】:@Nghia Tran 的回答帮助了我。 他只是混淆了添加观察者/删除观察者(我们需要两者)
添加观察者:
[self.playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:playbackBufferEmpty];
[self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:playbackLikelyToKeepUpKVOToken];
[self.playerItem addObserver:self forKeyPath:@"playbackBufferFull" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:playbackBufferFull];
移除观察者:
[self.playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty" context:playbackBufferEmpty];
[self.playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp" context:playbackLikelyToKeepUpKVOToken];
[self.playerItem removeObserver:self forKeyPath:@"playbackBufferFull" context:playbackBufferFull];
【讨论】:
以上是关于AVPlayer 项目缓冲区为空的主要内容,如果未能解决你的问题,请参考以下文章
AVPlayer 在将 PlayerItem 加载到播放器之前开始缓冲它
设置 AVPlayer AVPlayerItem 缓冲区大小?