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

随着Mac OS X 10.7苹果已经推出了AVFoundation,我试图生成一个简单的快速时间电影包含animation形状。 问题是,核心animation不渲染,我最终只有一个空白的“黑”video。 以下是我使用的代码。 我已经尝试了许多变化,但唉,他们都没有工作。 导出状态始终为“已完成”。

奇怪的是,用户界面视图包含另一个图层设置,但添加到AVSynchronizedLayer,它显示得很好,我可以在animation中来回擦洗。

// 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的指针。 在添加蓝色方形animation并看到它的工作后,我不得不像ChritianK那样得出结论,我的setupAnimationOnLayer是问题所在。 起初我以为这是我设置关键帧animation的方式,但也有效。 事实certificate,我正在使用CAShapeLayers,并根据这个问题 CAShapeLayers不呈现renderInContext被调用时,这是什么AVExportSession试图在后台做我想。 这也可以解释为什么我看到我的层支持的视图设置与setupAnimationOnLayer相同的调用时没有这个问题:

感谢你们两位的帮助。

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

你将不得不做一些重构,但NSView绝对是开始的地方。 祝你好运!

部分解决scheme

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

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