What You’ll Learn

  • How to detect scene changes with the scdet filter
  • How to tune detection sensitivity via threshold (t)
  • How to read per-scene timestamps from the filter metadata
  • How to extract a frame at each scene boundary using select
  • How to batch-generate thumbnails at every cut

Verified: FFmpeg 8.1 on Windows — all 4 commands in this article were executed by the verification script and passed (2026-09-06). Platform: Windows / macOS / Linux


Basic Command

ffmpeg -i input.mp4 \
  -vf "scdet=t=10,metadata=mode=print:key=lavfi.scd.score" \
  -f null /dev/null

-f null /dev/null skips writing an output file, and metadata=print prints detection info to stderr.


Reading the Output

[Parsed_metadata_1 @ 0x...] lavfi.scd.score=18.3
[Parsed_metadata_1 @ 0x...] lavfi.scd.time=4.96
[Parsed_metadata_1 @ 0x...] lavfi.scd.score=32.7
[Parsed_metadata_1 @ 0x...] lavfi.scd.time=23.42
Field Description
lavfi.scd.score Scene-change score (higher = larger change)
lavfi.scd.time Timestamp of the detection (seconds)

Tuning threshold

Parameter Default Description
t / threshold 10 Scores at or above this value are reported as scene changes
ffmpeg -i input.mp4 -vf "scdet=t=20" -f null /dev/null
  • Low value (e.g. 5): Detects small changes (more false positives)
  • High value (e.g. 40): Detects only clear cuts (more missed cuts)
  • Documentaries and films: 1020 is a reasonable starting point

Save a Frame at Every Scene Change

Combine with the select filter to save a still at each cut.

ffmpeg -i input.mp4 -vf "select='gt(scene,0.35)'" -vsync vfr scene_%04d.png

Note: select’s scene value is computed by the select filter itself. It is not the same scale as scdet’s lavfi.scd.score, so tune the thresholds separately.


ffmpeg -i input.mp4 -vf "scdet=t=10,metadata=print" -f null /dev/null

Threshold Suggestions by Content Type

Use case Recommended threshold
Film cut detection 8–15
Sports footage 15–25
Animation 10–20
Surveillance footage 5–10
Slideshow-style videos 30–50

Caveats

Fades and Dissolves Are Hard to Detect

Hard cuts (instant transitions) are detected reliably, but fades and dissolves (gradual transitions) can trip up scdet and cause misdetection.

Long Videos Take Time

Scene detection decodes every frame, so long videos take a while to analyze. You can narrow the analysis with -ss and -to.


Measured: time and size

This is the command that was measured:

ffmpeg -i input.mp4 -vf "scdet=t=12,metadata=mode=print:key=lavfi.scd.time" -f null -
Measured
Time 7.09 s (16.92x realtime)
Output file none — analysis only

Rig: a 1920x1080, 30 fps, 120 s, 351.4 MB H.264 source (Big Buck Bunny, looped, CC BY 3.0) on a Core i9-14900KF (32 threads) with FFmpeg 8.1 (gyan.dev), run sequentially on 2026-09-05. The raw numbers are published as a dataset.

Why 7.09 seconds

The size column is empty because no file is ever created. -f null - decodes every frame, pushes it through scdet, then discards it without encoding or writing anything. On the same clip and the same machine, a plain H.264 re-encode with no filter at all (-c:v libx264 -crf 23 -preset medium) took 27.97 s. The gap says nothing about scene detection being clever — it says the encoder was not running.

Look in the other direction and the spread is wider. Operations that never decode a frame finish in about a second: stream mapping at 0.41 s, moving the moov atom at 0.49 s, an audio fade at 1.03 s. Those only remux. scdet sits between the two extremes — a full decode pass, no encode pass — and that is the entire cost model for this command.

This article used to say runtime “can be faster than real time on a typical 8-core desktop”. That was too cautious: on 32 threads it ran at 16.92x realtime. Read the figure for what it covers, though — 1080p, 8-bit H.264, read from a local disk. 4K or 10-bit HEVC makes decoding itself expensive, and a source pulled over the network will hit I/O limits long before it hits CPU limits.

Note also that 7.09 s is a run that wrote zero images. Saving detected scenes as PNG adds image encoding and disk writes on top of that number (a configuration not measured here), and on heavily cut footage the PNG writing, not the detection, becomes the bottleneck. If you use the detected times as edit points, leave 0.2–0.49 seconds of padding: scene detection marks visual changes only and knows nothing about audio or subtitle timing.


Frequently Asked Questions

What threshold should I use for scene detection?

Start with select='gt(scene,0.35)' for significant cuts. Lower it to 0.25–0.3 for fast-cut content, or raise it to 0.45–0.5 for hard cuts only. This is not the same scale as scdet’s t value.

How do I export the timestamps to a file?

ffmpeg -i in.mp4 -filter:v "select='gt(scene,0.4)',showinfo" -f null - 2> scenes.log then grep for pts_time.

Why does scene detect miss obvious cuts?

Cross-fades and flash-cuts can hide under the threshold. Combine scene detection with blackdetect to catch fade-outs that act as cuts.

Can I split the video at every detected scene automatically?

Yes — feed the timestamps into a wrapper script that calls ffmpeg -ss A -to B -c copy partN.mp4 per detected range.

Does scene detect work on animation?

Yes but tune the threshold. Animation has flatter colour distributions, so lower the threshold to 0.25–0.3 to catch real cuts.



Verified: FFmpeg 8.1 on Windows — all 4 commands in this article were executed by the verification script and passed (2026-09-06). Primary sources: ffmpeg.org/ffmpeg-filters.html#scdet / ffmpeg.org/ffmpeg-filters.html#select