AVFoundation Tutorial: Adding Overlays and Animations to Videos

Abdul Azeem Khan
How to Add Borders,Overlays and Animations To Videos in iOS<br />

How to Add Borders,Overlays and Animations To Videos in iOS

The preceding AVFoundation tutorial in this series, How to Play, Record, and Edit Videos in iOS received some great response from readers. In fact, most readers wanted even more tips on advanced editing features that could add that extra touch of polish to their videos.

This follow-up AVFoundation tutorial is full of fresh new tricks to add some cool and professional effects to your videos.

The first AVFoundation tutorial showed you how to:

  • Select and play a video from the media library.
  • Record and save a video to the media library.
  • Merge multiple videos together into a combined video, complete with a custom soundtrack!

This new AVFoundation tutorial will build upon that by teaching all you budding video editors how to add the following effects to your videos:

  • Colored borders with custom sizes.
  • Multiple overlays.
  • Text for subtitles or captions.
  • Tilt effects.
  • Twinkle, rotate, and fade animation effects!

To get the most out of this tutorial, you will need to have some knowledge of the AVFoundation video rendering concepts described in the previous tutorial such as AVAsset and AVComposition. If you need to brush up on these topics, check out the previous tutorial before continuing. You could also refer to the Apple documentation for even more detailed information on the subject.

Ready? Lights, Camera… Action! :]

Getting Started

Start by downloading the starter project for this tutorial which includes all the stuff that was covered in How to Play, Record, and Edit Videos in iOS.

Note: If you run this project on the simulator, you’ll have no way to capture video. Plus, you’ll need to figure out a way to add videos to the media library manually. So you will need to test this project on a device.

The starter project has five screens that will demonstrate the five concepts covered in this AVFoundation tutorial. Each screen is accessible from the start screen, as seen in the screenshot below:

The starter app contains a storyboard with basic setup of the five UIViews. CommonVideoViewController is the superclass for all of the tutorial classes; it handles the loading of the video assets from the library as well as the rendering of the final video.

Note: If you are confused about the setup of the storyboards in the starter project, refer to the original tutorial, which shows you how to set up the storyboard for this particular app, or check out our Storyboards tutorial.

AddBorderViewController, AddOverlayViewController, AddSubtitleViewController, AddTiltViewController and AddAnimationViewController are the five controllers that are connected to the views in the storyboards. These views will provide examples of the five concepts that this AVFoundation tutorial focuses on.

CommonVideoViewController has a method called applyVideoEffectsToComposition:size: that will be overridden in each subclass.

As the name suggests, this is where the magic happens! In the starter project, this method has no functionality implemented, so the exported video file will simply be identical to the original. It’s up to you add the code that will add the magic to your video in each of the sub-classes!

Sound good? Quiet on the set — it’s time to get this show started!

The Star of the Show — Core Animation

Core Animation is a graphics rendering and animation framework in iOS that lets you animate views and other elements in your app. Most of the work to create your animation effects is done by Core Animation, so in most cases you simply need to set a few parameters on your animation object such as duration and transformation type.

Note: Sounds confusing? Or would like to learn more about Core Animation? Take a look at Introduction to CALayers and How to Use UIView Animation for some of the basics.

You may already have used Core Animation for rendering portions of the user interface in various other apps; however, the goal here is to render the animation composited into a video rather than directly on-screen.

The AVVideoCompositionCoreAnimationTool class — which is part of AVFoundation — is the workhorse that integrates Core Animation at the post-processing stage for your video. This stage is where you can add overlays, backgrounds, and animation to the output video.

At the top level, AVVideoCompositionCoreAnimationTool has a parent CALayer object that can have any number of child CALayer objects. It’s sort of like a top-level view that has multiple subviews. Shifting the order of these layers means you can stack your video effects, such as displaying a background under your video, or placing an overlay on top.

The diagram below illustrates this concept:

Since animation sequences can be added to CALayer objects, you’ll use this tactic to add animation to your videos.

Enough theory — time to start adding some cool effects to your video!

Make a Run for the Border — Adding Borders to Videos

Adding a border to your video is quite simple: you crop the video around the edges and place a colored background behind the video layer so that the color shows through the cropped sections. Voila! A colored border!

VideoEditing

You can then set the color of the background/border to whatever you wish, and you can also control the size of your border by simply adjusting the crop area.

An easy way to get the colored background is to use an image filled with a single solid color. Since AddBorderViewController will demonstrate how to add a border to a video, that’s where you’ll make the necessary changes.

