Getting Started with FFmpeg in Node.js

Installing FFmpeg and Node.js Bindings

Note: FFmpeg must be installed on your system and accessible in your PATH.

# On Mac
brew install ffmpeg

# On Ubuntu
sudo apt install ffmpeg

# Node.js bindings (choose one)
npm install fluent-ffmpeg        // Most popular wrapper
npm install ffmpeg-static        // Cross-platform static binaries

Basic FFmpeg Usage with fluent-ffmpeg

Convert a Video Format


const ffmpeg = require('fluent-ffmpeg');

ffmpeg('input.mp4')
  .output('output.avi')
  .on('end', () => console.log('Conversion finished'))
  .on('error', (err) => console.error('Error:', err))
  .run();

Basic Methods in fluent-ffmpeg

.input()

Sets the input source.

ffmpeg().input('video.mp4')

.output()

Sets the output file path.

.output('output.avi')

.run()

Starts the FFmpeg process.

.run()

.save(path)

Shortcut for setting output and running the process.

.save('result.mp4')

.format(format)

Specifies the output format (e.g. 'mp4', 'avi').

.format('mp4')

.videoCodec(codec)

Sets the video codec to be used (e.g. 'libx264').

.videoCodec('libx264')

.audioCodec(codec)

Sets the audio codec (e.g. 'aac', 'copy').

.audioCodec('aac')

.addOptions(options[])

Adds custom FFmpeg options.

.addOptions(['-preset fast', '-crf 22'])

Event Hooks

.on('start', callback)

Triggered when FFmpeg starts processing.

.on('progress', callback)

Triggered with progress info. Useful for monitoring.


.on('progress', (progress) => {
  console.log('Processing: ' + progress.percent + '% done');
});

.on('end', callback)

Triggered after FFmpeg completes successfully.

.on('error', callback)

Triggered when an error occurs.

Parameter Explanation

Common FFmpeg CLI Parameters Used in Node

  • -i: Input file path
  • -c:v: Video codec
  • -c:a: Audio codec
  • -r: Frame rate (e.g. -r 30)
  • -s: Size/resolution (e.g. -s 1280x720)
  • -preset: Encoding speed/quality (e.g. -preset fast)
  • -crf: Quality setting (18–28, lower is better)
  • -vf: Video filters (e.g. -vf "scale=640:360")
  • -t: Duration (e.g. -t 00:01:00)
  • -ss: Start time (e.g. -ss 00:00:05)

With fluent-ffmpeg


ffmpeg('input.mp4')
  .setStartTime('00:00:05')    // .setStartTime
  .duration('00:00:10')        // .duration
  .videoFilters('scale=640:360')
  .addOption('-crf', '23')
  .save('output.mp4');

Using ffmpeg-static with child_process

This approach gives full access to FFmpeg commands using raw CLI syntax.


const { spawn } = require('child_process');
const ffmpegPath = require('ffmpeg-static');

const ffmpeg = spawn(ffmpegPath, [
  '-i', 'input.mp4',
  '-c:v', 'libx264',
  '-preset', 'fast',
  '-crf', '23',
  'output.mp4'
]);

ffmpeg.stderr.on('data', data => console.error(data.toString()));
ffmpeg.on('exit', code => console.log('FFmpeg exited with code', code));

Conclusion and Resources

FFmpeg in Node.js is powerful for building media servers, converters, thumbnailers, etc. Use fluent-ffmpeg for convenience, or ffmpeg-static + spawn for full control.

Extract Audio


ffmpeg('video.mp4')
  .noVideo()
  .audioCodec('copy')
  .save('audio.aac');

Screenshot from Video


ffmpeg('video.mp4')
  .screenshots({
    timestamps: ['50%'],
    filename: 'thumbnail.png',
    folder: './screenshots'
  });

Advanced Operations

Adding Filters (e.g. Grayscale)


ffmpeg('input.mp4')
  .videoFilters('hue=s=0') // Grayscale filter
  .save('gray_output.mp4');

Combining Video and Audio


ffmpeg()
  .input('video.mp4')
  .input('audio.mp3')
  .outputOptions('-c:v copy')
  .outputOptions('-c:a aac')
  .save('combined.mp4');

Transcoding with Custom Codecs


ffmpeg('input.mov')
  .videoCodec('libx264')
  .audioCodec('aac')
  .format('mp4')
  .save('output.mp4');

Useful Tips

Getting FFmpeg Info


ffmpeg.ffprobe('video.mp4', function(err, metadata) {
  console.dir(metadata); // Lists streams, format, etc.
});

Using ffmpeg-static


const ffmpegPath = require('ffmpeg-static');
const { spawn } = require('child_process');

const ff = spawn(ffmpegPath, ['-i', 'input.mp4', 'output.avi']);
ff.stdout.on('data', (data) => console.log(data.toString()));

Best Practices and Resources

Best Practices

Resources