To pull a single frame out of a video as a thumbnail, seek to a timestamp and tell ffmpeg to write one frame:
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 thumb.jpgThat grabs the frame at the five-second mark and writes it to thumb.jpg. The whole trick is the placement of -ss: putting it before -i makes ffmpeg seek the input by keyframe before it starts decoding, which is near-instant even on a two-hour file. -frames:v 1 then stops after the first decoded frame. The rest of this page is the variations: letting ffmpeg pick a representative frame for you, sampling one frame every N seconds, controlling JPEG quality, and scaling the output.
Grab a frame at a specific timestamp
The command above is the one you want most of the time. A few notes on the parts:
# Five seconds in, written as a JPEG
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 thumb.jpg
# Same idea, written as PNG (lossless, larger file)
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 thumb.png
# Seconds work too: 90 = 1:30
ffmpeg -ss 90 -i in.mp4 -frames:v 1 thumb.jpg-ss before -i is a fast input seek: ffmpeg jumps to the nearest keyframe at or before the timestamp, so it is quick but lands on a keyframe rather than the exact requested moment. For a thumbnail that almost never matters. When you need the frame at that exact time (frame-accurate), use two -ss flags: an input seek before -i to jump quickly to a keyframe a little before the target, then an output seek after -i to decode forward the remaining distance to the exact timestamp:
# Input-seek to ~4s (fast, keyframe), then decode forward 1s to land on exactly 5s
ffmpeg -ss 00:00:04 -i in.mp4 -ss 00:00:01 -frames:v 1 thumb.jpgThe two add up to the target time (4s + 1s = 5s), so you get the speed of input seeking plus the frame accuracy of an output seek. Accurate seeking is on by default; pass -noaccurate_seek to turn it off. For a single still this is overkill, but it is the pattern to reach for when the precise frame matters.
Let ffmpeg pick a representative frame
If you do not have a timestamp in mind and just want a frame that looks like the video (not a black fade-in or a transition), use the thumbnail filter. It analyses a batch of frames and picks the one most representative of the set:
ffmpeg -i in.mp4 -vf "thumbnail" -frames:v 1 thumb.jpgBy default it considers 100 frames at a time and scores them against the batch average, so it tends to skip the near-black opening frames that a naive first-frame grab lands on. It is the right default for auto-generating a poster image when you cannot hand-pick the moment. You can widen the analysis window by passing a frame count, for example thumbnail=300, at the cost of a little more decoding.
Sample one frame every N seconds
For a series of stills (a storyboard, a set of preview images, the input for a contact sheet) use the fps filter with a fractional rate. fps=1/10 means one frame every ten seconds:
# One frame every 10 seconds, numbered shot-001.jpg, shot-002.jpg, ...
ffmpeg -i in.mp4 -vf "fps=1/10" shot-%03d.jpgThe %03d in the output name is a printf-style counter that ffmpeg fills in, zero-padded to three digits. Change the fraction to change the cadence: fps=1 is one frame per second, fps=1/60 is one per minute. Note that here -ss does not help much, because you are walking the whole file by design, so leave it off and let the filter sample across the entire duration.
If you want a fixed number of evenly spaced frames regardless of length, compute the rate from the duration, or reach for the thumbnail filter per segment. For a single tiled preview image, the tile filter pairs with fps to lay the samples out in a grid in one pass.
Control JPEG quality with -q:v
JPEG thumbnails default to a middling quality that can look soft. The -q:v flag (also spelled -qscale:v) sets the quality on a scale where lower is better: 1 is the best, 31 is the worst. For a crisp thumbnail, 2 is the standard choice:
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 -q:v 2 thumb.jpg-q:v 2 is the sweet spot for stills: visually near-lossless, still a reasonable file size. Drop to -q:v 1 if you want the absolute best and do not care about bytes. This flag only applies to lossy formats like JPEG; for PNG output it does nothing (PNG is already lossless), so save it for .jpg.
Scale the thumbnail
Resize while you extract by adding the scale filter. Use -1 for one dimension to preserve the aspect ratio:
# 320px wide, height auto to keep the aspect ratio
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 -vf "scale=320:-1" -q:v 2 thumb.jpgCombine it with the thumbnail filter by chaining them in one -vf chain (comma-separated, applied left to right):
ffmpeg -i in.mp4 -vf "thumbnail,scale=320:-1" -frames:v 1 -q:v 2 thumb.jpgIf a dimension comes out odd and your encoder complains, use -2 instead of -1 to round to the nearest even number, which some codecs require.
-frames:v versus -vframes
You will see both spellings in older guides. They do the same job for video, but -frames:v is the current form and -vframes is an obsolete alias:
# Current, preferred
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 thumb.jpg
# Old alias, still works but deprecated
ffmpeg -ss 00:00:05 -i in.mp4 -vframes 1 thumb.jpgPer the official documentation, -vframes is a deprecated alias and the stream-specifier form -frames:v is the one to use in new commands. Both stop writing after the given number of frames; reach for -frames:v so your commands age well.
FAQ
See also
- The ffmpeg command cheat sheet: every common operation (convert, crop, trim, compress) in one reference.
- Trim and cut a video with ffmpeg: the same fast
-ssseek, applied to clipping a segment without re-encoding. - Convert a video to a high-quality GIF with ffmpeg: the two-pass palette approach for a clean GIF instead of a single still.
Sources
Authoritative references this article was fact-checked against.
- ffmpeg documentation (official)ffmpeg.org
- ffmpeg filters documentation (official)ffmpeg.org




