Back to roadmaps ffmpeg Course

Project: Automated Video Thumbnail Generator

In this project, we will write a Node.js utility that extracts a specific frame from any video file and saves it as a JPEG thumbnail image. This is useful for generating preview images for video content management systems.


1. The FFmpeg Frame Extraction Command

To extract a single frame at a specific timestamp (for example, at the 5-second mark), use:

# Extract one frame at 00:00:05 and save as JPEG
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 thumbnail.jpg
  • -ss 00:00:05: Seek to the 5-second position.
  • -vframes 1: Extract only one video frame.

2. Building the Node.js Thumbnail Generator

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

const OUTPUT_DIR = './thumbnails';

if (!fs.existsSync(OUTPUT_DIR)) {
  fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}

function generateThumbnail(videoPath, timestamp = '00:00:05') {
  return new Promise((resolve, reject) => {
    const videoName = path.basename(videoPath, path.extname(videoPath));
    const outputPath = path.join(OUTPUT_DIR, `${videoName}.jpg`);

    const ffmpegArgs = [
      '-i', videoPath,
      '-ss', timestamp,
      '-vframes', '1',
      '-q:v', '2', // High quality JPEG (1 is best, 31 is worst)
      outputPath,
    ];

    execFile('ffmpeg', ffmpegArgs, (error) => {
      if (error) {
        reject(new Error(`Failed to generate thumbnail: ${error.message}`));
        return;
      }
      console.log(`Thumbnail saved: ${outputPath}`);
      resolve(outputPath);
    });
  });
}

// Example usage
generateThumbnail('./uploads/demo_video.mp4', '00:00:08')
  .then(thumbPath => console.log('Generated at:', thumbPath))
  .catch(console.error);

3. Batch Processing Multiple Videos

To generate thumbnails for all videos in a directory:

async function batchThumbnails(directory) {
  const files = fs.readdirSync(directory).filter(f => /\.(mp4|mov|mkv)$/.test(f));
  for (const file of files) {
    await generateThumbnail(path.join(directory, file));
  }
}
Published on Last updated: