AVPlayer replaceCurrentItemWithPlayerItem无法在iOS 4.3.3+上运行

时间:2011-09-14 17:03:48

标签: objective-c ios avplayer

我有一个使用AVPlayer构建的音频播放器。

目前,我保留player实例,当我需要交换曲目时(从手动选择或曲目到达结束)我创建了一个新的AVPlayerItem并且我调用{{ 1}}使用新项目。

根据文档,replaceCurrentItemWithPlayerItem是一个异步操作,所以我也观察了播放器的 currentItem 键路径。当它被调用时,我告诉我的玩家玩。

以下是相关代码:

replaceCurrentItemWithPlayerItem

这是关键值观察回调:

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerItemStatusChangedContext];

if (!_player) {
    _player = [[AVPlayer alloc] initWithPlayerItem:playerItem]; 
    [_player addObserver:self forKeyPath:@"status"          options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerStatusChangedContext];
    [_player addObserver:self forKeyPath:@"currentItem"     options:NSKeyValueObservingOptionNew context:CHStreamingAudioPlayer_PlayerCurrentItemChangedContext];
} else {
    [_player replaceCurrentItemWithPlayerItem:playerItem];
}

在iOS 4.3.3(和iOS 5)上调用我的关键观察方法,但- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == CHStreamingAudioPlayer_PlayerCurrentItemChangedContext) { NSLog(@"Player's current item changed! Change dictionary: %@", change); if (_player.currentItem) { [self play]; //<---- doesn't get called } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } 始终为_player.currentItem。在4.2.1和4.3.2上,此属性包含实际值。永远不会再调用此方法。所以从本质上讲,替换似乎总是失败。

这似乎是一个错误,但也许我做错了。

2 个答案:

答案 0 :(得分:17)

iOS 5(包括5.0.1)存在此问题。它曾经在iOS 4.x上正常工作。

有两种方法可以解决此问题,每次需要交换曲目时,都会使用所需的AVPlayer释放并重新创建AVPlayerItem。或者,只需在主线程上调用replaceCurrentItemWithPlayerItem:即可。

我尝试了两种选择,但它们运行良好。

致记:Apple Developer Forums

答案 1 :(得分:1)

我一直遇到类似的问题。你可能从像我这样的AVPlayerDemoPlaybackViewController from Apple sample code开始。也许currentItemnil的问题是因为它尚未加载或已准备好播放(我的问题是我无法获得新AVPlayerItem的持续时间。)

currentItem的观察状态为ReadyToPlay时,您可以尝试开始播放。

AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
    switch (status) {
        case AVPlayerStatusUnknown: {
            NSLog(@"PLAYER StatusUnknown");
        }
            break;
        case AVPlayerStatusReadyToPlay: {
            NSLog(@"PLAYER ReadyToPlay");
            [self play];
        }
            break;
        case AVPlayerStatusFailed: {
            AVPlayerItem *playerItem = (AVPlayerItem *)object;
            [self handleError: [playerItem.error localizedDescription]];
        }
            break;
    }

我不知道这是否适合你,我没有尝试过低于或高于4.3.4的iPad,所以我想我很快就会遇到并发症。