How to Create Video Contact Sheets with FFmpeg

This guide explains how to use the FFmpeg tile video filter to generate a contact sheet—a single image grid containing thumbnail previews of video frames. You will learn the essential command syntax, how to space out frame extraction, and how to customize the layout, size, and appearance of your final output grid.

The Standard Contact Sheet Command

To create a functional contact sheet, you must combine frame rate reduction with the tile filter. Generating a tile grid from raw video without reducing the frame rate will result in a massive image containing consecutive, nearly identical frames.

The standard command structure is:

ffmpeg -i input.mp4 -vf "fps=1/10,scale=320:-1,tile=4x3" output.png

How the Command Works:

  • -i input.mp4: Specifies your input video file.
  • -vf: Introduces the video filtergraph chain.
  • fps=1/10: Extracts one frame every 10 seconds. Adjust this value based on video length (e.g., fps=1/60 for one frame per minute).
  • scale=320:-1: Resizes each individual thumbnail to a width of 320 pixels while automatically maintaining the original aspect ratio for the height.
  • tile=4x3: Arranges the extracted frames into a grid of 4 columns and 3 rows (holding up to 12 frames total).
  • output.png: The final contact sheet image file.

Customizing the Tile Filter

The tile filter offers several parameters to customize the layout, spacing, and background color of your contact sheet.

Parameter Syntax:

tile=columnsxrows:padding=pixels:margin=pixels:color=color_name

Configuration Options:

  • Grid Dimensions (columnsxrows): Defines the layout (e.g., 5x5 for 25 frames, 8x4 for 32 frames).
  • padding: Sets the pixel width of the borders between individual thumbnails inside the grid.
  • margin: Sets the outer pixel border around the entire sheet.
  • color: Sets the color of the padding and margin area (default is black). You can use standard color names or Hex codes.

Example with Custom Styling:

To create a 5x4 grid with 10 pixels of white padding and a 20-pixel outer margin:

ffmpeg -i input.mp4 -vf "fps=1/30,scale=240:-1,tile=5x4:padding=10:margin=20:color=white" contact_sheet.jpg

Tips for Best Results

  • Matching Grid Size to Video Length: Ensure your fps interval math matches your grid capacity. For a 2-minute video (120 seconds) using a 4x3 grid (12 frames), capture one frame every 10 seconds (fps=1/10).
  • Performance: Placing the scale filter before the tile filter in the chain drastically reduces memory usage, as FFmpeg scales the individual frames down before assembling them into the larger grid.