在Mac OS X 10.7 Lion上使用Core Animation进行AVFoundation问题

时间:2011-09-23 02:06:06

标签: ios cocoa core-animation avfoundation

使用Mac OS X 10.7 Apple推出了AVFoundation,我正在尝试生成一个包含动画形状的简单快速时间电影。问题是核心动画没有渲染,我最终只有一个空白的“黑色”视频。下面是我使用的代码。我尝试了很多变化但是唉它们都没有用。导出状态始终为“已完成”。

奇怪的是,UI视图包含另一个图层设置,其方式相同,但添加到AVSynchronizedLayer,它显示得很好,我可以在动画中来回擦洗。

// NOTE: composition is an AVMutableComposition containing a single video 
//       track (30s of black in 1280 x 720).

// Create the animated layer
CALayer *renderAnimLayer = [CALayer layer];
renderAnimLayer.frame = CGRectMake(0, 0, 1280, 720);

// -- EDIT: Added animated square (now animates)
renderAnimLayer.backgroundColor = CGColorCreateGenericRGB(0.3, 0.0, 0.0, 0.5);

// -- Removed
// [self setupAnimationOnLayer:renderAnimLayer];

CALayer *square = [CALayer layer];
square.backgroundColor = CGColorCreateGenericRGB(0, 0, 1, 0.8);
square.frame = CGRectMake(100, 100, 100, 100);

[CATransaction begin];
[CATransaction setDisableActions:YES];
[CATransaction setAnimationDuration:30.0];

CABasicAnimation *animation = [CABasicAnimation animation];
animation.fromValue = [NSValue valueWithPoint:square.position];
animation.toValue = [NSValue valueWithPoint:CGPointOffset(square.position, 800, 400)];
animation.removedOnCompletion = NO;
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
animation.duration = 30.0;

[CATransaction commit];

[square addAnimation:animation forKey:@"position"];
[renderAnimLayer addSublayer:square];
// -- End of Edit

// Create a composition
AVMutableVideoCompositionLayerInstruction *layerInstr1 = 
    [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstruction];
layerInstr1.trackID = 2;

AVMutableVideoCompositionInstruction *instr = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instr.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration);
instr.layerInstructions = [NSArray arrayWithObject:layerInstr1];

AVMutableVideoComposition *renderComp = [AVMutableVideoComposition videoComposition];
renderComp.renderSize    = renderAnimLayer.frame.size;
renderComp.frameDuration = CMTimeMake(1, 30); // Normally 1,30
renderComp.instructions  = [NSArray arrayWithObject:instr];
renderComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer:renderAnimLayer asTrackID:2];


// Create an export session and export
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:@"AVAssetExportPreset1280x720"];
exportSession.outputURL = [NSURL URLWithString:@"file:///Users/eric/Desktop/toto.mov"];
exportSession.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMake(30, 1));
exportSession.shouldOptimizeForNetworkUse = YES;    
exportSession.videoComposition = renderComp;

// Just see how things have finished.
[exportSession exportAsynchronouslyWithCompletionHandler:^() {
    NSLog(@"Export completed with status: %ld", exportSession.status);
}];

// TODO: remove once everything works and objects have been retained.
while (exportSession.progress < 1.0)
    usleep(200000);

找到问题的原因

感谢@ChristianK的指针。添加蓝色方形动画并看到它工作后,我不得不像ChritianK一样得出结论,我的setupAnimationOnLayer就是问题所在。起初我认为这是我设置关键帧动画的方式,但也有效。事实证明我正在使用CAShapeLayers并且根据this question CAShapeLayers在调用renderInContext时不会渲染,这就是AVExportSession在后台尝试做的事情。这也可以解释为什么在查看我的图层支持的视图设置时,我没有遇到这个问题,同时调用setupAnimationOnLayer:。

感谢你们两位的帮助。

2 个答案:

答案 0 :(得分:0)

啊,你需要使用NSView作为动画层的基础。 CALayers是非常古怪的野兽,关于它们的一个鲜为人知的事实是它们有渲染问题,有时需要将 Quicktime组件拖到浏览器框架之外才能启动。

你必须进行一些重构,但NSView绝对是一个重要的起点。祝你好运!

答案 1 :(得分:0)

部分解决方案

上面的代码现在用于导出简单的图层动画,但它不会做的是导出自定义CALayers,其内容由drawInContext:或其委托版本drawLayer:inContext:确定。 CAShapeLayer不会导出其内容,也不会导出MyCustomLayer(据我所知)。

下一步:了解如何在AVExportSession中导出自定义图层。

相关问题