Learn how to create video sprites with just FFmpeg — perfect for lightweight video previews.
The following is an example of a video preview of the Big Buck Bunny video using a sprite sheet generated from Ffmpeg. Hover over the image to see the preview change.
Save the following shell script as sprite.sh
, and update the permissions so
you can execute it (ie. chmod +x ./sprite.sh
).
#! /usr/bin/bash
INPUT=$1
OUTPUT=$2
FRAMES=20
# Extract video duration in seconds
DURATION_S=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $INPUT)
# Calculate the FPS if we want to show 20 frames in our sprite sheet
FPS=$(echo "scale=8; $FRAMES / $DURATION_S" | bc)
# Generate the sprite sheet
ffmpeg \
-y \
-i "$INPUT" \
-frames 1 \
-q:v 2 \
-filter_complex "fps=$FPS,pad=width=max(iw\,ih*(16/9)):height=ow/(16/9):x=(ow-iw)/2:y=(oh-ih)/2,scale=-1:135:force_original_aspect_ratio=decrease,tile=1x$FRAMES" \
$OUTPUT
You can then run the script as follows:
./sprite.sh yourvideo.mp4 yourvideospritesheet.png
The ffmpeg command can be explained as follows:
-
-y
Override any existing output. -
-i "$INPUT"
The input file. -
-frames 1
Only output a single image (one frame). -
-q:v 2
Ouput quality, 0 is the best. -
-filter_complex
That's where all the magic happens.fps=$FPS
Set the desired FPS to extract the 20 frames from the entire length of the video.pad=width=max(iw\,ih*(16/9)):height=ow/(16/9):x=(ow-iw)/2:y=(oh-ih)/2
This pads the frame into a 16:9 aspect ratio and centres it.scale=-1:135:force_original_aspect_ratio=decrease
This scales the frame down to 240x135.tile=1x$FRAMES
Finally we tile our output vertically into this grid, 1 frame across, 20 frames down.
The final output image look as follows. Once combined with some basic CSS and JS, the scrubbing preview seen at the start of this article can be achieved.