Back to blog

How to Use FFmpeg to Extract Frames from Video (Creator's Guide)

How to Use FFmpeg to Extract Frames from Video

Sometimes you need a single frame from a video. Sometimes you need every frame. Sometimes you need one frame every 5 seconds for a time-lapse, or the exact moment a ball hits a bat for a thumbnail.

FFmpeg handles all of these, and while it has a learning curve, frame extraction is one of the simpler things you can do with it. Once you’ve got the commands down, it becomes a routine part of your toolkit.

What FFmpeg Is and Why You’d Use It

FFmpeg is a free, open-source multimedia framework that most video tools already use under the hood — including editors you probably work with daily. Running it directly gives you precise control over frame extraction without needing to click through a GUI.

Why it’s worth learning for frames:

  • Exact control over frame numbers, timestamps, and intervals
  • Batch processing across multiple files with a simple script
  • No quality loss — extract without recompression where possible
  • No watermarks or limitations — it’s free and open-source
  • Runs on everything — Mac, Windows, Linux, servers, CI pipelines

You’ll need FFmpeg installed first. On Mac: brew install ffmpeg. On Windows: download from ffmpeg.org or use winget install ffmpeg. On Linux: sudo apt install ffmpeg or your distro’s equivalent.

Extract a Single Frame

The most common use case: pulling one specific frame from a video file.

Extract the First Frame

ffmpeg -i input.mp4 -frames:v 1 frame.png

This takes the first frame of input.mp4 and saves it as frame.png.

  • -i input.mp4 — the input video file
  • -frames:v 1 — extract 1 video frame
  • frame.png — output filename (the extension determines format)

Extract a Frame at a Specific Timestamp

If you need a frame from 30 seconds into the video:

ffmpeg -ss 00:00:30 -i input.mp4 -frames:v 1 frame_at_30s.png

The -ss 00:00:30 flag seeks to 30 seconds before it starts processing. The timestamp format is HH:MM:SS, but you can also just use seconds directly: -ss 30.

Extract a Frame by Number

If you know the exact frame number you want (say, frame 1500):

ffmpeg -i input.mp4 -vf "select=eq(n\,1500)" -frames:v 1 frame_1500.png

This uses the select filter to grab that specific frame. Note that frame numbers start at 0.

Extract Frames at Regular Intervals

For thumbnails, reference images, or time-lapse sequences, you’ll often want one frame at a regular interval rather than a specific timestamp.

One Frame Every Second

ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png

The -vf fps=1 filter outputs 1 frame per second of video. The %04d in the output filename becomes a 4-digit number — so you get frame_0001.png, frame_0002.png, and so on.

One Frame Every 5 Seconds

ffmpeg -i input.mp4 -vf fps=1/5 frame_%04d.png

The fps=1/5 means “1 frame per 5 seconds of video.”

One Frame Every Minute

ffmpeg -i input.mp4 -vf fps=1/60 frame_%04d.png

This is useful for creating time-lapse reference images or quickly scanning through long footage without watching it.

Extract All Frames

To pull every single frame from a video:

ffmpeg -i input.mp4 frame_%04d.png

No -vf fps filter needed — FFmpeg outputs every frame by default when you give it an image output pattern.

Be careful with this one. A 60-second video at 30fps generates 1,800 PNG files. A 5-minute video generates 9,000. Make sure you have the storage space and that you actually need every frame before running it.

Control Output Quality and Format

The default PNG output is lossless — high quality but large files. You have options.

Output as JPEG (Smaller Files)

ffmpeg -i input.mp4 -frames:v 1 -q:v 2 frame.jpg

The .jpg extension tells FFmpeg to output JPEG, and -q:v 2 sets the quality level (2 is high quality, 31 is the lowest). For thumbnail generation where file size matters, JPEG is usually the better choice.

Output as High-Quality PNG

ffmpeg -i input.mp4 -frames:v 1 -compression_level 0 frame.png

Setting -compression_level 0 disables PNG compression for faster encoding. The files are larger, but the quality is identical.

Control Resolution

You can scale frames to a specific width as part of the extraction:

ffmpeg -i input.mp4 -vf fps=1,scale=640:-1 frame_%04d.png

The scale=640:-1 filter sets the width to 640px and calculates the height automatically to maintain the aspect ratio. This is useful for generating preview thumbnails or web-ready images without a separate resize step.

Extract Frames from Multiple Videos

If you need to pull frames from every video in a folder, a shell loop handles it cleanly.

Mac/Linux (Bash)

for f in *.mp4; do
  ffmpeg -i "$f" -ss 00:00:05 -frames:v 1 "${f%.mp4}_thumb.jpg"
done

This extracts a frame at 5 seconds from every MP4 file in the current directory and saves it as {filename}_thumb.jpg.

Windows (PowerShell)

Get-ChildItem *.mp4 | ForEach-Object {
  ffmpeg -i $_.Name -ss 5 -frames:v 1 "$($_.BaseName)_thumb.jpg"
}

Same concept — loop through the files, extract a frame from each, save with a new name.

Practical Use Cases

Generate Video Thumbnails

For building a video gallery or preview system:

ffmpeg -i video.mp4 -vf "select=not(mod(n\,300))" -vsync vfr -q:v 2 thumb_%04d.jpg

This extracts every 300th frame (roughly every 10 seconds for a 30fps video). The -vsync vfr flag prevents duplicate frames in the output.

Reference Frames from Multiple Takes

When you need quick comparison images to decide which take to use:

ffmpeg -i take01.mp4 -ss 5 -frames:v 1 take01_ref.jpg
ffmpeg -i take02.mp4 -ss 5 -frames:v 1 take02_ref.jpg
ffmpeg -i take03.mp4 -ss 5 -frames:v 1 take03_ref.jpg

Create a Time-Lapse from Video

Extract frames at intervals, then recompose them into a faster video:

ffmpeg -i long_video.mp4 -vf fps=1/10 timelapse_%04d.jpg

This gives you one frame every 10 seconds. Then reassemble into a video at whatever frame rate you want:

ffmpeg -framerate 30 -i timelapse_%04d.jpg -c:v libx264 timelapse.mp4

Pull a Frame for Social Sharing

When you need a specific moment from a video as a still image:

ffmpeg -ss 00:02:47 -i video.mp4 -frames:v 1 shareable_moment.jpg

Common Issues and Fixes

Frame Doesn’t Match the Timestamp You Expected

Placing -ss before -i seeks to the timestamp before decoding, which is faster but can be slightly imprecise (it snaps to the nearest keyframe). Placing it after -i decodes everything up to the timestamp first — slower but frame-accurate. For single frames, either approach usually works fine.

ffmpeg -ss 30 -i input.mp4 -frames:v 1 frame.png

Timestamp Not Found

If your timestamp is beyond the video’s duration, FFmpeg produces no output without any helpful error message. Check the duration first:

ffmpeg -i input.mp4

The duration will appear in the output metadata.

Output Files Overwriting Each Other

The %04d pattern in the output filename is critical when extracting multiple frames. Without it, FFmpeg overwrites the same file for every frame it extracts. Always use a numbered pattern for sequences:

  • %04d — 4-digit numbers (0001, 0002, …)
  • %03d — 3-digit numbers (001, 002, …)

JPEG Quality Too Low

Use -q:v 2 for high-quality JPEG output. The range is 2-31, where lower numbers mean higher quality. If file size isn’t a concern, switch to PNG for lossless output.

Quick Reference

# First frame
ffmpeg -i input.mp4 -frames:v 1 frame.png

# Frame at specific time
ffmpeg -ss 00:00:30 -i input.mp4 -frames:v 1 frame.png

# Frame at frame number
ffmpeg -i input.mp4 -vf "select=eq(n\,1500)" -frames:v 1 frame.png

# Every second
ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png

# Every 5 seconds
ffmpeg -i input.mp4 -vf fps=1/5 frame_%04d.png

# All frames
ffmpeg -i input.mp4 frame_%04d.png

# Thumbnail from every video in folder
for f in *.mp4; do ffmpeg -i "$f" -ss 5 -frames:v 1 "${f%.mp4}_thumb.jpg"; done

# JPEG with quality control
ffmpeg -i input.mp4 -frames:v 1 -q:v 2 frame.jpg

# Scaled to width
ffmpeg -i input.mp4 -vf fps=1,scale=640:-1 frame_%04d.png

FFmpeg isn’t the most intuitive tool, but for frame extraction it’s hard to beat. Once you know the handful of commands you actually need, save them in a script file or a notes doc. Thumbnail generation, reference frames, time-lapse assembly — it all becomes a few seconds of typing instead of clicking through menus in a GUI you don’t need.

VioletFlare turns raw footage into beat-synced reels, ready for your editor.

Join the waitlist