AVPlayer replaceCurrentItemWithPlayerItem不适用于iOS 4.3.3+

我有一个使用AVPlayer构build的audio播放器。

目前,我保持player实例,当我需要交换轨道(无论是从手动select或轨道已达到结束),我创build一个新的AVPlayerItem和我调用replaceCurrentItemWithPlayerItem与新项目。

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

这是相关的代码:

 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]; } 

这里是关键值观察callback:

 - (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]; } } 

在iOS 4.3.3(和iOS 5)上,我的关键观察方法被调用,但_player.currentItem总是nil 。 在4.2.1和4.3.2上,这个属性包含了实际值。 这个方法不会再被调用。 所以实质上,替代似乎总是失败。

这看起来像一个错误,但也许我做错了什么。

我有iOS 5(包括5.0.1)这个问题。 它曾经在iOS 4.x上正常工作。

有两种方法可以解决这个问题,每次需要交换音轨时,都可以使用所需的AVPlayerItem发布和重新创buildAVPlayer 。 或者,只需在主线程上调用replaceCurrentItemWithPlayerItem:即可。

我尝试了两个选项,他们工作得很好。

致谢: 苹果开发者论坛

我一直在遇到类似的问题。 您可能已经从像我这样的Apple示例代码的AVPlayerDemoPlaybackViewController开始。 也许问题是为什么currentItem nil是因为它尚未加载或准备播放(我的问题是我无法获得新的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,所以我想很快就会遇到麻烦。