ScreenshotNeo

BlogHow-to

How to Take Screenshots of an FLV File Every Minute with FFmpeg

Extract one frame every minute from an FLV with FFmpeg, control timing and quality, troubleshoot failures, and automate thumbnail workflows.

By the ScreenshotNeo team30 September 20268 min read

How to Take Screenshots of an FLV File Every Minute with FFmpeg

To save one screenshot from an FLV file every 60 seconds, run:

ffmpeg -i input.flv -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

The fps=1/60 filter emits one output frame every minute. The frame_%04d.jpg pattern creates files such as frame_0001.jpg, frame_0002.jpg, and so on. The original FLV is read only; FFmpeg decodes frames and encodes separate still images. The FFmpeg filters documentation defines the fps filter, while the image-sequence output is handled by the image2 muxer described in the formats documentation.

1. Prepare FFmpeg and an output directory

Install a current FFmpeg build for your operating system, then verify that the executable is available:

ffmpeg -version

Create the destination directory before running the extraction command:

mkdir -p screenshots

On Windows PowerShell, use:

New-Item -ItemType Directory -Force screenshots

Use a writable local path. If the input filename contains spaces, quote it:

ffmpeg -i 'my recording.flv' -vf 'fps=1/60' -q:v 2 'screenshots/frame_%04d.jpg'

2. Understand what the command does

Part Purpose
-i input.flv Opens the FLV input.
-vf 'fps=1/60' Produces one output frame per 60 seconds.
-q:v 2 Requests high JPEG quality; lower values generally mean better quality and larger files.
screenshots/frame_%04d.jpg Writes a numbered image sequence with four-digit zero padding.

The first image normally represents the first frame selected by the filter. Timestamps, variable frame rate, damaged packets, and decoder behavior can affect the exact source timestamp represented by an image. If exact timing matters, inspect the media timestamps and validate a few output frames rather than assuming every file is exactly on an integer minute.

The fps filter samples the video timeline and writes a numbered image sequence.
The fps filter samples the video timeline and writes a numbered image sequence.

3. Choose JPEG, PNG, or another image format

JPEG for thumbnails and contact sheets

ffmpeg -i input.flv -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

JPEG is compact and usually appropriate for video thumbnails. Adjust quality with -q:v. For FFmpeg’s JPEG encoder, values near 2 are high quality; larger values reduce quality and file size. Test representative frames because highly detailed or noisy video can produce much larger files.

PNG for lossless stills

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

PNG preserves pixels without lossy compression but can consume substantially more storage. It is useful for screen recordings, diagrams, subtitles, or later image processing where compression artifacts matter.

WebP when supported by your workflow

ffmpeg -i input.flv -vf 'fps=1/60' -c:v libwebp -q:v 80 screenshots/frame_%04d.webp

Confirm that your installed build includes the encoder and that the consuming application accepts WebP.

4. Restrict the time range or number of screenshots

Start at a particular timestamp

ffmpeg -ss 00:10:00 -i input.flv -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

This begins decoding at approximately ten minutes. Placing -ss before -i is generally faster because FFmpeg can seek before decoding, but the seek may be less exact for formats with sparse keyframes. For accuracy, place it after the input:

ffmpeg -i input.flv -ss 00:10:00 -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

The accurate form can decode more data and therefore take longer.

Process only a fixed duration

ffmpeg -i input.flv -t 00:30:00 -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

This limits processing to the first 30 minutes. Combine -ss and -t to extract a window:

ffmpeg -ss 00:10:00 -i input.flv -t 00:05:00 -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg

Stop after a known number of images

ffmpeg -i input.flv -vf 'fps=1/60' -frames:v 20 -q:v 2 screenshots/frame_%04d.jpg

With one frame per minute, -frames:v 20 produces at most 20 images. This is useful when you know the required thumbnail count but do not know the exact duration.

5. Resize frames while extracting

Add a scale filter after fps to create predictable thumbnail dimensions:

Seeking, duration limits, frame counts, and scaling keep extraction focused and storage manageable.
Seeking, duration limits, frame counts, and scaling keep extraction focused and storage manageable.
ffmpeg -i input.flv -vf 'fps=1/60,scale=640:-2' -q:v 3 screenshots/frame_%04d.jpg

640:-2 sets the width to 640 pixels and calculates an even height while preserving aspect ratio. To force a fixed canvas, use a crop or pad strategy instead of stretching:

ffmpeg -i input.flv -vf 'fps=1/60,scale=640:360:force_original_aspect_ratio=decrease,pad=640:360:(ow-iw)/2:(oh-ih)/2' -q:v 3 screenshots/frame_%04d.jpg

Keep the output dimensions consistent if the images will be assembled into a contact sheet, indexed in a database, or displayed in a grid.

6. Add timestamps or other overlays

You can burn the selected frame timestamp into each image with the drawtext filter. Font paths vary by operating system, so provide an explicit path when required:

ffmpeg -i input.flv -vf 'fps=1/60,drawtext=fontfile=/path/to/font.ttf:text=%{pts\:hms}:x=20:y=20:fontsize=28:fontcolor=white:box=1:boxcolor=black@0.6' -q:v 2 screenshots/frame_%04d.jpg

Escaping rules differ between the shell and FFmpeg filter syntax. If this command fails, remove drawtext first to confirm that extraction works, then add the overlay in smaller steps.

