CoreAnimation,AVFoundation和进行视频导出的能力

时间:2011-02-17 16:32:19

标签: objective-c iphone ios4 avfoundation

我正在寻找将照片序列导出为快速视频的正确方法。

我知道AV基金会能够合并或重组视频,还可以添加构建单个视频资产的音轨。

现在......我的目标有点不同。我想从头开始创建一个视频。我有一组UIImage,我需要在一个视频中渲染所有这些。 我阅读了有关AV Foundation的所有Apple文档,我找到了AVVideoCompositionCoreAnimationTool类,它能够获取CoreAnimation并将其重新编码为视频。我还检查了Apple提供的AVEditDemo项目,但似乎有些东西在我的项目上没有用。

这是我的步骤:

1)我创建了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

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)我将视频导出到文档路径

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

在导出和导出时出现此错误:

导出完成:错误域= AVFoundationErrorDomain代码= -11822“无法打开”UserInfo = 0x49a97c0 {NSLocalizedFailureReason =不支持此媒体格式。,NSLocalizedDescription =无法打开}

我在文档中找到了它:AVErrorInvalidSourceMedia = -11822,

AVErrorInvalidSourceMedia 由于无法读取某些源媒体,因此无法完成操作。

我完全相信我构建的CoreAnimation是正确的,因为我将它渲染到测试层中,我可以正确地看到动画进度。

任何人都可以帮我理解我的错误在哪里?

2 个答案:

答案 0 :(得分:4)

  

我找到了AVVideoCompositionCoreAnimationTool类,它能够获取CoreAnimation并将其重新编码为视频

我的理解是,这只能采用CoreAnimation并将其添加到现有视频中。我刚检查了文档,唯一可用的方法也需要视频层。

编辑:是的。挖掘文档和WWDC视频,我认为您应该使用AVAssetWriter,并将图像附加到作者。类似的东西:

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:somePath] fileType:AVFileTypeQuickTimeMovie error:&error];

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:320], AVVideoWidthKey, [NSNumber numberWithInt:480], AVVideoHeightKey, nil];
AVAssetWriterInput* writerInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain];

[videoWriter addInput:writerInput];

[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:CMTimeMakeWithSeconds(0, 30)]
[writerInput appendSampleBuffer:sampleBuffer];
[writerInput markAsFinished];
[videoWriter endSessionAtSourceTime:CMTimeMakeWithSeconds(60, 30)];
[videoWriter finishWriting];

答案 1 :(得分:4)

也许你需要一个假影片,其中包含完全黑框以填充视频图层,然后添加一个CALayer来操纵图像