Open the starter project in Xcode (if it’s not already open) and add the following method to AddBorderViewController.m:

- (UIImage *)imageWithColor:(UIColor *)color rectSize:(CGRect)imageSize {
    CGRect rect = imageSize;
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
    [color setFill];
    UIRectFill(rect);   // Fill it with your color
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
 
    return image;
}

This method creates a colored image matching the provided size by using standard drawing functions and then returns it.

Find applyVideoEffectsToComposition:size: in AddBorderViewController.m. This is the stubbed-out method mentioned earlier. Now’s your chance to add some video magic! :]

Add the following code to applyVideoEffectsToComposition:size:

    UIImage *borderImage = nil;
 
    if (_colorSegment.selectedSegmentIndex == 0) {
        borderImage = [self imageWithColor:[UIColor blueColor] rectSize:CGRectMake(0, 0, size.width, size.height)];
    } else if(_colorSegment.selectedSegmentIndex == 1) {
        borderImage = [self imageWithColor:[UIColor redColor] rectSize:CGRectMake(0, 0, size.width, size.height)];
    } else if(_colorSegment.selectedSegmentIndex == 2) {
        borderImage = [self imageWithColor:[UIColor greenColor] rectSize:CGRectMake(0, 0, size.width, size.height)];
    } else if(_colorSegment.selectedSegmentIndex == 3) {
        borderImage = [self imageWithColor:[UIColor whiteColor] rectSize:CGRectMake(0, 0, size.width, size.height)];
    }

_colorSegment refers to the segmented control that lets the user pick the border color. Take a peek at MainStoryboard.storyboard if you’re curious about how this is used. The selected value from the segment control is used to determine the border color to be applied. Then imageWithColor:rectSize: is called to get the a background image with the correct color.

Remember those CALayer objects that you read about earlier? It’s time to call them in and put them to work!

Still in AddBorderViewController.m, add the following lines to applyVideoEffectsToComposition:size:, directly below the code you added earlier:

    CALayer *backgroundLayer = [CALayer layer];
    [backgroundLayer setContents:(id)[borderImage CGImage]];
    backgroundLayer.frame = CGRectMake(0, 0, size.width, size.height);
    [backgroundLayer setMasksToBounds:YES];

AVVideoCompositionCoreAnimationTool, the Core Animation class which handles the video post-processing, needs three CALayer objects for the video composition: a parent layer, a background layer, and a video layer. The code above sets up the background layer using the colored image.

Next, you need to add the video layer.

Add the following code to applyVideoEffectsToComposition:size:, just below the bit you added before:

    CALayer *videoLayer = [CALayer layer];
    videoLayer.frame = CGRectMake(_widthBar.value, _widthBar.value,
                                size.width-(_widthBar.value*2), size.height-(_widthBar.value*2));

Hopefully it comes as no shock to you that the video layer holds…the video! :] You’ll notice that the video’s frame size is reduced by _widthBar.value*2 to leave a border around the edge.

Now add the following code to create the parent layer (still in applyVideoEffectsToComposition:size:):

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

The parent layer is rendered at full size and holds both the background layer and the video layer.

The order of adding child layers matters here; the background layer has to be added as a sublayer first. If you mix up the order of the background and the video, you’ll get a stunning rendition of a solid colored rectangle with no video to be seen anywhere! That’s because the video layer is being rendered behind the background — not exactly the effect you were looking for!

Finally, add this line to the end of applyVideoEffectsToComposition:size:

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

AVVideoCompositionCoreAnimationTool needs to point to where the output should go — videoLayer — and where the input is coming from — parentLayer.

Note that even though you’re using Core Animation, there’s nothing actually being animated here — none of your objects move around on the screen. Core Animation is simply being used because it makes video compositing easy.

Build and run. When your app launches, select “Add Border to video” and then “Add Video Asset” to select a video from your library. Pick a border width and color, then tap on “Generate Output”.

You won’t see any feedback while the device churns away in the background, but after a little while you should see a “Video Saved” message pop up. Head on over to your Photos app and check out your processed video! Depending on the width and colors you picked, your video should look something like the following:

Borders are nice, but you’re an aspiring video editor, and you’ve probably already started thinking “If I can add objects behind videos, surely I can also add them on top of videos!” :]

You’re right — the next section deals with adding custom overlays to your video!

Taking Center Stage — Adding Overlays to Videos

Overlays are really useful for adding watermarks, copyright labels, or other images to your video. By this point, you have almost everything you need to add overlay layers to your video.

