AVPlayer项目缓冲区为空。

6

我使用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)
    {
        ...
    }
 }
}

请帮助我找到正确的方法来获取“缓冲区空”和“缓冲区就绪”事件(例如,当网络连接断开时)。谢谢!
2个回答

2
你在添加观察者时需要使用上下文。以下是一个样例代码。
初始化上下文。
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];
}

0
@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];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接