ios - 为什么 AVPlayer 在 'playbackBufferEmpty' 之后立即以 'playbackLikelyToKeepUp' 状态失败?

标签 ios objective-c avplayer key-value-observing

我有一个要播放的音频流,然后 KVO 观察 playbackLikelyToKeepUp 两次,然后立即停止播放观察 playbackBufferEmpty 两次。 首先,我不明白为什么应该为每条消息调用两次 observeValueForKeyPath。其次,playbackLikelyToKeepUp 的存在应该表明 playbackBufferEmpty 不应该发生。

我应该注意到这是在模拟器和设备中发生的。

- (void)setRetryConnectionTimer:(NSTimer *)newTimer
{
    if (_retryConnectionTimer) { // Take care of releasing old Timers here to make things easy.
        NSLog(@"[Timer Setter] Timer Exists. Invalidating and releasing.");
        [_retryConnectionTimer invalidate];
        [_retryConnectionTimer release];
        _retryConnectionTimer = nil;
    }
    _retryConnectionTimer = [newTimer retain];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {
    if (object == self.audioStream && [keyPath isEqualToString:@"status"]) 
    {
        if(self.audioStream.status == AVPlayerStatusReadyToPlay)
        {
            //AVPlayer ready. Kill retry timer.
            if(self.retryConnectionTimer){
                if([self.retryConnectionTimer isValid]){
                    NSLog(@"Timer is valid. invalidating and setting to nil.");
                    [self.retryConnectionTimer invalidate];
                    self.retryConnectionTimer = nil;
                }
            }
            NSLog(@"Buffering..."); // Allow the buffer to fill some by delaying play message.
            [self.audioPlayer performSelector:@selector(play) withObject:nil afterDelay:kBufferSize];
        }
    }
    if ([keyPath isEqualToString:@"playbackBufferEmpty"]){
        NSLog(@"BUFFER EMPTY!!!"); // Buffer empty.... why when playbackShouldKeep up was just sent milliseconds ago.
        _retries = 0;
        [self.audioPlayer pause];
        self.retryConnectionTimer = [NSTimer scheduledTimerWithTimeInterval:20.0f
                                                         target:self
                                                       selector:@selector(tryReconnect:)
                                                       userInfo:nil
                                                        repeats:YES];
    }
    if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){
        NSLog(@"playbackLikelyToKeepUp");
    }
}
- (void)tryReconnect:(NSTimer *)sender {
    NSLog(@"tryReconnect Called. Retry: %i", _retries);
    if (_retries <= kReconnectRetries) {
        [self restartStream];
        _retries ++;
    } else {
        NSLog(@"Connection Dropped: invalidating Timer.");
        [self.retryConnectionTimer invalidate];
        self.retryConnectionTimer = nil;
        _retries = 0;
    }
}

- (void)restartStream
{
    [self.audioStream removeObserver:self forKeyPath:@"status"];
    [self.audioStream removeObserver:self forKeyPath:@"playbackBufferEmpty"];
    [self.audioStream removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    self.audioStream = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://myaudiostream.com:9094"]];
    [self.audioStream addObserver:self forKeyPath:@"status" options:0 context:nil];
    [self.audioStream addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    [self.audioStream addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    NSLog(@"Playing audioPlayer with new AVPlayerItem");
    self.audioPlayer = [AVPlayer playerWithPlayerItem:self.audioStream];
}

来自日志。

2014-01-04 13:32:48.121 Audio Test [833:70b] Playing audioPlayer with new AVPlayerItem
2014-01-04 13:32:55.749 Audio Test [833:70b] Buffering... 
2014-01-04 13:32:55.752 Audio Test [833:70b] playbackLikelyToKeepUp
2014-01-04 13:36:00.266 Audio Test [833:70b] playbackLikelyToKeepUp
2014-01-04 13:36:00.267 Audio Test [833:70b] BUFFER EMPTY!!!
2014-01-04 13:36:00.267 Audio Test [833:70b] Creating new timer and assigning to self.retryConnectionTimer
2014-01-04 13:36:03.701 Audio Test [833:70b] BUFFER EMPTY!!!
2014-01-04 13:36:03.702 Audio Test [833:70b] Creating new timer and assigning to self.retryConnectionTimer
2014-01-04 13:36:03.702 Audio Test [833:70b] [Timer Setter] Timer Exists. Invalidating and releasing.
2014-01-04 13:36:07.171 Audio Test [833:70b] playbackLikelyToKeepUp
2014-01-04 13:36:23.697 Audio Test [833:70b] tryReconnect Called. Retry: 0
2014-01-04 13:36:23.698 Audio Test [833:70b] Playing audioPlayer with new AVPlayerItem
2014-01-04 13:36:34.002 Audio Test [833:70b] Buffering... 
2014-01-04 13:36:34.002 Audio Test [833:70b] Timer is valid. invalidating and setting to nil.
2014-01-04 13:36:34.002 Audio Test [833:70b] [Timer Setter] Timer Exists. Invalidating and releasing.

最佳答案

你真的在检查结果吗? playbackLikelyToKeepUp 是一个 BOOL,所以它很可能是 NO

关于ios - 为什么 AVPlayer 在 'playbackBufferEmpty' 之后立即以 'playbackLikelyToKeepUp' 状态失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20916743/

相关文章:

swift - 如何从 superView 中删除自定义的playerView?

ios - 更改 UINavigationBar 背景图像并使 UINavigationBar 缩放

ios - 如何将iTunesAccount帐户添加或链接到其他人的Apple Developer帐户?

android - Android 上的 iOS 自动布局约束 (greaterThanOrEquall) 等效项是什么?

iphone - 仅在 Superview 上禁用触摸事件?

iOS 7(子层)AVPlayer 全屏动画,需要在上面(覆盖)UINavigationBar

ios - 如何从 UIViewController 中抽象出交互?

ios - FBSession.activeSession.permissions 似乎没有准确描述有效的授予权限

iphone - 如何使用从 iPhone 应用程序主视图传递的搜索字符串在 subview 上调用 google 搜索

ios - RTC 报告和 pancake.apple.com 错误