To extract frames from a video with FFmpeg, you run a single command that names the input file, picks frames using a time argument or a video filter, and writes each image to a numbered output filename; the canonical pattern for one frame per second is ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png, and for a single still at a chosen time it is ffmpeg -i input.mp4 -ss 00:00:05 -frames:v 1 output.png. FFmpeg reads the source container, decodes the matching frames, and saves each one using the format implied by the output extension, which is most commonly PNG, JPG, or BMP. The decoded frame keeps the source's pixel dimensions unless a scale filter is added to the chain, and timestamps are resolved against the nearest decodable frame because FFmpeg seeks to keyframes rather than to exact packet positions. That single behavior, seek-to-keyframe plus optional frame selection, is what every variant in this guide builds on, and the rest of the article walks through the four most useful patterns, the limits to keep in mind, and a no-install browser alternative for one-off PNGs.

extract frames from video ffmpeg
extract frames from video ffmpeg

Common FFmpeg Commands to Extract Frames

FFmpeg's frame-extraction commands share a structure: an input flag, an optional seek or filter that selects which frames to decode, and an output pattern that names each image. The four patterns below cover the cases most readers need, and each one writes valid PNGs, JPGs, or BMPs depending on the file extension you choose.

GoalFFmpeg commandOutput behavior
Pull one still at a known timeffmpeg -i input.mp4 -ss 00:00:12.5 -frames:v 1 output.pngWrites a single PNG sized to the decoded frame
Extract one frame per secondffmpeg -i input.mp4 -vf fps=1 frame_%04d.pngWrites frame_0001.png, frame_0002.png, and so on
Capture a time rangeffmpeg -ss 00:00:10 -i input.mp4 -t 5 -vf fps=2 range_%03d.pngWrites ten PNGs named range_001.png through range_010.png
Save every Nth source frameffmpeg -i input.mp4 -vf "select='not(mod(n,30))'" -vsync 0 frame_%04d.pngWrites every 30th frame by source frame counter

The fps filter and the select filter do most of the heavy lifting. fps=1 resamples the timeline at one frame per second, while select='not(mod(n,30))' uses the source frame counter to drop all but every 30th frame. The -frames:v 1 flag is the simplest single-still shortcut and tells FFmpeg to stop writing after the first decoded video frame, which is what makes the one-still command so compact. The -ss flag placed before -i does an input-side seek that is faster on large files, while the same flag after -i does a more precise output-side seek; for most frame-extraction tasks the pre-input position is good enough and saves time on long clips.

For more nuanced control, you can chain filters. A command like ffmpeg -i input.mp4 -vf "fps=1,scale=1280:-1" frame_%04d.png resamples to one frame per second and scales each frame to a width of 1280 pixels while preserving the aspect ratio through the -1 placeholder. That pattern is useful when you need thumbnails or smaller reference stills and do not want to write a separate scaling step.

Picking the Right Time in Seconds

FFmpeg accepts time values in three formats: integer or decimal seconds (12, 12.5), the hh:mm:ss form (00:00:12.500), and a millisecond variant on supported builds. Decimal seconds are the most readable for single-frame pulls because you can write -ss 12.5 instead of -ss 00:00:12.500, and the result is the same.

The position of -ss changes the meaning slightly. Placed before -i, it is a fast input seek that jumps to the nearest keyframe at or before the requested time and then decodes forward, which is fast but can land a few frames off the exact target. Placed after -i, it is a precise output seek that scans from the start of the decoded stream to the requested time, which is slower but lands closer to the chosen point. For batch extraction with fps=1 the difference is usually invisible because every frame in the range is written anyway; for a single -frames:v 1 still it can mean the difference between the exact frame you wanted and the previous keyframe.

If you are deciding which timestamp to type in, the guide on picking the right time when extracting frames walks through how to scrub a video in a player first and read the timestamp from the scrubber so that the FFmpeg -ss value matches the frame you actually see on screen.

How to Extract a Single PNG Frame in Your Browser

If you need one still from a short clip and you do not want to install FFmpeg or open a terminal, the Video Frame Extractor runs the same job in the current tab. The browser decodes the local file, seeks to the time you type, draws the decoded frame onto a canvas, and encodes a PNG for download. Nothing leaves your machine, which matters when the clip is private or work-restricted.

  1. Choose one supported local video (MP4, WebM, MOV, M4V, or Ogg) and wait for its duration and preview to load.
  2. Enter a frame time in moments between zero and the displayed duration, using decimals when the frame falls between whole seconds (for example, 12.5 for the frame at twelve and a half seconds in).
  3. Select Extract PNG frame, verify the still shown in the preview matches the moment you wanted, and download the PNG that the tool saves locally.

The PNG filename includes the time you entered, so a request for 12.5 seconds produces something like frame-12.500.png in your downloads folder. Because the tool draws the frame at its decoded dimensions, the image is the same width and height as the source clip; nothing is resized, cropped, sharpened, or filtered along the way. Transparency is preserved only if the codec's decoded frame includes it, which is rare for typical MP4 and MOV files but possible with WebM sources that use an alpha channel.