“Really? Already?” you might say. Sure! Recall that when you added a border to a video, the border was simply an image on a layer behind the video. The only difference with overlays is that they go on top of the video. That means the overlay image needs to have transparent sections where the video will show through.

The starter project has three sample overlay images the user can choose from: Frame-1.png, Frame-2.png, and Frame-3.png, as seen below:

Switch to AddOverlayViewController.m and find, the hopefully by now familiar, applyVideoEffectsToComposition:size: which should be empty. You’ll just need to add a sprinkling of video magic!

Add the following code to applyVideoEffectsToComposition:size::

  // 1 - set up the overlay
  CALayer *overlayLayer = [CALayer layer];
  UIImage *overlayImage = nil;
  if (_frameSelectSegment.selectedSegmentIndex == 0) {
    overlayImage = [UIImage imageNamed:@"Frame-1.png"];
  } else if(_frameSelectSegment.selectedSegmentIndex == 1) {
    overlayImage = [UIImage imageNamed:@"Frame-2.png"];
  } else if(_frameSelectSegment.selectedSegmentIndex == 2) {
    overlayImage = [UIImage imageNamed:@"Frame-3.png"];
  }
 
  [overlayLayer setContents:(id)[overlayImage CGImage]];
  overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
  [overlayLayer setMasksToBounds:YES];
 
  // 2 - set up the parent layer
  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];
 
  // 3 - apply magic
  composition.animationTool = [AVVideoCompositionCoreAnimationTool
                               videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

Does this code look familiar? Yup, it’s very similar to the previous code for adding borders!

Going through the numbered comments above, you’ll find the following:

  1. The user is able to select which overlay image to use. The selected image is loaded into overlayImage, which is then added to overlayLayer for compositing.
  2. Next, the parent layer is set up. Note the difference in order: the video layer is added before the overlay layer. This way, the overlay will appear on top of the video, but the transparent parts of the image will let the video show through.
  3. Finally, the usual call to AVVideoCompositionCoreAnimationTool is made to set up the final composition with the layers.

Build and run, tap the “Add Overlay to video” button, select your overlay, and then tap “Generate Output”. Once the video has been saved, go to the Photos app and check out your new video.

You should be rewarded with something like the following:

You can add images behind of or in front of a video (or both at the same time) to generate all sorts of neat effects!

Okay, it’s pretty cool to add images on top of your videos, but what about adding things like titles? You know that the world will be dying to know the name of the genius behind all of these great effects — you :]

You’ve probably guessed that adding titles to your video is as simple as adding another overlay to your video. Read on and learn how!

Just Like Those Foreign Films — Adding Subtitles to Videos

Adding text overlays to video can be used for subtitles or captions. This is especially useful for video presentations or to make your videos fully accessible to those who don’t choose to (or aren’t able to) listen to the audio track.

With text overlays, you don’t use an image overlay. Instead, you create an overlay layer on which you’ll render the text.

Open AddSubtitleViewController.m and look for applyVideoEffectsToComposition:size:.

You know the drill by now; add the code below to applyVideoEffectsToComposition:size::

    // 1 - Set up the text layer
    CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
    [subtitle1Text setFont:@"Helvetica-Bold"];
    [subtitle1Text setFontSize:36];
    [subtitle1Text setFrame:CGRectMake(0, 0, size.width, 100)];
    [subtitle1Text setString:_subTitle1.text];
    [subtitle1Text setAlignmentMode:kCAAlignmentCenter];
    [subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]];
 
    // 2 - The usual overlay
    CALayer *overlayLayer = [CALayer layer];
    [overlayLayer addSublayer:subtitle1Text];
    overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
    [overlayLayer setMasksToBounds:YES];
 
    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];

Again, this should look very familiar! Just to be complete, though, here’s a rundown of the steps:

  1. CATextLayer, as the name suggests, is a CALayer subclass specifically designed for text layout and rendering. You set the various subtitle properties such as font, size, text, and position here.
  2. The rest of the method should be familiar by now: set up the overlay, set up the parent layer, and then finally use AVVideoCompositionCoreAnimationTool to do the composition.

Build and run your app. This time, tap the “Add Subtitle to video” button and select a video to process. Type in some subtitle text, then hit the “Generate Output” button.

Once the video is saved, go to your Photos app and you should see a subtitle at the bottom of your video, similar to the screen below:

You can play around with the text and font settings in the code above and see the difference in the output. Note that the text itself comes from _subTitle1, which is a UITextField on the storyboard.

