Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use -ss to choose the start, then choose -t for a duration or -to for an absolute end time. For one still, add -frames:v 1. For regular sampling, use the fps filter; to keep every frame whose timestamp falls in a range, use select='between(t,start,end)'.

For example, this saves one frame per second from 01:00 through the next 10 seconds:

ffmpeg -ss 00:01:00 -i input.mp4 -t 00:00:10 -vf fps=1 -fps_mode passthrough frames_%04d.png

Choose the command that matches your time range

FFmpeg has two different meanings for the second boundary. -t is a length measured from the selected start, while -to is an absolute position in the input. They are mutually exclusive; if both are supplied, -t takes priority.

Goal Command pattern What it means
One screenshot -ss start -frames:v 1 Seek to the start and write one video frame.
Every second for a fixed duration -ss start -t duration -vf fps=1 Generate one output frame each second for the requested duration.
Every second until an absolute end -ss start -to end -vf fps=1 Use clock positions in the input, such as 01:00 through 01:10.
Every source frame in a timestamp interval -vf "select='between(t,start,end)'" Keep frames whose presentation time is inside the interval.

Replace input.mp4 with your file name. The output pattern frames_%04d.png creates files such as frames_0001.png and frames_0002.png.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Take one screenshot at a time

Fast seek

Put -ss before -i when you want a quick seek:

ffmpeg -ss 00:01:00 -i input.mp4 -frames:v 1 screenshot.png

This is usually fast because FFmpeg seeks to a nearby seek point and decodes forward. It may not be the exact requested presentation timestamp: in most formats, seeking cannot land exactly and FFmpeg chooses the closest seek point before the target.

Precision-oriented seek

For a frame that must be checked at the requested time, place -ss after the input:

ffmpeg -i input.mp4 -ss 00:01:00 -frames:v 1 screenshot.png

This decodes from the beginning (or from an earlier point selected by the demuxer) and then applies the seek, so it can be considerably slower on long files. Inspect the resulting image when an exact visual state matters, and adjust the timestamp if the source’s frame boundaries do not line up with your decimal value.

Fractional seconds

FFmpeg accepts decimal seconds, so these are valid:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ffmpeg -ss 60.5 -i input.mp4 -frames:v 1 half_second.png
ffmpeg -i input.mp4 -ss 00:01:00.500 -frames:v 1 half_second.png

The source still determines the available precision. A low-frame-rate or variable-frame-rate file may not contain a frame exactly at 60.500 seconds.

Extract one frame every second between two times

Duration-based range with -t

To sample from 01:00 for 10 seconds, use:

ffmpeg -ss 00:01:00 -i input.mp4 -t 00:00:10 -vf fps=1 -fps_mode passthrough frames_%04d.png

The fps=1 filter sets the output rate to one frame per second. Because -t is a duration, the interval starts at 01:00 and runs for 10 seconds.

Absolute end with -to

When your requirement is “from 01:00 through 01:10,” express both positions:

ffmpeg -ss 00:01:00 -i input.mp4 -to 00:01:10 -vf fps=1 -fps_mode passthrough frames_%04d.png

Do not add -t to this command. The two options are mutually exclusive, and FFmpeg gives -t priority if both appear.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a different cadence

Set fps to the number of output frames per second. For two frames per second over 10 seconds:

ffmpeg -ss 00:01:00 -i input.mp4 -t 00:00:10 -vf fps=2 -fps_mode passthrough frames_%04d.jpg

Use an output extension that matches the image format you want. PNG is lossless; JPEG is smaller but introduces compression.

Keep every frame whose timestamp is in the interval

fps creates a regular sampling cadence. If instead you need every source frame from 60 through 70 seconds, use the select filter:

ffmpeg -i input.mp4 -vf "select='between(t,60,70)'" -fps_mode passthrough frames_%04d.png

The expression evaluates each frame’s timestamp in seconds. between(t,60,70) retains frames at or between those bounds. This can decode much more of the input than an input seek, especially when the range is late in a long video.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why -fps_mode passthrough matters

Selected frames are not evenly spaced. -fps_mode passthrough tells the output to preserve their timing instead of duplicating or dropping frames to fit a constant-rate stream. On older FFmpeg builds, the equivalent spelling is -vsync 0:

ffmpeg -i input.mp4 -vf "select='between(t,60,70)'" -vsync 0 frames_%04d.png

Understand timestamps, keyframes and “early” screenshots