Browser-side extraction shares the same precision caveat as FFmpeg: the requested time is a media-timeline position, not a guarantee of source-frame accuracy. The browser may land on a nearby decoded frame because of keyframes, variable frame rates, edit lists, and codec rounding, so the still you get may be a nearby decoded frame rather than the exact frame you intended. That is fine for thumbnails, references, and presentation stills, and the Video Frame Extractor page itself recommends switching to a dedicated desktop tool if you need frame-accurate editorial work.

The mechanics behind that flow are documented on MDN's pages for HTMLMediaElement currentTime and Canvas drawImage, which are the same browser APIs the tool uses to seek to the chosen timestamp and copy the decoded frame into the canvas before encoding it as PNG.

Limits and Codec Caveats That Affect Frame Extraction

FFmpeg will happily try to open almost any container or codec it has been compiled with, which is why it is the default choice for unusual formats such as MKV, AVI, ProRes, or DNxHR. A browser-based tool is much narrower: the Video Frame Extractor works only with MP4, WebM, MOV, M4V, and Ogg files that the browser can decode, and even a recognized file extension is no guarantee the codec inside the container is supported. An MP4 that holds H.264 video usually opens; an MP4 that holds ProRes or HEVC on a browser without a hardware decoder will not.

ConstraintFFmpegVideo Frame Extractor
Container supportAnything FFmpeg is compiled with, including MKV, AVI, ProRes, MOVMP4, WebM, MOV, M4V, Ogg that the browser codec stack can decode
File size capSet by your disk and memory500 MiB
Duration capSet by your disk and memory5 minutes
Pixel cap per sideNone at the command line4096 pixels
Resolution capNone at the command line3840 × 2160
Processing locationLocal binary on your machineLocal browser tab, no upload
Output format choicePNG, JPG, BMP, TIFF, RAW, and morePNG only

The shared video safety policy that caps the browser tool at 500 MiB and five minutes is there to keep the tab responsive; once a file exceeds those limits, decoding large frames into a canvas blocks the main thread and the tab can hang. FFmpeg has no such guardrail, which is one reason it remains the right choice for long-form footage, large 4K masters, and unusual codec combinations, while a browser tool is the right choice for a single clip under five minutes that you want to keep off a server.

When to Use FFmpeg vs a Browser Tool

The decision usually comes down to three questions: how many frames do you need, how long is the source, and does the file already open in your browser. If you need hundreds or thousands of frames from a long clip, FFmpeg is a sensible option because the command line scales without manual work and the fps filter handles the cadence for you. If you need one still from a clip under five minutes that already opens in your browser, the Video Frame Extractor saves the install step and the command-line syntax.

There is also a middle case: you have a long file, but you only want a single still at a known time. For that case you can run FFmpeg with -ss before -i and -frames:v 1 and stop after the first image is written, which is roughly the same amount of work as opening the browser tool and skipping the upload step. The tradeoff is that the FFmpeg version runs on your machine's CPU and disk and does not depend on whether the browser can decode the file, while the browser version does not touch your disk at all beyond the final PNG.

A useful rule of thumb: FFmpeg when the codec is unusual, the clip is long, or you need many frames at once; the browser tool when you want one PNG quickly from a short clip you already trust your browser to play.

Output Quality, Format, and Transparency

PNG is the right format when the still will be edited, overlaid on a slide, or composited with another image because PNG is lossless and supports an alpha channel. JPG is the right format when the still is going into a document or a web page and file size matters more than lossless quality. BMP is rarely the right choice today, but FFmpeg supports it as an output extension for legacy pipelines.

The pixel dimensions of the output match the decoded frame. FFmpeg does not resize, crop, or filter the frame unless you add a scale or crop filter, and the browser tool explicitly does not resize, crop, sharpen, interpolate, or apply filters either. If you need a smaller version, FFmpeg's -vf "scale=W:-1" chain is the cleanest way to do it in one pass.

Transparency is the one subtle case. PNG supports an alpha channel, but the decoded frame only carries alpha if the source codec produces it; H.264 video in an MP4 almost never does, while WebM with VP8 or VP9 plus an alpha track does. The browser tool preserves transparency only if the decoded frame includes it.

Troubleshooting Failed Extractions

Empty downloads and failed decodes have a small set of usual causes. In FFmpeg, an "Invalid data found when processing input" error usually means the container is recognized but the codec inside is not, and the fix is to install or enable the codec or to remux the file with a tool like VLC. In the browser tool, the same situation surfaces as a decode error rather than an empty PNG, and the fix is to re-encode the clip with a browser-supported codec such as H.264 for MP4 or VP9 for WebM before retrying.

If the still lands on the wrong frame, the fix is the same in both tools: add a small offset to the time value or scrub the video in a player first to find the closest whole-second or half-second marker that lands on the frame you wanted. FFmpeg's -noaccurate_seek flag and the browser's display of the requested time are both signals that the decoded position is approximate, and the eight time fixtures the browser tool uses internally cover the start, millisecond values, fractional seconds, ordinary seconds, frame-rate-style decimals, one minute, and the maximum duration boundary for the same reason.

Files that exceed the browser tool's 500 MiB or five-minute limits are rejected before decoding starts, which is the desired behavior because a tab that locks up on a 10 GB file is worse than a clear error message. For those cases the fix is to trim or downscale the source with a tool such as the Video Trimmer or Video Resizer before extracting frames, or to switch to FFmpeg where the same limits do not apply.