7. Filter timing versus output-rate control

fps=1/60 expresses the intended sampling interval directly in the filter graph. Another approach is output-rate control:

ffmpeg -i input.flv -r 1/60 -f image2 -q:v 2 screenshots/frame_%04d.jpg

Both approaches can create a one-frame-per-minute sequence, but they differ in how frame timestamps are converted and how other filters interact with the output. Prefer the explicit fps filter when the goal is periodic sampling. If you use -r, specify the image2 format explicitly when diagnosing unexpected output.

8. Handle variable frame rate, missing timestamps, and damaged files

FLV files may contain irregular timestamps or incomplete metadata. Start by inspecting the stream:

ffprobe -v error -show_entries format=duration:stream=index,codec_name,codec_type,avg_frame_rate,r_frame_rate,time_base -of json input.flv

If duration is missing, FFmpeg may continue until end of input or report an estimate. A damaged file can produce decoder warnings while still yielding usable images. Save diagnostic output to a log:

ffmpeg -loglevel warning -i input.flv -vf 'fps=1/60' -q:v 2 screenshots/frame_%04d.jpg 2> extraction.log

Review the log for corrupt packets, timestamp discontinuities, or an unsupported codec. If the first frame is black because the stream begins with a fade or empty segment, use -ss to start later or discard the first output with -start_number only when numbering, rather than selection, is the issue.

9. Automate extraction in scripts

Shell loop for many FLV files

for input in *.flv; do
  name=${input%.flv}
  mkdir -p "screenshots/$name"
  ffmpeg -nostdin -y -i "$input" -vf 'fps=1/60,scale=640:-2' -q:v 3 "screenshots/$name/frame_%04d.jpg"
done

-nostdin prevents a background job from waiting for terminal input. Use -y only when overwriting existing files is intentional.

Python subprocess example

from pathlib import Path
import subprocess

source = Path('input.flv')
out_dir = Path('screenshots')
out_dir.mkdir(exist_ok=True)

subprocess.run([
    'ffmpeg', '-nostdin', '-i', str(source),
    '-vf', 'fps=1/60,scale=640:-2',
    '-q:v', '3', str(out_dir / 'frame_%04d.jpg')
], check=True)

Use a unique output directory per input so reruns do not mix frames from different videos. Capture FFmpeg’s stderr in production if you need to classify failures.

10. Performance, storage, and reliability

  • Decode cost: FFmpeg may decode much of the file even though it writes only one image per minute. Long-GOP video and accurate seeking increase work.
  • Bound the job: Use -ss, -t, or -frames:v when you need only a segment.
  • Reduce output size: Scale frames and choose JPEG quality appropriate for the display size.
  • Parallelize carefully: Independent files can be processed concurrently, but too many FFmpeg processes can saturate CPU, disk, or memory bandwidth.
  • Make reruns safe: Write to a temporary directory, check the exit code, then rename the directory after successful completion.
  • Verify results: Count files and inspect the first, middle, and last image. A successful process can still produce fewer frames when the input ends early.

For repeatable pipelines, record the FFmpeg version, command line, input checksum, output count, and any warnings. This makes changes in decoder behavior or source files easier to diagnose.

11. Troubleshooting common errors

Symptom Likely cause Fix
ffmpeg: command not found FFmpeg is not installed or not on PATH. Install FFmpeg and reopen the terminal, then run ffmpeg -version.
No images are created The output directory does not exist, the input is empty, or the command failed before encoding. Create the directory, run with normal log output, and inspect the input with ffprobe.
Only one image appears The input is shorter than one minute or a duration limit was applied. Check duration and remove or increase -t and -frames:v.
Images are black The selected timestamps contain black frames, the decoder cannot decode correctly, or hardware acceleration is unstable. Try a later -ss, update FFmpeg, and test software decoding.
Output numbering starts unexpectedly Existing files, a custom start number, or a different pattern is being used. Use a fresh directory and an explicit pattern such as frame_%04d.jpg.
Huge JPEG files High quality, high resolution, or noisy source content. Increase -q:v, add scale, or use WebP where supported.
Timestamp warnings Irregular or missing input timestamps. Inspect with ffprobe, limit the range, and validate representative frames.
drawtext parse errors Font path or escaping is incorrect. Remove the overlay, use an absolute font path, and re-add escaped characters carefully.

12. Or skip the browser setup

FFmpeg is the right tool when the source is a local FLV and you need deterministic, batch extraction. If the source is a web page and you need a rendered screenshot instead, ScreenshotNeo provides a single HTTP call and an MCP server for AI agents. See the ScreenshotNeo API documentation for the available options.

curl -G 'https://api.screenshotneo.com/v1/shot' -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

13. Short FAQ

Does fps=1/60 mean exactly one image at every clock minute?

It means one output frame per 60 seconds of the input timeline. Variable timestamps, seeking, and damaged media can affect which source frame is selected.

Can I preserve the original video resolution?

Yes. Omit the scale filter. Add it only when you need smaller, consistent thumbnails.

Will FFmpeg change my FLV?

No. The command reads the FLV and writes separate image files.

How do I extract frames every ten seconds instead?

ffmpeg -i input.flv -vf 'fps=1/10' screenshots/frame_%04d.jpg

How do I stop overwriting existing screenshots?

Remove -y if you added it, or write each run to a new directory. FFmpeg will ask before replacing files when interactive input is available.