How to create 1,000 videos in 60 seconds

Overview

How I built 1,000 personalised videos in 60 seconds

In this article, we will show you how to build 1,000 personalized birthday videos for 1,000 different people. This is close to impossible to do using traditional video editors such as Adobe Premiere and After Effects, with specialized personalization agencies charging tens of thousands of dollars for this type of service.

The Shotstack API allows you to render tens of thousands of videos in the cloud, and personalise each individual video through small changes to a JSON file.

With our API capable of rendering hundreds videos concurrently in the cloud, the ability to work at enormous scale allows you to render all 1,000 of our videos in less than 30 seconds.

Getting started

Shotstack API key

You can sign up for a free developer account.

Just be aware of throttling as the free account allows for 1 request per second.

Personalised videos using Node.js

I'll use vanilla javascript through Node.js to build the application, but feel free to use what works for you. We have SDKs available for PHP, Node, Ruby and Python.

Personalised videos using Integromat

You can also use our Make app to achieve the same result without using any code at all.

Choosing our footage

I built a promotional video which we'll use to offer our fictitious customers a discount on their birthday. This video has been completely built within Shotstack, but you can achieve the same result using a pre-rendered video built in a video editing solution such as After Effects.

https://youtu.be/01I6xFbhXFE

We'll remove some of the video's content, and use those empty spaces for our personalised data. This data will be placed into a JSON file, and will place back all of those missing items with new values and animations.

For this particular template we'll personalise the name, age, their younger "fake" age, the discount code, and the discount amount.

https://youtu.be/2rijxKxUdXY

Shotstack uses a JSON object that acts like an editable timeline. This works in a similar fashion to how any desktop video editing solution would work, with a timeline representing the video duration, and individual clips allowing you to manipulate its content.

For this article I won't go into how this video was built, but if you're interested in understanding how this particular video was edited you can take a closer look at the JSON template. And if you're really keen this tutorial goes a little deeper into how you can design these videos yourself.

For this example we'll use a simplified template where the animations have been pre-rendered, making it easy for us to add in specific HTML assets where our personalised content should go:

{
  "timeline": {
    "fonts": [
      {
        "src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/fonts/FiraCode-Regular.ttf"
      },
      {
        "src": "https://shotstack-assets.s3-ap-southeast-2.amazonaws.com/fonts/Nexa-Bold.otf"
      }
    ],
    "background": "#000000",
    "tracks": [
      {
        "clips": [
          {
            "asset": {
              "type": "html",
              "html": "<p>firstName</p>",
              "css": "p { font-family: \"Nexa Bold\"; font-size: 128px; color: #ffffff; text-align: left; }"
            },
            "start": 2.35,
            "length": 1.45,
            "offset": {
              "y": -0.23,
              "x": 0.05
            },
            "transition": {
              "out": "carouselDown"
            }
          },
          {
            "asset": {
              "type": "html",
              "html": "<p><b>age</b></p>",
              "css": "p { font-family: \"Nexa Bold\"; font-size: 149px; color: white; text-align: left; }"
            },
            "position": "center",
            "start": 5.2,
            "length": 1.3,
            "offset": {
              "y": -0.23,
              "x": 0.05
            },
            "transition": {
              "in": "zoom",
              "out": "zoom"
            }
          },
          {
            "asset": {
              "type": "html",
              "html": "<p><b>fakeAge</b></p>",
              "css": "p { font-family: \"Nexa Bold\"; font-size: 384px; color: #ffffff; text-align: left;}"
            },
            "position": "center",
            "start": 11.15,
            "length": 2.5,
            "offset": {
              "y": -0.05,
              "x": 0.05
            },
            "transition": {
              "out": "carouselLeft"
            }
          },
          {
            "asset": {
              "type": "html",
              "html": "<p>discountCode</p>",
              "css": "p { font-family: \"Fira Coda\"; font-size: 42px; color: #3498db; text-align: center; background-color: #ffffff; padding: 32px; line-height: 106px; }",
              "width": 320,
              "height": 107
            },
            "start": 17.2,
            "length": 4.8,
            "offset": {
              "y": -0.05,
              "x": 0
            }
          },
          {
            "asset": {
              "type": "html",
              "html": "<p>For discount Off</p>",
              "css": "p { font-family: \"Nexa Bold\"; font-size: 58px; color: #3498db; text-align: left;} span { color: #e74c3c; }"
            },
            "start": 19.2,
            "length": 1.2,
            "offset": {
              "y": -0.302,
              "x": 0.04
            }
          },
          {
            "asset": {
              "type": "html",
              "html": "<p>For <span>discount Off</span></p>",
              "css": "p { font-family: \"Nexa Bold\"; font-size: 58px; color: #3498db; text-align: left;} span { color: #e74c3c; }"
            },
            "start": 20.3,
            "length": 1.7,
            "offset": {
              "y": -0.302,
              "x": 0.04
            }
          }
        ]
      },
      {
        "clips": [
          {
            "asset": {
              "type": "video",
              "src": "https://shotstack-content.s3-ap-southeast-2.amazonaws.com/birthday/birthday-template.mp4",
              "volume": 1
            },
            "start": 0,
            "length": 22
          }
        ]
      }
    ]
  },
  "output": {
    "format": "mp4",
    "resolution": "sd"
  }
}

