Setting Complex Filters, Zoom, Pan, and Xfade with FFmpeg using Fluent-FFmpeg
In this article, we will discuss how to set up complex filters, zoom, pan, and xfade using FFmpeg and Fluent-FFmpeg in a Node.js environment.
Prerequisites
To follow along with this article, you should have a basic understanding of Node.js and FFmpeg. You should also have Node.js and FFmpeg installed on your system.
Setting up the project
First, let's create a new Node.js project and install Fluent-FFmpeg as a dependency.
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');
const imageCount = 5;
const imagesPath = './images/';
const outputPath = './output.mp4';
const filters = Array.from({length: imageCount - 1}).map((_, i) => {
const randomInt = Math.floor(Math.random() * 10) + 1;
return `
[0:v][${i + 1}:v]
overlay=x='if(gte(on,${randomInt}), min(${randomInt}00-(on-${randomInt})*100,\
w-w-${randomInt}00)', y='if(gte(on,${randomInt}), 0, \
h-h-${randomInt}00)'):shortest=1[out${i}]
`;
});
In the code block above, we have created a Node.js script that sets up the complex filters. We have defined the number of images, the path to the images, and the output path. We have also created an array of filters using the Array.from() method. Each filter randomly overlays one image on top of another with a fade-in effect.
Applying the filters
ffmpeg()
.input(imagesPath + 'image%d.jpg')
.complexFilter(filters.join(''), 'out')
.outputOptions('-c:v libx264')
.save(outputPath)
.on('end', () => {
console.log('Output file created at ' + outputPath);
})
.on('error', (err) => {
console.error(err);
});
In the code block above, we have applied the filters to the input images using the complexFilter() method. We have also specified the output options and saved the output file.
Zooming and panning
To zoom and pan the input images, we can use the zoompan filter.
const zoomPanFilters = Array.from({length: imageCount - 1}).map((_, i) => {
const randomInt = Math.floor(Math.random() * 10) + 1;
return `
[${i}][${i + 1}]
zoompan=z='zoom+0.001*max(1-(on-${randomInt}),0)':x='if(gte(on,${randomInt}), \
${randomInt}*iw/100-(iw-ow)/2, x)':y='if(gte(on,${randomInt}), \
${randomInt}*ih/100-(ih-oh)/2, y)':d=1:s=${w}x${h}
`;
});
In the code block above, we have created an array of zoom and pan filters. Each filter randomly zooms in on the input image and pans it to a random position.
Applying the zoom and pan filters
ffmpeg()
.input(imagesPath + 'image%d.jpg')
.complexFilter(zoomPanFilters.join(''), 'out')
.outputOptions('-c:v libx264')
.save(outputPath)
.on('end', () => {
console.log('Output file created at ' + outputPath);
})
.on('error', (err) => {
console.error(err);
});
In the code block above, we have applied the zoom and pan filters to the input images using the complexFilter() method.
Xfade transition
To apply an xfade transition between the input images, we can use the xfade filter.
const xfadeFilter = `
xfade=transition=fade:duration=1:offset=${fadeDuration}
`;
In the code block above, we have created an xfade filter that applies a fade transition between the input images with a duration of 1 second and an offset of fadeDuration.
Applying the xfade filter
ffmpeg()
.input(imagesPath + 'image%d.jpg')
.complexFilter(xfadeFilter)
.outputOptions('-c:v libx264')
.save(outputPath)
.on('end', () => {
console.log('Output file created at ' + outputPath);
})
.on('error', (err) => {
console.error(err);
});
In the code block above, we have applied the xfade filter to the input images using the complexFilter() method.
- We have discussed how to set up complex filters, zoom, pan, and xfade with FFmpeg using Fluent-FFmpeg in a Node.js environment.
- We have demonstrated how to create and apply complex filters, zoom and pan filters, and xfade filters to input images.
References
-
Fluent-FFmpeg documentation:
-
FFmpeg documentation:
-
Node.js documentation: