从队列中删除项目时,AVQueuePlayer播放会冻结

时间:2013-05-20 16:48:42

标签: cocoa-touch avplayer avqueueplayer

我成功使用AVQueuePlayer排队并播放AVPlayerItems。但是,当我通过调用removeItem:方法更改玩家队列时,问题就开始了。我的假设是,只要我不触摸当前播放的项目,我就可以自由修改此队列,但似乎每次调用removeItem:都会暂停播放。

请考虑以下代码段:

+ (void)setBranch:(BranchType)bType {
    NSArray* items = [dynamicMusicPlayer items];
    for (AVPlayerItem* item in [items copy]) {
        if (item == dynamicMusicPlayer.currentItem) {
            continue; // don't remove the currently played item
        }
        [dynamicMusicPlayer removeItem:item];
    }
    [self queueNextBlockFromBranchType:bType];
    currentBranch = bType;
}

你可以从中猜出,它是一个动态的音乐播放器,播放来自不同分支的音乐。所以基本上,当我评论删除项目的行时,它会播放一切正常,但显然分支不会在我想要的时候立即更改。冻结恰好在删除发生时发生,因此当前播放的项目正在被中断,但实际项目之间的转换是无缝的。另请注意,队列中的项目从不超过2个,因此在循环中我基本上只删除了一个项目。

所以,我的问题是:有没有办法避免这种冻结?是什么导致了冻结的第一个位置?

编辑因此,对于遇到相同问题的人,我的解决方案是停止使用AVFoundation并改为使用OrigamiEngine

2 个答案:

答案 0 :(得分:0)

您可以考虑安排NSOperation稍后执行此操作,而不是删除循环中的项目。

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // do something here
}];

例如:

+ (void)setBranch:(BranchType)bType {
    NSArray* items = [dynamicMusicPlayer items];
    for (AVPlayerItem* item in [items copy]) {
        if (item == dynamicMusicPlayer.currentItem) {
            continue; // don't remove the currently played item
        }
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [dynamicMusicPlayer removeItem:item];
        }];
    }
    [self queueNextBlockFromBranchType:bType];
    currentBranch = bType;
}

我不知道这是否会有所帮助,但它至少会将实际的项目移除转移到设备可以决定何时运行的预定操作。

答案 1 :(得分:0)

这是一个非常黑客的解决方案,但它可能有所帮助。

您可以将其添加到要删除的单独维护列表中,而不是立即从dynamicMusicPlayer删除该项,您可以将其标记为删除。

然后,当AVQueuePlayer即将前进到下一个项目时,浏览可删除项目列表并将其删除。这样,blip发生在项目之间的边界而不是回放期间。