Understanding frame extraction
One PNG per frame, or one every second.
What gets exported, the format choice for stills, and why "every Nth frame" is a more useful default than "every frame".
The operation.
Frame extraction reads a video stream, decodes each frame to a bitmap, writes it out as an image. The result is one image per output frame. For a 60-fps, 5-minute video, "every frame" is 18,000 PNG files — usually more than anyone wants. The useful version is "every Nth frame" or "one frame per second": a manageable number of representative stills.
A worked extraction.
Extract one frame per second from a 30-minute lecture recording. ffmpeg -i lecture.mp4 -vf fps=1 frames/frame-%04d.png — produces 1800 PNG files (frame-0001.png through frame-1800.png). For "every 5 seconds": fps=1/5, producing 360 files. For "one frame at a specific timestamp": ffmpeg -ss 00:01:30 -i lecture.mp4 -frames:v 1 out.png.
One per second
-vf fps=1
The fps filter decimates frames to a target rate.
30-min video → 1800 stills
= Manageable set
Single timestamp
-ss 00:01:30 -frames:v 1
Seek before decode, extract one frame, stop.
Sub-second runtime regardless of total video length
= One precise still
Format choice for the stills.
PNG is the safe default — lossless, every detail preserved, larger files. JPEG is smaller for photographic content and fine for stills you'll glance at, not edit. WebP is even smaller and supported by every modern browser; useful for contact-sheet generation. For pixel-level analysis (computer vision, before-and- after comparisons), stick to PNG; for quick visual scanning, JPEG or WebP is fine.
Seek before decode.
For a "one frame from minute 30 of a two-hour video" extraction, the question is whether to seek first or decode first. -ss before -i tells FFmpeg to seek the input to that timestamp before decoding — fast, but might land at a keyframe rather than the exact requested frame. -ss after -i decodes from the start and discards frames until the target — slow but frame-accurate. The former is almost always what you want for snapshot extractions.
Filename templates.
The output template uses C-style printf: frame-%04d.png means "four-digit zero-padded counter". Pad enough for the total count — five digits for up to 99,999 frames. Without padding, file listings sort wrong (frame-2.png comes after frame-10.png). Some pipelines want timestamps embedded in the filename instead — a custom filter is needed for that.
When you actually want every frame.
Computer vision pipelines, frame-by-frame animation work, super-resolution training data — these need every frame. The output count grows fast: a 1-minute 60fps 4K video is 3600 frames, each 4K PNG is ~10MB, total ~36GB. Plan for the storage; use a SSD; consider compressing the resulting frames into a tar afterward; or use a format like EXR that stores sequences compactly. For these use cases, the extraction step is the easy part.