FFmpeg recipe
FFmpeg: Extract a Single Frame as a JPG
Combine -ss (seek) with -vframes 1 to grab one frame at a precise timestamp.
Command
ffmpeg -ss 00:00:10 -i input.mp4 -vframes 1 -q:v 2 -y thumbnail.jpgPrefer no terminal?
Use the Frame Extractor in your browser
What each flag does
| -ss | Seek to this timestamp (HH:MM:SS or seconds). Place BEFORE -i for fast keyframe seek; AFTER -i for sample-accurate seek. |
|---|---|
| -i | Input file. Can be a video, audio, or image. Repeat for multiple inputs. |
| -y | Overwrite output file without confirmation. |
| -vframes 1 | Output exactly one video frame. |
| -q:v 2 | JPEG quality (2 = highest). Range 1–31, lower = better. |
Notes & gotchas
- For PNG output (lossless), drop -q:v and use thumbnail.png.
- For multiple thumbnails at intervals, use -vf fps=1/30 to grab one frame every 30 seconds.
Check it worked
ffprobe -v error -show_entries stream=width,height -of csv=p=0 frame.pngThe full source resolution, since a frame grab should not be scaled.
What to change
| -ss before -i is fast, after is exact | Before the input seeks to the nearest keyframe instantly. After it decodes up to the timestamp and gives you that exact frame. |
|---|---|
| -q:v is JPEG quality, inverted | 2 is near-lossless and 31 is the worst. It is not a percentage, and higher is not better. |
| PNG for graphics | Swap the extension for .png when the frame is a screenshot or has text. JPEG artefacts around sharp edges are obvious. |
If it fails
The frame is black.
Why: The timestamp landed on a fade, or before the first decodable frame.
Fix: Move the timestamp a second later, and place -ss after -i for an accurate grab rather than a keyframe one.
Many images were written instead of one.
Why: Without -frames:v 1 or -vframes 1, FFmpeg keeps writing frames until the input ends.
Fix: Add -frames:v 1.