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

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

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!