Personalise videos using a spreadsheet

For our customers we'll use a dataset with information on about 1,000 concocted users. This will include their name, age, fake age, their discount code, and the discount amount. We will then use the data in this CSV to fill in the JSON template and send it to the API. You can find the complete spreadsheet on GitHub.

Create videos from CSV data

The only thing you need to do now is iterate over the CSV file, add those personalised datapoints to the JSON template, and send each video edit to the API for rendering.

The below script works using an .env environment file with the Shotstack API key details in it. You can take a look at my .env file to see how we can use environment variables in our script.

require("dotenv").config();

const fs = require("fs");
const axios = require("axios").default;
const csv = require("fast-csv");
const argv = require("yargs").argv;
const numWords = require("num-words");
const getAge = require("get-age");
const capitalize = require("capitalize");
const Throttle = require("throttle-stream");

const USER_LIST = "./user-list-test.csv";
const VIDEO_LIST = "./video-list.csv";
const API_KEY = process.env.SHOTSTACK_KEY;
const ENDPOINT = process.env.SHOTSTACK_ENDPOINT;
const CUSTOMER_ID = process.env.SHOTSTACK_CUSTOMER_ID;
const PREVIEW_URL = process.env.SHOTSTACK_PREVIEW_URL;
const TEMPLATE = fs.readFileSync("./template.json", "utf8");
const fileStream = fs.createWriteStream(VIDEO_LIST, { flags: "a" });

let count = 0;

fs.createReadStream(USER_LIST)
  .pipe(new Throttle({ bytes: 200, interval: 1000 }))
  .pipe(csv.parse())
  .on("data", (row) => {
    let age = getAge(row[1]);
    let ageInWords = capitalize.words(numWords(age));

    var mapObj = {
      firstName: row[0],
      age: ageInWords,
      fakeAge: row[2],
      discountCode: row[3],
      discount: row[4],
    };

    let template = JSON.parse(
      JSON.stringify(TEMPLATE).replace(
        /firstName|age|fakeAge|discountCode|discount/gi,
        function (matched) {
          return mapObj[matched];
        }
      )
    );

    axios({
      method: "post",
      url: ENDPOINT,
      headers: {
        "x-api-key": API_KEY,
        "content-type": "application/json",
      },
      data: template,
    }).then(
      (response) => {
        if (response.status !== 201) {
          console.log(row[0], response.data.response.id);
          return;
        }

        let video = response.data.response.id + ".mp4";
        fileStream.write(`${row[0]},${PREVIEW_URL}${CUSTOMER_ID}/${video}\n`);
        console.log("Video queued for: " + row[0]);
      },
      (error) => {
        throw error;
      }
    );
  });

The result - 1000 personalised videos

Once you run the script you'll see all thousand personalised templates be sent through to the API for rendering, and all output data will end up in a CSV file called video-list.csv, which will include the urls for each individual video. Image for post

A small sample of the 10,000 personalised videos created

The below list contains the first 20 videos, but if you don't believe me you can find the whole list here.

<script src="https://gist.github.com/derkzomer/a7e3d29d1bbdd2a02b5d79c62321315f.js"></script>

So what next?

Personalised marketing has shown to lead to higher email open rates, higher click-through rates, better engagement, and provides you with a new way to build relationships with your audience.

The above only shows you a small example of what can be done by personalising videos at scale. You can use Shotstack to build personalised media experiences for your customers and automate your customer engagement by linking Shotstack to Sendgrid via Integromat, or many other hyper-personalised automations that takes your customer engagement strategy to the next level.

You might also like...

A jQuery plugin that creates a countdown timer in years, months, days, hours and seconds in the form a bunch of rotating 3d cubes

CountdownCube is a jQuery plugin that is in the form of a bunch of rotating 3D cubes. It uses CSS transitions to create the 3D rotating cube effects.

Mar 6, 2022

⏬ Fetch the most up-to-date ABI of verified Smart Contracts (including proxy implementations) from Etherscan in seconds!

etherscan-abi ⏬ 🚀 Fetch the most up-to-date ABI of verified Smart Contracts (including proxy implementations) from Etherscan in seconds! Usage CLI Fe

Dec 27, 2022

Infisical — Sync your .env securely in seconds.

Infisical Infisical is a simple, end-to-end encrypted secrets manager for your .env files. It enables teams to securely sync and manage .env files in

Jan 4, 2023

🔥 Set up your new Solid component library in seconds!

Create Solid Library Create SolidJS libraries with ease! Usage npx create-solid-library name Development Developing components is often a visual pro

Oct 28, 2022

Search Engine for YouTuber Ali Abdaal's videos

Search Engine for YouTuber Ali Abdaal's videos

Ali Abdaal Search Engine This is a personalized search engine for my favorite YouTubers, Ali Abdaal. I used selenium to scrape all his videos, youtube

Oct 14, 2022

Make use of your favicon with badges, images or videos

favico.js More info here. Author Miroslav Magda Version 0.3.9 Contributors: Serge Barysiuk, pissflaps, Yaroslav Yakovlev, LoicMahieu, Renan Gonçalves,

Dec 21, 2022

Automation scripts I use for my Bitburner gameplay videos.

Bitburner Automation Note: I release a new piece of code when I finish a video segment in the series. If it's a multi-part series, the scripts will no

Dec 25, 2022

A browser extension to simplify web pages and hide distracting things like hide cookie banners, auto-playing videos, sidebars, etc

A browser extension to simplify web pages and hide distracting things like hide cookie banners, auto-playing videos, sidebars, etc

Unclutter Browser Extension A browser extension to simplify web pages and hide distracting things like hide cookie banners, auto-playing videos, sideb

Jan 9, 2023
Owner
Shotstack
The Cloud Video Editing API
Shotstack
List of ~240,000 Persian words

an-array-of-persian-words List of ~240,000 English words. Derived from the Dehkhoda dictionary. Install npm: npm install an-array-of-persian-words Use

peyman farahmand 3 Mar 16, 2022
Its an app that uses a weather API with access to over 200,000 cities current weather conditons.

Weather App Its an app that uses a weather API with access to over 200,000 cities current weather conditons. Screenshots Links Live Site URL: live sit

Yusuf Lawal 5 Aug 17, 2022
Weather app made using openweather api that supports over 200,000 cities

About This is an open-source weather app built using React.js, and you are welcome to add your unique touch to this project by contributing to the rep

Nikhil Mishra 6 Oct 17, 2022
Create your own NFTs within seconds 🪄

MagicaNFT An automated process to create a number of NFTs At the moment, the program only makes pixelated NFTs, with only a certain number of characte

Jaival Patel 2 Feb 3, 2022
Create 💎 beautiful video mockups from templates withing ⏳ seconds

?? Mockoops Create animated mockups from boring screen recordings in seconds, powered by React. ⚡️ Superfast rendering powered by Serverless Functions

Mohit Yadav 185 Jan 6, 2023
🚀AI拟声: 5秒内克隆您的声音并生成任意语音内容 Clone a voice in 5 seconds to generate arbitrary speech in real-time

English | 中文 Features ?? Chinese supported mandarin and tested with multiple datasets: aidatatang_200zh, magicdata, aishell3, and etc. ?? PyTorch work

Vega 25.6k Dec 29, 2022
Get started on Remix with TypeScript and Tailwind CSS in seconds

remix-typescript-tailwind-quickstart Get started on Remix with TypeScript and Tailwind CSS in seconds. This is an example setup of Remix building on t

Resi Respati 12 Mar 16, 2022
Get any Candy Machine ID in seconds with this npm module!

What Does it do? Grabs Candy Machine ID of any v1 or v2 candy machine websites. Installation npm i candymachinescraper --save Example Usage // Get Can

Oscar Gomez 9 Oct 26, 2022
Deploy a local project to Replit, in seconds!

mvrepl A tool to deploy a local project to replit, in seconds! Requirements: latest version of Node.js (https://nodejs.org/) latest version of npm (ht

grr 5 Jun 18, 2022