我有一个 AVComposition 和一个 AVVideoComposition,我为视频的每半秒左右生成拇指。我将动画工具用于一些叠加层。我在操作队列上执行调用,并在某些类型的编辑后触发。操作队列是串行的而不是异步的,所以进程永远不会并发运行,我已经验证了这一点。下面的代码在串行队列中另一个 NSOperation 的主线程上执行。
现在我的问题是,拇指随机失败,没有模式。我可以运行一次并让它全部成功。我可以使用完全相同的参数再次运行它,并且有些拇指失败了。我可以再次运行它并且有不同的拇指失败。
它似乎与其他线程中正在进行的其他活动有多少有关,例如从 ALAssetLibrary 或 MediaFramework 查询很多项目。
我还将提到这在 iOS6 中有效,没有这个问题。
在生成拇指之前,我确实创建了 AVComposition 和 AVVideoComposition 的副本。
有人对我有任何指示吗?
我很感激。
//this must be called on the main thread to correctly generate overlays
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
AVAsset *asset = avComposition;
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = TRUE;
AVMutableVideoComposition *mutableVideoComposition = (AVMutableVideoComposition *) avVideoComposition.mutableCopy;
CALayer *baseSyncLayer = [CALayer layer];
baseSyncLayer.frame = CGRectMake(0, 0, resolution.width, resolution.height);
CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(0, 0, resolution.width, resolution.height);
[baseSyncLayer addSublayer:videoLayer];
__unused NSArray *imageLayers = [MovieCompositionService applyImageAnimations:avComposition andLayer:baseSyncLayer andProject:project fileRender:YES addTextOverlays:addTextOverlays andResolution:resolution];
mutableVideoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:baseSyncLayer];
generator.videoComposition = mutableVideoComposition;
NSMutableArray *images = [[NSMutableArray alloc] init];
__block BOOL hasErrors = NO;
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
if (!hasErrors) {
DDLogVerbose(@"ACTUAL GENERATION TIME %f", CMTimeGetSeconds(actualTime));
if (result != AVAssetImageGeneratorSucceeded) {
DDLogError(@"Failed to generate thumb: %@", error.localizedDescription);
hasErrors = YES;
[generator cancelAllCGImageGeneration];
finishBlock(images, YES);
} else {
[images addObject:[UIImage imageWithCGImage:im]];
if (CMTIME_COMPARE_INLINE(requestedTime, ==, ((NSValue *) timeIntervals.lastObject).CMTimeValue)) {
DDLogVerbose(@"Movie composition thumb generation complete");
finishBlock(images, NO);
}
}
}
};
generator.maximumSize = thumbSize;
[generator generateCGImagesAsynchronouslyForTimes:timeIntervals completionHandler:handler];
}];