0

I'm trying to add an overlay to my video which contains a sublayer that has the content changed over time. So I'm adding CAKeyframeAnimation to the layer as follows:

CALayer *overlayLayer = [CALayer layer];
[overlayLayer setFrame:CGRectMake(0, 0, size.width, size.height)];
[overlayLayer setMasksToBounds:YES];

NSArray *frames = [self.gifImage frames];

CALayer *aLayer = [CALayer layer];
UIImage *firstImage = [frames objectAtIndex:0];
CGFloat nativeWidth = CGImageGetWidth(firstImage.CGImage);
CGFloat nativeHeight = CGImageGetHeight(firstImage.CGImage);
CGRect frame = CGRectMake(0.0, 0.0, nativeWidth, nativeHeight);
aLayer.frame = frame;
aLayer.contents = (id)firstImage.CGImage;
[aLayer setMasksToBounds:YES];

CAKeyframeAnimation *animationSequence = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animationSequence.calculationMode = kCAAnimationDiscrete;
animationSequence.duration = [self.gifImage totalDuration];
animationSequence.repeatCount = HUGE_VALF;

NSMutableArray *animationSequenceArray = [[NSMutableArray alloc] init];
for (UIImage *image in frames) {
    [animationSequenceArray addObject:(id)image.CGImage];
}

animationSequence.values = animationSequenceArray;
[aLayer addAnimation:animationSequence forKey:@"contents"];
[overlayLayer addSublayer:aLayer];

CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer];

composition.animationTool = [AVVideoCompositionCoreAnimationTool
                             videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

Somehow when I add aLayer as a sublayer of my view, it animates properly. But When I add it to the overlay of the video, the animation doesn't work. Is there something I'm missing here? Any help is appreciated.

huong
  • 4,534
  • 6
  • 33
  • 54
  • To add animation to a video, use AVVideoCompositionCoreAnimationTool - https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVVideoCompositionCoreAnimationTool_Class/index.html#//apple_ref/swift/cl/AVVideoCompositionCoreAnimationTool – matt Jan 01 '15 at 19:28
  • @matt I'm actually using it (if you notice that last line) – huong Jan 02 '15 at 04:48

2 Answers2

1

If you use kCAAnimationDiscrete, here's a checklist:

  • keyTimes needs a value from 0-1, not a time
  • keyTimes must start at 0.0 and end with value 1.0
  • keyTimes must have one more value than your animation frames count
MikeNatty
  • 147
  • 1
  • 5
0

I've finally managed to fix this issue by changing calculationMode to kCAAnimationLinear. This seems to be a silly issue, but I hope it may be useful for someone.

huong
  • 4,534
  • 6
  • 33
  • 54
  • Hi @friedegg-bacon-sandwich, can you share some more details? I'm trying to do the same but can't get the sprite animation on the video. If I use a CABasicAnimation to animate opacity it works just fine and I can get a dummy layer with a fade in / out animation on the video. But when trying to add an animated sprite by using CAKeyframeAnimation just like you do, I get nothing. – irodrigo17 Jan 27 '16 at 14:41