Search code examples
objective-ciphonexcodeavfoundationavmutablecomposition

AVVideoCompositionCoreAnimationTool making first frame black


when using AVVideoCompositionCoreAnimationTool to add a text overlay to one of my videos, the first frame is a black one most of the times. When I comment out the all of the code belonging to the animation tool and its setup, everything is working as expected, the first frame is never black. Hence I'm starting to think that my AVMutableComposition used to compose the finished video is indeed working as expected and configured correctly. The following code is used to setup the text layer:

CALayer* layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 480, 480);
layer.opacity = 0.0f;

CATextLayer* textLayer = [[CATextLayer alloc] init];
textLayer.frame = CGRectMake(0, 0, 450, 80);
[textLayer setString:@"mytext"];
textLayer.foregroundColor = [UIColor whiteColor].CGColor;
textLayer.alignmentMode = kCAAlignmentRight;
[textLayer setFont:CTFontCreateWithName((__bridge CFStringRef)@"HelveticaNeue", 18, &CGAffineTransformIdentity)];
[layer addSublayer:textLayer];

CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];

parentLayer.bounds = CGRectMake(0, 0, 480, 480);
parentLayer.anchorPoint =  CGPointMake(0, 0);
parentLayer.position = CGPointMake(0, 0);

videoLayer.bounds = CGRectMake(0, 0, 480, 480);
[parentLayer addSublayer:videoLayer];
videoLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds), CGRectGetMidY(parentLayer.bounds));

textLayer.position = CGPointMake(CGRectGetMidX(layer.bounds), 20);

[parentLayer addSublayer:layer];
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

Any ideas on how to fix this issue?


Solution

  • For anyone in the future, here is what I did: Apparently the AVVideoCompositionCoreAnimationTool doesn't play nice with AVMutableVideoCompositions. Therefore I first exported video and audio using an AVAssetExportSession but without my CALayer and afterwards added the overlay layer in a second pass. I know this is probably not a "good" solution and requires a little bit more processing but in the end it worked out.