Okay, that’s enough for static overlays. Time to take the user on a crazy “Inception”-like ride through your video by adding some perspective effects!

Nothing Shifty About This Video — Add Tilt Effect to Videos

The stacking of layers to create overlays is similar to multiple views stacked in a view hierarchy. Similarly, CATransform3D is Core Animation’s version of CGAffineTransform in Core Graphics.

Note: Want to learn more about Core Graphics and CGAffineTransform? Then take a look at Core Graphics Tutorial: Curves and Layers.

CATransform3D can really be useful for advanced video editors who want to add cool transitions to their videos. In this section, you’ll create a simple 3D tilt effect along the x-axis for your video.

Open AddTiltViewController.m and — you guessed it! — find applyVideoEffectsToComposition:size:. Then add the following code to the method:

    // 1 - Layer setup
    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];
 
    // 2 - Set up the transform
    CATransform3D identityTransform = CATransform3DIdentity;
 
    // 3 - Pick the direction
    if (_tiltSegment.selectedSegmentIndex == 0) {
        identityTransform.m34 = 1.0 / 1000; // greater the denominator lesser will be the transformation
    } else if (_tiltSegment.selectedSegmentIndex == 1) {
        identityTransform.m34 = 1.0 / -1000; // lesser the denominator lesser will be the transformation
    }
 
    // 4 - Rotate
    videoLayer.transform = CATransform3DRotate(identityTransform, M_PI/6.0, 1.0f, 0.0f, 0.0f);
 
    // 5 - Composition
    composition.animationTool = [AVVideoCompositionCoreAnimationTool
                                 videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

You’ll notice right off that the implementation here is quite different than before. First off, there’s no overlay layer. In this case, you’re applying a transform to the video layer itself — so there’s no need for an overlay.

Going through the code section-by-section, you’ll find the following:

  1. The usual setup for the parent and video layers.
  2. An identity transform is just a baseline transform that does nothing, just as multiplying a number by 1 does nothing. It’s the starter CATransform3D object that you’ll tweak to get the desired effect.
  3. Internally, transforms are just matrices (you can brush up on the ugly math at Wikipedia, if you like). The number at position (3,4) of the matrix (accessed by the m34 property) controls the amount of tilt, or how “squashed” the video appears.
  4. The CATransform3DRotate function takes identityTransform as the starting point and applies a rotation around the x-axis.
  5. Finally, the usual composition via AVVideoCompositionCoreAnimationTool is done.

Build and run your project!

Select “Add Tilt to video”, choose your video, and generate a copy with the tilt effect. Go find your video in your Photos app and check out the crazy tilt effect, much like the images below:

If you don’t see a drastic difference between the original video and the tilted video after using the code above, try reducing the value in section #3 to something smaller like 100. Play around with the tilt settings and see how the output is affected. Replacing 1000 with 500 for a “squashier” tilt. Or change the angle in section #4 from “M_PI/6.0″ (that’s 30 degrees) to “M_PI/3″ for an extreme 60 degree tilt!

The last three parameters in the call to CATransform3DRotate() control the axis of rotation; try playing around with these to rotate around the y-axis (0.0f, 1.0f, 0.0f) instead of the x-axis (1.0f, 0.0f, 0.0f) or some other arbitrary vector.

Note: For more information on how to use CATransform3D and matrix manipulation, check out the Core Animation Programing Guide.

So far, you’ve learned about image overlays, text overlays, and now direct video transforms. And all this time you’ve dealt with Core Animation — but nothing’s actually been animated yet! Can you animate things in your video using Core Animation?

Okay, we won’t keep you in suspense any longer — you can definitely add animations to your video! Read on to find out how.

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!

Abdul Azeem Khan

Abdul Azeem is a software architect and co-founder at Datainvent Systems, a software development and IT services company. Azeem has been developing iOS applications since 2009 and has over 10 application on Appstore.

Check out his portfolio or contact him for work or just to chat via Twitter, LinkedIn, or email.

User Comments

28 Comments

[ 1 , 2 ]
  • Hi ,

    Is it possible to record on the main thread and replay a different file on another thread.


    Thanks,
    Niki
    niki
  • The tutorial is excellent. Even the previous tutorial about play, record edit merge was really good. But only problem I have found is once we process the video in any of the application original audio is removed. How can we retain that audio. Will be great if you can guide. Thanks a ton
    SandeepK
  • The information is outstanding. Even the past information about perform, history modify combine was really good. But only problem I have discovered is once we procedure it clip in any of the program unique sound is eliminated.
    johnjony
  • This tutorial was amazingly helpful! Thanks so much. I have taken your sample project as a starting point for something I am working, and I have everything working quite nicely. I am creating similar overlay and mate effects as this win the tutorial, but when I export the final product using AVAssetExportSession, I get a complete video, but it has no audio.

    The recorder video has audio then can be heard when previewing the recorded video in UIImagePickerController.

    ios7.

    Any help would be greatly appreciated.

    _mike
    nibeck
  • In case anyone else is having issues with the audio portion of this tutorial. If you are planning on using the audio from the recorded video (and not load in a separate audio file from iTunes), you need some more processing.

    The audio portion of a video asset will NOT automatically transfer through the composition process. You need to create a separate AssetTrack for that audio, even though it's part of the video.

    if([[self.videoAsset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
    audioTrack = [self.videoAsset tracksWithMediaType:AVMediaTypeAudio][0];
    }

    Then simply add this into your composition and the audio will be back.

    _mike
    nibeck
  • Hi,

    By using your code i am trying to add overlay video over another video just like below app
    https://itunes.apple.com/us/app/action- ... 21253?mt=8

    Can you please guide me that can we use above code for video also?


    Thanks
    kanwarpalsingh
  • Hi,

    Using above code i am trying to add overlay video on another video just like below app
    https://itunes.apple.com/us/app/action- ... 21253?mt=8


    Can you please guide me that is it possible by above code? if not then can you please give me direction to achieve that functionality?

    Thanks
    kanwarpalsingh
  • Hi,

    Using above code i am trying to add overlay video on another video just like below app
    https://itunes.apple.com/us/app/action- ... 21253?mt=8


    Can you please guide me that is it possible by above code? if not then can you please give me direction to achieve that functionality?

    Thanks
    kanwarpalsingh
  • Hi,

    By using above code we are trying to add overlay videos over the videos instead of images just like below app
    https://itunes.apple.com/us/app/action- ... 21253?mt=8

    Can you please guide us that is it possible with above code? if not then can you please give us directions?

    Thanks
    kanwarpalsingh
  • Hi

    Great tutorial! But there is an issue I faced, if i add the overlay on video and send video from iPhone to another device(Specially to Samsung galaxy note 2 and samsung Tab) via Whats app. The quality of video becomes so poor thats why this code becomes useless. How can i get the the good quality of video?

    Thanks
    Prachi
    prachi_rajput
  • hi

    i have used your code for video rendering for the video formats .mp4 and it works fine and if i use two different video formats like (.mp4 and .mov) then wasn't work , any changes is required to do that......?????
    raju ram
  • I have been working on merging of videos into a single video using the AVMutableComposition and have got the required output.But i'm getting two different types of issues while merging thevideos.
    1) I couldn't set the custom frames for the videos using the AVMutableVideoCompositionLayerInstruction.
    2) While playing the merged video, the first merged video is been vanished(removed) after its been stopped. But the other videos are staying correctly after stopped in their respective location.
    Please suggest any solution..

    I have attached the video which i have rendered......
    raju ram
  • Thank you for your great post.

    I'm working on an app that creates videos from a series of images. I wanted to add a "ken burns" effect on the images, and I created the effect applying transforms to the main AVMutableVideoCompositionLayerInstruction object using the method "setTransformRampFromStartTransform: toEndTransform: timeRange:"
    It works, but the scale effect gives an ugly result... it looks like refreshes of the frames are visible... it is like an old computer that cannot keep up the frame rate of the video... I don't really know how to explain this :)
    Do you think there is a better way to achieve the result? For example, using AVVideoCompositionCoreAnimationTool?
    Can I add animations to the single video tracks in the compositions?
    Thanks for your help!
    totoro81
[ 1 , 2 ]

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!


Coming up in May: Procedural Level Generation in Games with Kim Pedersen.

Sign Up - May

Coming up in June: WWDC Keynote - Podcasters React! with the podcasting team.

Sign Up - June

Vote For Our Next Book!

Help us choose the topic for our next book we write! (Choose up to three topics.)

    Loading ... Loading ...

Our Books

Our Team

Tutorial Team

  • Martin Walsh

... 55 total!

Editorial Team

  • John Clem

... 21 total!

Code Team

  • Orta Therox

... 1 total!

Translation Team

  • David Xie
  • Heejun Han
  • Fabio Casado

... 38 total!

Subject Matter Experts

... 4 total!