May 10, 2024
O Wolfson
In this article I'll outline step-by-step how to up a script that will convert GIF files to MP4 videos using fluent-ffmpeg
. You will understand the code, and know how to run the script.
Gif
Video
Ensure that Node.js is installed on your system. If not, download and install it from nodejs.org.
Create a new directory for your project and navigate into it:
bashmkdir gif-to-mp4
cd gif-to-mp4
Run the following command to create a package.json
file:
bashnpm init -y
Install fluent-ffmpeg
and ffmpeg-static
by running:
bashnpm install fluent-ffmpeg ffmpeg-static
Make sure that FFmpeg is correctly installed and accessible in your environment's PATH. The ffmpeg-static
package provides an FFmpeg binary that fluent-ffmpeg
can use.
Create a file named convert.js
:
bashtouch convert.js
Paste the following code into convert.js
:
javascriptconst ffmpeg = require("fluent-ffmpeg");
const fs = require("fs");
const path = require("path");
const ffmpegStatic = require("ffmpeg-static");
// Set FFmpeg binary path
ffmpeg.setFfmpegPath(ffmpegStatic);
const inputDir = "./_input";
const outputDir = "./_videos";
// Ensure output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
// Read files from input directory
fs.readdir(inputDir, (err, files) => {
if (err) {
console.error("Error reading input directory:", err);
return;
}
files
.filter((file) => path.extname(file).toLowerCase() === ".gif")
.forEach((file) => {
const inputFilePath = path.join(inputDir, file);
const outputFilePath = path.join(
outputDir,
path.basename(file, ".gif") + ".mp4"
);
// Convert GIF to MP4
ffmpeg(inputFilePath)
.complexFilter([
{
// Scale filter: Adjusts the height of the video to maintain a 16:9 aspect ratio based on the original height
// and scales the width accordingly, setting it to automatically calculate so that the aspect ratio is preserved.
filter: "scale",
options: "ih*16/9:-1",
inputs: "[0:v]",
outputs: "[scaled]",
},
{
// Colorlevels filter: Adjusts the minimum input levels for red, green, and blue channels to 1.
// This can be used to manipulate image contrast or correct color levels that are too dark or washed out. Here I am using it to black-out the background.
filter: "colorlevels",
options: "rimin=1:gimin=1:bimin=1",
inputs: "[scaled]",
outputs: "[bg]",
},
{
// Overlay filter: Places the original input video over the scaled and color-adjusted background.
// The placement coordinates ensure that the video is centered on both axes.
filter: "overlay",
options: "(W-w)/2:(H-h)/2",
inputs: ["[bg]", "[0:v]"],
outputs: "[overlayed]",
},
{
// Crop filter: Crops the overlayed video to maintain the 16:9 aspect ratio by adjusting the height.
// It calculates the height to be proportional to the current width keeping the aspect ratio.
filter: "crop",
inputs: "[overlayed]",
options: { h: "iw*9/16" },
outputs: "[cropped]",
},
{
// Scale filter: Finally scales the cropped video to a fixed resolution of 640x360 pixels,
// which is a standard resolution maintaining a 16:9 aspect ratio.
filter: "scale",
options: "640:360",
inputs: "[cropped]",
output: "[final]",
},
])
.output(outputFilePath)
.run();
});
});
bashmkdir _input _videos
Add some GIF files to the _input
directory.
Execute the script by running:
bashnode convert.js
This will start the conversion process, where each GIF file in the _input
directory is processed and saved as an MP4 file in the _videos
directory. The script logs the status of each file, indicating whether the conversion was successful or if there were errors.
This tutorial covers the essential aspects of setting up a Node.js project to convert GIF files to MP4 using fluent-ffmpeg
. Adjust the filter and encoding settings in the script as needed to fit your specific requirements.