How to Use FFmpeg with Node.js and Docker

Mohammad Faisal - Jul 9 '22 - - Dev Community

To read more articles like this, visit my blog

How to work with Audio and Video files in Node.js easily

Today we will learn how we can use FFmpeg with Node.js inside a Docker container.

Background

Usually, when we are running a Node.js application, all of the required parts for that application are inside the npm packages which go inside the node_modules folder.

However, for some specific use cases, we need to access the OS-level applications which makes it a little bit complicated.
One good example of this is FFmpeg which is described in their documentation as:
https://ffmpeg.org/

A complete, cross-platform solution to record, convert and stream audio and video.

Long story short, if you need to work with audio and video conversion or modification, you will need this.

The problem

The problem is FFmpeg is not any npm module that you can just install and use. There are some libraries on top of the FFmpeg like ffcreator and fluent-ffmpeg which create an abstraction on top of FFmpeg but you will still need FFmpeg installed on the OS level.

So, to resolve the problem, one easy solution is to install FFmpeg on the server where you are running your application.

But in modern days, we hardly directly use the hardware. Because whenever you need a new server, you will need to install it again.

Which is repetitive and boring right?

The Solution

The easier approach is to bundle your application with FFmpeg installed inside a Docker image which makes it really easy to distribute and your application is now sharable and reproducible!

But how exactly do you do that? It's really simple. On top of your base image, you will run the commands for installing FFmpeg and that’s it!

Below is a working Dockerfile that does the trick.

FROM node:16-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

## following 3 lines are for installing ffmepg
RUN apk update
RUN apk add
RUN apk add ffmpeg

COPY . .

EXPOSE 4000

RUN npm run build

CMD [ "node", "dist/src/index.js" ]
Enter fullscreen mode Exit fullscreen mode

So, the 3 lines in the middle install the FFmpeg inside your Node.js Alpine base image.

RUN apk update
RUN apk add
RUN apk add ffmpeg
Enter fullscreen mode Exit fullscreen mode

Note: We are using apk add because at the top, we chose the node:16-alpineversion of node (which is smaller in size).

If you are using a proper Node.js image like node:16, then the commands to install FFmpeg will be like the following:

RUN apt update
RUN apt install ffmpeg
Enter fullscreen mode Exit fullscreen mode

That should do the trick.

Alternative

The above approach works for Node.js and Docker images. But if you want to deploy your Node.js application using AWS Lambda or Google Cloud Functions, then it will create some problems.

To avoid that, there is another approach. We can use an npm package called ffmpeg-static.

Inside your project:

npm install --save ffmpeg-static
Enter fullscreen mode Exit fullscreen mode

It will download the binary files and store them inside the node_modules folder. From your application, you have to point the path to the binary files inside the node_modules folder.

You can get the path in the following manner:

var pathToFfmpeg = require('ffmpeg-static');
console.log(pathToFfmpeg);
Enter fullscreen mode Exit fullscreen mode

Then you can export it as a path.

ENV PATH="/your/path/to/node_modules/ffmpeg-
static/bin/linux/x64:${PATH}"
Enter fullscreen mode Exit fullscreen mode

That’s how you can achieve that. This particular thread is useful.
https://stackoverflow.com/questions/50693091/ffmpeg-install-within-existing-node-js-docker-image

That’s it for today. Have a great day!

Resources:
https://stackoverflow.com/questions/50693091/ffmpeg-install-within-existing-node-js-docker-image

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .