11

AVQueuePlayer用来播放从 URL 加载的一系列电影。
我试图用AVPlayerItems我需要玩的所有东西的数组来初始化播放器实例。

player = [[AVQueuePlayer queuePlayerWithItems:playerItemsArray]

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

有可能只将 first 添加AVPLayerItem到播放器的队列中,观察其状态并仅在 first 到达结束时将第二个项目添加到队列中,但在这种情况下,由于 second 的初始化和缓冲而导致两个项目的播放之间存在间隙AVPlayerItem

有什么方法可以在不冻结的情况下组织多个视频的无缝播放?
我应该为此目的使用其他播放器吗?

提前致谢。

4

3 回答 3

17

找到了解决方案。

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 的这个解决方案队列可以填充没有任何间隙和冻结的项目。

于 2013-03-04T13:16:44.923 回答
2

在 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)
}
于 2016-01-20T10:50:49.520 回答
-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;
}
于 2013-11-24T11:08:36.453 回答