0

我成功地使用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

4

2 回答 2

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

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

于 2013-05-23T20:39:29.590 回答
0

这是一个更hackier的解决方案,但它可能会有所帮助。

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

然后,当AVQueuePlayer即将前进到下一个项目时,扫过你的可删除项目列表并将它们取出。这样,blip 就会出现在项目之间的边界中,而不是在播放期间。

于 2013-05-24T19:59:41.593 回答