Node.js FFmpeg Integration via Standard I/O

This article explains how to build a Node.js application that interfaces directly with the FFmpeg binary using standard input (stdin) and standard output (stdout) streams. By leveraging Node.js’s native child_process module, you can pipe media data into FFmpeg for processing and receive the output stream in real-time, eliminating the need to write temporary files to disk.

Prerequisites

To follow this guide, you must have Node.js installed on your system, along with the FFmpeg binary. Ensure that FFmpeg is added to your system’s PATH environmental variable so it can be executed from the command line.

Spawning the FFmpeg Process

Node.js provides the child_process module to run system commands. To redirect standard I/O, you use the spawn function.

When configuring FFmpeg for standard I/O: * Use pipe:0 (or just -) to tell FFmpeg to read input data from the stdin stream. * Use pipe:1 (or just -) at the end of the argument list to tell FFmpeg to write the output data to the stdout stream. * Specify the output container format explicitly using the -f flag, as FFmpeg cannot auto-detect the format from a stream pipe.

Implementation Example

The following code demonstrates how to stream an input video file (input.mp4), pipe it into FFmpeg to extract the audio, convert it to MP3 format, and write the resulting audio stream directly to an output file (output.mp3).

const { spawn } = require('child_process');
const fs = require('fs');

// Create readable and writable file streams
const inputStream = fs.createReadStream('input.mp4');
const outputStream = fs.createWriteStream('output.mp3');

// Spawn the FFmpeg process
const ffmpeg = spawn('ffmpeg', [
  '-i', 'pipe:0',      // Read input from stdin
  '-f', 'mp3',         // Force output format to MP3
  '-ab', '192k',       // Set audio bitrate
  'pipe:1'             // Write output to stdout
]);

// Pipe the input stream into FFmpeg's stdin
inputStream.pipe(ffmpeg.stdin);

// Pipe FFmpeg's stdout into the output file stream
ffmpeg.stdout.pipe(outputStream);

// FFmpeg writes logs, progress, and errors to stderr
ffmpeg.stderr.on('data', (data) => {
  console.log(`FFmpeg progress/log: ${data.toString()}`);
});

// Handle stream errors
ffmpeg.stdin.on('error', (err) => {
  console.error('FFmpeg stdin error:', err.message);
});

ffmpeg.stdout.on('error', (err) => {
  console.error('FFmpeg stdout error:', err.message);
});

// Handle process completion
ffmpeg.on('close', (code) => {
  if (code === 0) {
    console.log('FFmpeg processing completed successfully.');
  } else {
    console.error(`FFmpeg process exited with code ${code}`);
  }
});

Key Considerations