首页 文章

AVPlayer replaceCurrentItemWithPlayerItem无法在iOS 4.3.3上运行

提问于
浏览
15

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

目前,我保持 player 实例,当我需要交换曲目时(从手动选择或曲目到达结束)我创建一个新的 AVPlayerItem 并用新项目调用 replaceCurrentItemWithPlayerItem .

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

这是相关代码:

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

这里是关键值观察回调:

- (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上,此属性包含实际值 . 永远不会再调用此方法 . 所以从本质上讲,替换似乎总是失败 .

这似乎是一个错误,但也许我做错了什么 .

2 回答

  • 17

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

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

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

    致积于:Apple Developer Forums

  • 1

    我一直遇到类似的问题 . 你可能像我一样从_2918229开始 . 也许 currentItemnil 的问题是因为它's not loaded yet or ready for playback (my problem was I couldn' t得到了新的 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,所以我想我很快就会遇到并发症 .

相关问题