Input seeking with -ss before -i is a performance optimization, not a guarantee that decoding begins on the exact requested frame. Compressed video generally permits random access only at keyframes. FFmpeg seeks to the closest seek point before the requested position, then decodes forward. The first image written can therefore look slightly earlier than your timestamp.

  • Use input seeking (-ss before -i) for speed when a nearby frame is acceptable.
  • Use output seeking (-ss after -i) when visual precision is more important than speed.
  • For auditing or frame-accurate work, decode and select the range, then inspect the output rather than assuming a keyframe boundary.
  • With variable-frame-rate material, trust the frame timestamps, not a simple frame-number calculation.

Output naming, formats and overwrite behavior

Numbered image sequences

Use a printf-style sequence in the output name:

ffmpeg -ss 00:01:00 -t 00:00:10 -i input.mp4 -vf fps=1 frames_%04d.png

%04d pads numbers to four digits. Increase the width for larger batches, for example %06d.

Prevent accidental overwrites

FFmpeg asks before replacing an existing file. Add -y for unattended jobs that should overwrite, or -n to fail instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ffmpeg -y -ss 00:01:00 -i input.mp4 -frames:v 1 screenshot.png

Control image quality

For JPEG output, set the image quality with the JPEG-specific option:

ffmpeg -ss 00:01:00 -i input.mp4 -frames:v 1 -q:v 2 screenshot.jpg

Lower JPEG quantizer values generally mean higher quality and larger files. PNG does not use this JPEG quality scale.

Performance and reliability decisions

When speed wins

Use input seeking, a narrow range, and a low fps value when producing previews or contact sheets. A keyframe-near seek avoids decoding the entire file.

When accuracy wins

Use output seeking or select when the exact visual state is part of the result. Expect more decoding work, especially for long-GOP codecs and ranges near the end of a file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check the source before extraction

  • Confirm that the requested end is inside the actual duration.
  • Check whether the file is variable-frame-rate, interlaced or damaged.
  • Use a timestamp with decimals only when the source has enough temporal resolution to distinguish it.
  • Choose an output directory with enough space; extracting every frame can create thousands of images quickly.

Troubleshooting common failures

No images are produced

The start may be beyond the file duration, the input may contain no video stream, or the output pattern may point to an unwritable directory. Try a known-good time near the beginning, verify the path, and inspect FFmpeg’s stream information in its console output.

The first image is before the requested time

This is normally keyframe-based input seeking. Move -ss after -i, or decode and use select for timestamp-driven extraction.

The command stops earlier than expected

Check whether you used -t as a duration when you intended an absolute end. For 01:00 to 01:10, use -to 00:01:10, not -t 00:01:10. Also make sure the input really runs past the requested end.

Too many or too few files

fps=N generates a cadence; it does not mean “every original frame.” Use select='between(t,start,end)' for every source frame, and confirm the range’s boundary behavior if a frame exactly at the end matters.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Images look duplicated or timing changes

The output synchronizer may be inserting or dropping frames. Add -fps_mode passthrough (or -vsync 0 on older versions) when preserving selected-frame timing.

Shell quoting errors

The select expression contains quotes that shells interpret. In a POSIX shell, wrap the complete filter in double quotes as shown. In Windows PowerShell or Command Prompt, adjust quoting for that shell and keep the expression as one argument.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If the source is a web page rather than a local video, ScreenshotNeo returns a screenshot or PDF through one HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

Use the same one-call pattern from the ScreenshotNeo documentation:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Sign up for the free ScreenshotNeo plan.

FAQ

Can I use a frame number instead of a timestamp?

You can, but timestamps are safer across variable-frame-rate files. A frame number does not map consistently to seconds unless the source has a stable, known frame rate.

Does -to include the frame exactly at the end?

Boundary inclusion depends on the available frame timestamps and the filters or muxer in use. If the endpoint is critical, inspect the final extracted timestamp rather than relying on a visual assumption.

Can FFmpeg write WebP screenshots?

Yes, when your FFmpeg build includes a WebP encoder; use a .webp output name and confirm encoder support in the build’s capabilities.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can I use a frame number instead of a timestamp?

You can, but timestamps are safer across variable-frame-rate files. A frame number does not map consistently to seconds unless the source has a stable, known frame rate.

Does -to include the frame exactly at the end?

Boundary inclusion depends on the available frame timestamps and the filters or muxer in use. If the endpoint is critical, inspect the final extracted timestamp rather than relying on a visual assumption.

Can FFmpeg write WebP screenshots?

Yes, when your FFmpeg build includes a WebP encoder; use a .webp output name and confirm encoder support in the build’s capabilities.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.