CoreAnimation,AVFoundation和进行视频导出的能力 [英] CoreAnimation, AVFoundation and ability to make Video export
问题描述
我正在寻找将我的图片序列导出为快速视频的正确方法。
I'm looking for the correct way to export my pictures sequence into a quicktime video.
我知道AV Foundation有能力合并或重组视频和还要添加构建单个视频资产的音轨。
I know that AV Foundation have the ability to merge or recombine videos and also to add audio track building a single video Asset.
现在......我的目标有点不同。我想从头开始创建一个视频。我有一套UIImage,我需要在一个视频中渲染所有这些。
我阅读了有关AV Foundation的所有Apple文档,我找到了AVVideoCompositionCoreAnimationTool类,它能够获取CoreAnimation并将其重新编码为视频。我还检查了Apple提供的AVEditDemo项目,但是我的项目似乎无法正常工作。
Now ... my goal is a little bit different. I would to create a video from scratch. I have a set of UIImage and I need to render all of them in a single video. I read all the Apple Documentation about AV Foundation and i found the AVVideoCompositionCoreAnimationTool class that have the ability to take a CoreAnimation and reencode it as a video. I also checked the AVEditDemo project provided by Apple but something seems not working on my project.
这里我的步骤:
1)我创建CoreAnimation图层
1) I create the CoreAnimation Layer
CALayer *animationLayer = [CALayer layer];
[animationLayer setFrame:CGRectMake(0, 0, 1024, 768)];
CALayer *backgroundLayer = [CALayer layer];
[backgroundLayer setFrame:animationLayer.frame];
[backgroundLayer setBackgroundColor:[UIColor blackColor].CGColor];
CALayer *anImageLayer = [CALayer layer];
[anImageLayer setFrame:animationLayer.frame];
CAKeyframeAnimation *changeImageAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
[changeImageAnimation setDelegate:self];
changeImageAnimation.duration = [[albumSettings transitionTime] floatValue] * [uiImagesArray count];
changeImageAnimation.repeatCount = 1;
changeImageAnimation.values = [NSArray arrayWithArray:uiImagesArray];
changeImageAnimation.removedOnCompletion = YES;
[anImageLayer addAnimation:changeImageAnimation forKey:nil];
[animationLayer addSublayer:anImageLayer];
2)比我实例化AVComposition
2) Than I instantiate the AVComposition
AVMutableComposition *composition = [AVMutableComposition composition];
composition.naturalSize = CGSizeMake(1024, 768);
CALayer *wrapLayer = [CALayer layer];
wrapLayer.frame = CGRectMake(0, 0, 1024, 768);
CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(0, 0, 1024, 768);
[wrapLayer addSublayer:animationLayer];
[wrapLayer addSublayer:videoLayer];
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
AVMutableVideoCompositionInstruction *videoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMake([imagesFilePath count] * [[albumSettings transitionTime] intValue] * 25, 25));
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstruction];
videoCompositionInstruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:wrapLayer];
videoComposition.frameDuration = CMTimeMake(1, 25); // 25 fps
videoComposition.renderSize = CGSizeMake(1024, 768);
videoComposition.instructions = [NSArray arrayWithObject:videoCompositionInstruction];
3)我将视频导出到文档路径
3) I export the video to document path
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetLowQuality];
session.videoComposition = videoComposition;
NSString *filePath = nil;
filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
filePath = [filePath stringByAppendingPathComponent:@"Output.mov"];
session.outputURL = [NSURL fileURLWithPath:filePath];
session.outputFileType = AVFileTypeQuickTimeMovie;
[session exportAsynchronouslyWithCompletionHandler:^
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Export Finished: %@", session.error);
if (session.error) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
}
});
}];
在导出和导出时出现此错误:
At the and of the export a get this error:
导出完成:错误域= AVFoundationErrorDomain代码= -11822无法打开UserInfo = 0x49a97c0 {NSLocalizedFailureReason =不支持此媒体格式。,NSLocalizedDescription =无法打开}
Export Finished: Error Domain=AVFoundationErrorDomain Code=-11822 "Cannot Open" UserInfo=0x49a97c0 {NSLocalizedFailureReason=This media format is not supported., NSLocalizedDescription=Cannot Open}
我在文档中找到了它:AVErrorInvalidSourceMedia = -11822,
I found it inside documentation: AVErrorInvalidSourceMedia = -11822,
AVErrorInvalidSourceMedia
由于无法读取某些源媒体,因此无法完成操作。
AVErrorInvalidSourceMedia The operation could not be completed because some source media could not be read.
我完全相信我构建的CoreAnimation是正确的,因为我将它渲染到测试层中,我可以正确地看到动画进展。
I'm totally sure that the CoreAnimation build by me is right because I rendered it into a test layer and i could see the animation progress correctly.
任何人都可以帮我理解我的错误在哪里?
Anyone can help me to understand where is my error?
推荐答案
也许你需要一个假电影,包含完全黑色的框架,以填充视频图层,然后添加CALayer来manpiulate图像
maybe you need a fake movie that contains totally black frame to fill the video layer, and then add a CALayer to manpiulate the images
这篇关于CoreAnimation,AVFoundation和进行视频导出的能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!