简体   繁体   English

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

[英]AVFoundation Issue With Core Animation on Mac OS X 10.7 Lion

With Mac OS X 10.7 Apple has introduced AVFoundation and I'm trying to generate a simple quick time movie containing an animated shape. 在Mac OS X 10.7中,Apple推出了AVFoundation,我正在尝试生成一个包含动画形状的简单快速时间电影。 The problem is that the core animation does not render and I end-up having only a blank "black" video. 问题是核心动画没有渲染,我最终只有一个空白的“黑色”视频。 Below is the code that I used. 下面是我使用的代码。 I've tried many variations but alas none of them work. 我尝试了很多变化但是唉它们都没有用。 The export status is always "Completed". 导出状态始终为“已完成”。

The odd thing is that the UI view contains another layer setup with the same way but added to an AVSynchronizedLayer and it displays just fine and I'm able to scrub back and forth in the animation. 奇怪的是,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);

Found Cause of the Issue 找到问题的原因

Thanks to @ChristianK for the pointer. 感谢@ChristianK的指针。 After adding the blue square animation and seeing it work I had to conclude, like ChritianK, that my setupAnimationOnLayer was the issue. 添加蓝色方形动画并看到它工作后,我不得不像ChritianK一样得出结论,我的setupAnimationOnLayer就是问题所在。 At first I thought it was the way I setup key frame animation but that also worked. 起初我认为这是我设置关键帧动画的方式,但也有效。 It turns out that I was using CAShapeLayers and as per this question CAShapeLayers don't render when renderInContext is called, which is what AVExportSession is trying to do in the background I suppose. 事实证明我正在使用CAShapeLayers并且根据这个问题 ,CAShapeLayers在调用renderInContext时不会渲染,这就是AVExportSession在后台尝试做的事情。 This would also explain why I don't have that issue when looking at my layer backed view setup with the same call to setupAnimationOnLayer:. 这也可以解释为什么在查看我的图层备份视图设置时,我没有遇到这个问题,同时调用setupAnimationOnLayer:

Thanks to both of you for your help. 感谢你们两位的帮助。

Ahhh, you need to use NSView as the basis for your animation layer. 啊,你需要使用NSView作为动画层的基础。 CALayers are very quirky beasts, and a lesser-known fact about them is that they have rendering issues that sometime require that the Quicktime component be dragged outside the browser frame before it will initiate. CALayers是非常古怪的野兽,关于它们的一个鲜为人知的事实是它们有渲染问题,有时需要将Quicktime组件拖到浏览器框架之外才能启动。

You will have to do some refactoring, but NSView is absolutely the place to start. 你将不得不做一些重构,但NSView绝对是一个开始的地方。 Good luck! 祝好运!

Partial Solution 部分解决方案

The above code now works to export simple layer animations but what it won't do is export custom CALayers the contents of which is determined by drawInContext: or its delegate version drawLayer:inContext:. 上面的代码现在可以导出简单的图层动画,但它不会做的是导出自定义CALayers,其内容由drawInContext:或其委托版本drawLayer:inContext:确定。 CAShapeLayer won't export its content and neither will a MyCustomLayer (as far as I could see). CAShapeLayer不会导出其内容,也不会导出MyCustomLayer(据我所知)。

Next step: discover how to export custom layers in an AVExportSession. 下一步:了解如何在AVExportSession中导出自定义图层。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM