In this guide we'll show you how to add picture-in-picture functionality to your videos using Node.js and Shotstack dynamic templates.
We'll take the following base footage:
And overlay the following clip as a picture-in-picture video:
Sign up for a Shotstack developer account to receive your API keys.
Our script will be written in Node.js and will only require the axios
dependency.
A Shotstack video edit is a JSON file describing your video in similar terms to how you would use a desktop video editor.
You can directly send the JSON to the API, but for this guide we'll use the dashboard to save the template to our account, simplifying the process.
Create a template by heading over to your dashboard and clicking on Studio
. There you can create a new template. Make sure to note down the uuid of the template as we'll use it in our application.
Now copy the JSON below over into the editor. Our edit will be using merge fields. These will allow us to easily change the PiP video url in our code through the use of handlebars {{ ... }}
.
{
"timeline": {
"background": "#000000",
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "{{pipUrl}}",
"volume": 1
},
"start": 0,
"length": 11,
"scale": 0.35,
"position": "bottomRight",
"offset": {
"x": -0.05,
"y": 0.05
}
}
]
},
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/filming-montage.mp4"
},
"start": 0,
"length": 11
}
]
}
]
},
"output": {
"format": "mp4",
"resolution": "hd"
},
"merge": [
{
"find": "pipUrl",
"replace": "https://shotstack-assets.s3.amazonaws.com/footage/scott-ko.mp4"
}
]
}
To test whether your template looks the way you want, you can render the template or preview it using the editor.
Create a new Node.js script file and add the code below. The script will retrieve your template and POST it to the API template render
endpoint. It will then poll the API to retrieve the render status.
Set your API key as an environment variable (Linux/Mac):
export SHOTSTACK_API_KEY=your_key_here
or, if using Windows:
set SHOTSTACK_API_KEY=your_key_here
Copy the code below over to your own app.js
file making sure to replace the template id with your own.
const axios = require('axios');
const headers = {
'Content-Type': 'application/json',
'x-api-key': process.env.SHOTSTACK_API_KEY,
}
const pipUrl = 'https://shotstack-assets.s3.amazonaws.com/footage/scott-ko.mp4';
const poll = async (uuid) => {
await timeout(1000);
try {
const response = await axios({
method: 'get',
url: `https://api.shotstack.io/v1/render/${uuid}`,
headers: headers,
});
console.log(response.data.response.status);
if (response.data.response.status !== 'done') {
await poll(uuid);
} else {
console.log(response.data.response);
return;
}
} catch (error) {
console.log(error);
}
}
const timeout = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}
const render = async (pipUrl) => {
try {
const response = await axios({
method: 'post',
url: 'https://api.shotstack.io/v1/templates/render/',
data: {
id: 'e2d839f6-e4d1-4794-9bfb-d0415998f10a',
merge: [
{
find: 'pipUrl',
replace: pipUrl
}
]
},
headers: headers,
});
console.log(response.data);
await poll(response.data.response.id);
} catch (error) {
console.log(error);
}
}
render(pipUrl);
The final output is a video with picture-in-picture video overlaid.
This guide shows you how to build an application that places a scaled video on top of another video; creating a picture-in-picture effect.
For a working application you can check out our open-source picture-in-picture generator which you can use to generate picture-in-picture videos. The complete source code is available on GitHub, which you could use as a starting point to build your own application.
Every month we share articles like this one to keep you up to speed with automated video editing.