The Marketing Technologist.

We talk about analytics, code, data science and everything related to marketing technology. Backed by the tech geeks of Greenhouse Group.

Creating dynamic videos using JavaScript and After Effects: the basics

In digital marketing, there is a lot of buzz around dynamic videos. You may have noticed all the start-ups popping up in this scene. Dynamic is nothing new in the world of display advertising. We already see a lot of dynamic ads for retargeting by big parties like Criteo, but when it comes to online video, there aren't a lot of dynamic video cases (that we know of). We believe there are a couple of reasons for this, but we'll get into that in another post. In this post, we'll focus on the technical aspects of creating a dynamic video.

What's dynamic video anyway?

There are a lot of (buzz) words flying around: interactive video, dynamic video, personalized video etc. And misconceptions, too. For instance: clickable videos, like those with info cards or in-video link-buttons, are interactive, not dynamic. A couple of years ago it was cool (mostly in social) to personalize animations using Flash or HTML5 Canvas. That's not dynamic video either, that's a personalized web animation.

To me, a video becomes dynamic when a specific video is rendered, pre-rendered or on-the-fly, for a specific context. That context may apply to a big group of people with the same interests, or to a single user. Another alternative term would be personalized video.

I'm aware that these definitions are both pretty technical. If you have a better one, please feel free to share it in the comment section below.

One of the advantages of creating a dynamic video is that you don't have to spend a lot of money on production when you want to change a specific part of your video. You can theoretically create thousands of variations of one video without touching any video editing software or asking your production party.

Let's create a dynamic video

Enough with the definitions. In this post, I'd like to show how you can add a dynamic section to an existing video and render it using code. What we put in the dynamic section can be configured in a JSON file. In our example, we use a static JSON file, but in a real world example, this file would be generated by a server for a specific situation. For composing and rendering, we'll use Adobe After Effects CC.

In this example, we are using a funny TV commercial by Vodafone. We haven't done any dynamic video cases for Vodafone (yet), so this is just a hypothetical example. Here's the original:

In this post, we'll add a section at the end of the video, showing a nice personalized offer for an iPhone 6. In a real-world retargeting example, we might want to show this video as a preroll to a user that just visited an iPhone 6 page on the Vodafone website. The dynamic video we're going to create will look something like this:

Create the data model

We want to show a specific proposition at the end of the video. Let's keep it simple for now, and just add the phone image and its name. The code should look this:

// Model.js
var proposition = {
	imageUrl: 'phone.png',
    name: 'iPhone 6 Space Grey'
}

In our demo, this file is static, but in the real world this data might be generated by some user interface, enabling a marketer to create dynamic videos. Or the data is generated by any trigger, like a scraper or an API call.

Create placeholders in After Effects

We need to add some elements that will act as placeholders for our data. As we want to show the name of the phone and its image, let's draw a text field and an image. There is nothing special going on here. To make it look good, let's draw a background as well, and maybe add an animation. For me it looks something like this:

My timeline now looks like this:

Fill the placeholders with the JSON data

Now we've got our static video in place, let's add our JavaScript data model to the placeholders. Let's start with the name of the phone. Select your title layer and extend the text properties. We are looking for the Source Text property. We need to write an expression to fill this property with our model data.

// Absolute path to our JavaScript model file
var pathToModel = '/path/to/Model.js';
// Evaluate our model
$.evalFile(pathToModel)
// Now the proposition is accessible, return the name property
proposition.name

After you added this code to the Source Text expression, it looks like this:

For now we just hard code the path to our data model in the After Effects file. Please note that this path cannot be relative.

Render the video with the command-line

Of course, we could just render the video in the After Effects GUI, and we'd have a nice video based on a data file. But to make it a lot more useful, we want to render the video using code, and without even opening After Effects. So let's start to render the video using the command-line.

Rendering After Effects files without even opening After Effects is possible by using a file called aerenderer. The executable file aerender.exe is a program with a command-line interface that allows you to automate rendering. The executable file is located in the same folder as the primary After Effects application. If you are working on a web server, you need to make sure you installed After Effects on that machine as well.

The default locations for this file are:

Windows: \Program Files\Adobe\Adobe After Effects CC\Support Files
Mac OS: /Applications/Adobe After Effects CC

This executable accepts a lot of arguments, but for now we're interested in these three:

  • -comp comp_name: comp_name specifies a composition to render
  • -project -project_path: project_path is a file path or URI specifying a project file to open. If this argument is not used, aerender works with the currently open project. If no project is specified and no project is open, the result is an error.
  • -output outputpath: output_path is a file path or URI specifying the destination for the final output file. If this argument is not used, aerender uses the path defined in the project file.
  • -OMtemplate output_module_template: output_module_template is the name of a template to apply to the output module. In our example, we'll just stick with h264.

To render our previously created AE file, we'll enter this command in our terminal:

earenderer -project template.aep -comp final -output video.mov -OMtemplate h264

Please note that aerender starts a new instance of After Effects by default, even if one is already running. To use the currently running instance instead, add the –reuse argument.

Use NodeJS to render the video

If we want to render the video in a web environment, we need some way to call the render command from a web server. Because NodeJS is our server technology of choice, we'll stick with NodeJS. We can call command line instructions in NodeJS using spawn on the child_process module.

// render.js
var spawn = require('child_process').spawn;

var ae = spawn('/Applications/Adobe After Effects CC 2015/aerender',[
'-project', 'template.aep',
'-comp', 'final',
'-output', 'movie.mov,
'-OMtemplate', 'h264'
]);

ae.stderr.on('data', function (data) {
// Error occured
console.log('stderr: ' + data);
});

ae.on('close', function (code) {
// Video has rendered
});

We can now run our index.js with Node:

node render.js

That's it. We've just rendered a dynamic video using After Effects and JavaScript. Nice!

Next steps

If you just want to render a video once in a while, this solution will do the trick. We got everything working for a single video on a local machine, but the real challenge is scalability and infrastructure. If you'd like to render thousands of videos and even do it in a parallel fashion, you'll need some really powerful machines, and start thinking about building a render farm. We'll get to that in a future post.

Eventually, we'd like to serve custom made videos for a single unique visitor on the fly, but so far none of the big advertising platforms support the real-time serving of videos. We're talking to some parties about this, so I expect to see some cool things happen in 2016.

Thanks to my brilliant friend and colleague Niels Wijers, who first came up with this proof of concept. All credits go to him.