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

Tested with: FFmpeg 6.1 (verified against real FFmpeg)
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
FieldDescription
lavfi.scd.scoreScene-change score (higher = larger change)
lavfi.scd.timeTimestamp of the detection (seconds)

Tuning threshold

ParameterDefaultDescription
t / threshold10Scores 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 caseRecommended threshold
Film cut detection8–15
Sports footage15–25
Animation10–20
Surveillance footage5–10
Slideshow-style videos30–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 Example

Analyzing a 1080p/30fps, 2-minute H.264 video with scdet does not re-encode video because no output video is written:

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

Runtime is close to decode speed and can be faster than real time on a typical 8-core desktop. 4K sources, 10-bit HEVC, or network storage can make it much slower.

If you save scene frames as PNG, image encoding and disk writes are added. For videos with many cuts, PNG output can become the bottleneck. When using detected times as edit points, leave 0.2–0.5 seconds of padding because scene detection does not account for audio or subtitle timing. Results vary by environment.


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.



Tested with ffmpeg 6.1 / Ubuntu 24.04 (検証スクリプトで実行確認) Primary sources: ffmpeg.org/ffmpeg-filters.html#scdet / ffmpeg.org/ffmpeg-filters.html#select