AVFoundation Tutorial: Adding Overlays and Animations to Videos

AVFoundation is the framework in iOS that lets you perform video editing. Add overlays and animations to your videos in this AVFoundation tutorial! By .

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Roger Rabbit, Eat Your Heart Out — Add Animation to Videos

Here’s the most awesome part of this AVFoundation tutorial — adding running animations on top of your videos!

An animation layer is just a plain old CALayer object, and you can add any sort of CAAnimation sequence to it. Your final lesson in this tutorial will add a couple of stars to your video…much like the star that awaits you on Hollywood Boulevard :]

A sample star.png image is included in the starter project for you to use, and you’ll apply fading, rotating, and twinkling effects to the video using this image.

To add animation to your video, you will use almost the same concepts you used to add overlays, with the addition of using CABasicAnimation sequences. You’ll assign these sequences to the overlay layer before you superimpose it on your video layer.

Okay, by now you can probably recite the next steps in your sleep :]

Open AddAnimationViewController.m and add the code below to the empty implementation of applyVideoEffectsToComposition:size::

  // 1
  UIImage *animationImage = [UIImage imageNamed:@"star.png"];;
  CALayer *overlayLayer1 = [CALayer layer];
  [overlayLayer1 setContents:(id)[animationImage CGImage]];
  overlayLayer1.frame = CGRectMake(size.width/2-64, size.height/2 + 200, 128, 128);
  [overlayLayer1 setMasksToBounds:YES];

  CALayer *overlayLayer2 = [CALayer layer];
  [overlayLayer2 setContents:(id)[animationImage CGImage]];
  overlayLayer2.frame = CGRectMake(size.width/2-64, size.height/2 - 200, 128, 128);
  [overlayLayer2 setMasksToBounds:YES];

  // 2 - Rotate
  if (_animationSelectSegment.selectedSegmentIndex == 0) {
    CABasicAnimation *animation =
    [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    animation.duration=2.0;
    animation.repeatCount=5;
    animation.autoreverses=YES;
    // rotate from 0 to 360
    animation.fromValue=[NSNumber numberWithFloat:0.0];
    animation.toValue=[NSNumber numberWithFloat:(2.0 * M_PI)];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer1 addAnimation:animation forKey:@"rotation"];

    animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    animation.duration=2.0;
    animation.repeatCount=5;
    animation.autoreverses=YES;
    // rotate from 0 to 360
    animation.fromValue=[NSNumber numberWithFloat:0.0];
    animation.toValue=[NSNumber numberWithFloat:(2.0 * M_PI)];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer2 addAnimation:animation forKey:@"rotation"];

  // 3 - Fade
  } else if(_animationSelectSegment.selectedSegmentIndex == 1) {
    CABasicAnimation *animation
    =[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.duration=3.0;
    animation.repeatCount=5;
    animation.autoreverses=YES;
    // animate from fully visible to invisible
    animation.fromValue=[NSNumber numberWithFloat:1.0];
    animation.toValue=[NSNumber numberWithFloat:0.0];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer1 addAnimation:animation forKey:@"animateOpacity"];

    animation=[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.duration=3.0;
    animation.repeatCount=5;
    animation.autoreverses=YES;
    // animate from invisible to fully visible
    animation.fromValue=[NSNumber numberWithFloat:1.0];
    animation.toValue=[NSNumber numberWithFloat:0.0];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer2 addAnimation:animation forKey:@"animateOpacity"];

  // 4 - Twinkle
  } else if(_animationSelectSegment.selectedSegmentIndex == 2) {
    CABasicAnimation *animation =
    [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation.duration=0.5;
    animation.repeatCount=10;
    animation.autoreverses=YES;
    // animate from half size to full size
    animation.fromValue=[NSNumber numberWithFloat:0.5];
    animation.toValue=[NSNumber numberWithFloat:1.0];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer1 addAnimation:animation forKey:@"scale"];

    animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation.duration=1.0;
    animation.repeatCount=5;
    animation.autoreverses=YES;
    // animate from half size to full size
    animation.fromValue=[NSNumber numberWithFloat:0.5];
    animation.toValue=[NSNumber numberWithFloat:1.0];
    animation.beginTime = AVCoreAnimationBeginTimeAtZero;
    [overlayLayer2 addAnimation:animation forKey:@"scale"];
  }

  // 5
  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:overlayLayer1];
  [parentLayer addSublayer:overlayLayer2];

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

Yes, that code block is significantly longer than the others :] Take some time to read through the breakdown below, in order to understand just what’s going on:

  1. There are two overlay layers, each with a star image. These layers will be manipulated in different ways depending on the selected effect.
  2. The rotate effect will put rotating stars on top of the video. The animations are set with a duration of 2 seconds and from/to values of 0.0 to 2*M_PI (i.e. 0 to 360 degrees – a full circle).
  3. The fade effect will fade the two star overlays in and out. The opacity is animated from fully visible (opacity=1.0) to invisible (opacity=0.0).
  4. The twinkle effect will animate the stars by changing their scale factor. The scale value changes from half-size (0.5) to full-size (1.0) which creates the twinkle effect.
  5. This part’s the usual: set up the parent layer, the video layer, and the two overlay layers, then finally process it all via AVVideoCompositionCoreAnimationTool

That’s it — build and run to see your latest and greatest effect at work!

Choose “Add Animation to video”, and go through the usual steps of selecting a video and generating the output. Once the video has been saved to the photo library, you should be able to view it and see an animation running on top of your video like in the screens below:

Okay, admittedly the static image above doesn’t do full justice to the effect — but an amazing video editor like yourself can always visualize these things, right? :]

Where to Go From Here?

Here is the final project with all of the code from the above AVFoundation tutorial.

At this point, you should have a pretty good understanding of how to use AVVideoCompositionCoreAnimationTool to add cool effects to your own videos. And you should be able to take the basic principles from this tutorial and expand upon them to add many cool and interesting effects to your own videos.

Here are some more video-wrangling suggestions to try out in your app:

  • Create an app to add watermarks to videos.
  • Add snow or rain effects to a video.
  • Use CATransform3D to scale, skew, and otherwise warp a video.

Please let us know in the comments if this tutorial helped you to creating any great iOS apps, or if you were able to create some other amazing effect with help of this tutorial!

If you have any questions, comments, or suggestions for this tutorial, please join the discussion on our forums!