AVQueuePlayer无间隙播放和冻结

时间:2013-02-18 17:00:56

标签: ios objective-c avfoundation avqueueplayer

我使用AVQueuePlayer播放从网址加载的一系列电影 我尝试使用我需要播放的所有AVPlayerItems数组来初始化播放器实例。

player = [[AVQueuePlayer queuePlayerWithItems:playerItemsArray]

但在这种情况下,AVQueuePlayer会在开始播放之前加载每个AVPlayerItem的一些初始部分。它导致令人沮丧的冻结,应用程序几秒钟内没有响应。

有可能只将第一个AVPLayerItem添加到玩家的队列中,观察其状态并仅在第一个到达结束时在队列中添加第二个项目,但在这种情况下,两个项目的回放之间会有间隙通过初始化和缓冲第二个AVPlayerItem

有没有办法在没有冻结的情况下组织几个视频的无间隙播放? 我应该为此目的使用其他玩家吗?

提前致谢。

3 个答案:

答案 0 :(得分:16)

找到解决方案。

AVPlayerItem队列中添加新的AVQueuePlayer时,播放器会同步等待播放器项目的初始部分被缓冲。

因此,在这种情况下,播放器项应该异步缓冲,之后可以添加到队列中。
可以使用[AVURLAsset loadValuesAsynchronouslyForKeys: completionHandler:]

完成

例如:

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *keys = [NSArray arrayWithObject:@"playable"];

[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^()
{
    dispatch_async(dispatch_get_main_queue(), ^
    {
        AVPlayerItem *playerItem = [[[AVPlayerItem alloc] initWithAsset:asset] autorelease];         
        [player insertItem:playerItem afterItem:nil]; 
    });

}];

使用AVQueuePlayer的此解决方案队列可以填充没有任何间隙和冻结的项目。

答案 1 :(得分:1)

在Swift 2中,在这里工作:

func load() {
     let player = AVQueuePlayer()
     for url in urls {
        makeItem(url)
    }
}

func makeItem(url: String) {
    let avAsset = AVURLAsset(URL: NSURL(string: url)!)

    avAsset.loadValuesAsynchronouslyForKeys(["playable", "tracks", "duration"], completionHandler: {
        dispatch_async(dispatch_get_main_queue(), {
            self.enqueue(avAsset: avAsset)
        })
    })
}

func enqueue(avAsset: AVURLAsset) {
    let item = AVPlayerItem(asset: avAsset)
    self.player.insertItem(item, afterItem: nil)
}

答案 2 :(得分:-1)

这是解决方案。

- (void)_makePlayer{
     _player = [[AVQueuePlayer alloc] initWithPlayerItem:[AVPlayerItem playerItemWithAsset:[SSMoviePreviewItemMaker generateAVMovieItem]]];
}

+ (AVAsset *)generateAVMovieItem{
    NSArray * array = [SSMovieFileManager getAllMovieResourceURL];
    AVMutableComposition *composition = [[AVMutableComposition alloc] init];
    for (int i = 0; i < array.count; i++) {
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:array[i] options:nil];
        [composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration)
                             ofAsset:asset
                              atTime:composition.duration error:nil];

    }
   return composition;
}