Back to roadmaps ffmpeg Course

Project: Automated Video Compression Pipeline in Node.js

In this project, we will build a Node.js script that watches an upload directory, automatically compresses any new video files using FFmpeg, and moves the output to a processed folder.


1. Using Child Process to Spawn FFmpeg

Node.js can call system commands using the built-in child_process module. We use spawn rather than exec because it streams output in real time, which is important for long-running FFmpeg processes:

// src/compress.js
const path = require('path');
const { spawn } = require('child_process');
const fs = require('fs');

const INPUT_DIR = './uploads';
const OUTPUT_DIR = './processed';

// Ensure output directory exists
if (!fs.existsSync(OUTPUT_DIR)) {
  fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}

function compressVideo(inputPath, outputPath) {
  return new Promise((resolve, reject) => {
    console.log(`Compressing: ${path.basename(inputPath)}`);
    
    const ffmpegArgs = [
      '-i', inputPath,
      '-c:v', 'libx264',
      '-crf', '26',
      '-preset', 'fast',
      '-c:a', 'aac',
      '-b:a', '128k',
      '-movflags', '+faststart', // Move metadata to start for faster web streaming
      outputPath,
    ];

    const ffmpegProcess = spawn('ffmpeg', ffmpegArgs);

    ffmpegProcess.stderr.on('data', (data) => {
      process.stdout.write('.'); // Print progress dots
    });

    ffmpegProcess.on('close', (exitCode) => {
      if (exitCode === 0) {
        console.log(`\nDone: ${path.basename(outputPath)}`);
        resolve(outputPath);
      } else {
        reject(new Error(`FFmpeg exited with code ${exitCode}`));
      }
    });
  });
}

// Process all video files in the uploads directory
async function processAll() {
  const files = fs.readdirSync(INPUT_DIR).filter(f => f.endsWith('.mp4'));
  
  for (const file of files) {
    const inputPath = path.join(INPUT_DIR, file);
    const outputPath = path.join(OUTPUT_DIR, file.replace('.mp4', '_compressed.mp4'));
    
    await compressVideo(inputPath, outputPath);
  }

  console.log('All videos processed.');
}

processAll().catch(console.error);

2. Running the Script

Place video files in the uploads/ folder and run:

node src/compress.js
Published on Last updated: