How to Convert an Audio File into Video in NodeJS
Power of FFmpeg with NodeJS
Converting audio files into video files is an everyday use case in the current age of content production.
While there are many ways to do it via some custom websites, we programmers don’t follow that easy, simple path, right?
Today, I will show you how to convert an audio file into a video file in NodeJS.
What Will We Use?
We will use the power of FFmpeg. In their documentation, they identify themselves as:
A complete, cross-platform solution to record, convert and stream audio and video.
This is not something specific to NodeJS. Instead, it’s OS-level documentation that you can install on your machine by running the following commands on
Linux
sudo apt update
sudo apt install ffmpeg
And verifying the version
ffmpeg -version
If you are on macOS, it’s even easier.
brew install ffmpeg
If you want to learn how to use FFMpeg in Docker, you can check the following article. https://javascript.plainenglish.io/how-to-use-ffmpeg-with-node-js-and-docker-c21f56993e14
The problem with NodeJS
The problem is accessing the FFmpeg directly from NodeJS can be tricky. However, several libraries create an abstraction on top of the FFmpeg.
Some of the most notable ones are fluent-ffmpeg
and ffcreator
.
Today we will use the light version of ffcreator
which is called ffcreatorlite
Let’s get started
I am assuming you already have a NodeJS project up and running. If not, then you can use the following boilerplate. https://github.com/Mohammad-Faisal/nodejs-typescript-skeleton Just run the following command:
git clone https://github.com/Mohammad-Faisal/nodejs-typescript-skeleton.git
It will give you a basic NodeJS project.
Install Dependencies
Add the required dependency
yarn add ffcreatorlite
Then add an audio file to the project. You will probably also want a cover image for your generated video, right? So bring that in too.
|- src
|----index.ts
|----source.mp3 // your audio file
|----cover.png // your cover image
That’s the preparation. Let’s build it.
Get the Individual Functions
First, you will need an instance of the FFcreator
import path from 'path';
import { FFScene, FFImage, FFCreator } from 'ffcreatorlite';
const CANVAS_WIDTH = 1246; // play with the dimensions. I am creating a 16:9 canvas for youtube videos
const CANVAS_HEIGHT = 700;
const VIDEO_DURATION = 30;
const getCreatorInstance = () => {
const outputDir = path.join(__dirname, '../assets/output/'); // you can add anything
const cacheDir = path.join(__dirname, '../assets/cache/');
return new FFCreator({
cacheDir,
outputDir,
width: CANVAS_WIDTH,
height : CANVAS_WIDTH,
});
}
Now add a function for adding the Audio:
const addAudio = (creator: FFCreator) => {
const audio = `./source.mp3` // adding the audio
creator.addAudio(audio);
return creator
};
Another function to add the cover image:
addCoverImage = (creator: FFCreator) => {
const coverImagePath = './cover.png';
const scene = new FFScene();
scene.setDuration(VIDEO_DURATION);
const backgroundImage = new FFImage({
path: coverImagePath,
x: 0,
y: 0,
});
scene.addChild(backgroundImage);
creator.addChild(scene);
return creator
};
Let’s Combine Them All!
Now let’s combine these functions to create our video file from the audio file.
const generateVideoFromAudioFile = async (): Promise<string> => {
return new Promise((resolve, reject) => {
let creator = getCreatorInstance();
creator = addAudio(creator);
creator = addCoverImage(creator);
creator.start();
creator.closeLog();
creator.on('start', () => {
console.log(`FFCreator start`);
});
creator.on('error', (e: any) => {
console.log(`FFCreator error: ${e.error}`);
reject(e);
});
creator.on('progress', (e: any) => {
console.log(`FFCreator progress: ${(e.percent * 100) >> 0}%`);
});
creator.on('complete', async (e: any) => {
console.info(`FFCreator completed: \n USEAGE: ${e.useage} \n PATH: ${e.output} `);
resolve(e.output);
});
});
};
The syntax is a little weird because of the structure of the ffcreatorlite
library, but what this essentially does:
1. Creates a creator instance
2. Adds a audio
3. Adds a cover image
4. Starts the process and wait's for it's completion
5. after completing returns the generated video file path
So, now you can run the function like the following:
await generateVideoFromAudioFile();
And after everything is finished, you will see a generated video file randomid.mp4 inside your project, which you can use any way you like.
Final Thoughts
I have shown a minimal use case that is possible to do with this awesome library. There are a lot of things that you can do with ffcreatorlite
and ffcreator
library like adding multiple images with transition and everything.
I encourage you to try that.
That’s it for today. Have a great day!