Adjust Scene Change Threshold in FFmpeg Select Filter
FFmpeg allows users to detect and extract scene transitions
automatically using the select video filter paired with the
scene evaluation variable. By adjusting the scene detection
threshold, you can control how sensitive FFmpeg is to visual changes
between consecutive frames. This guide explains how the scene score
works, how to configure the threshold value, and how to execute
practical commands to extract scene changes or generate I-frame
thumbnails.
Understanding the Scene Detection Syntax
FFmpeg evaluates the difference between the current frame and the
previous frame, assigning it a scene score between
0.0 and 1.0. A score of 0.0
represents completely identical frames, while 1.0
represents a total visual shift.
To filter frames based on this score, use the gt()
(greater than) function inside the select filter:
-vf "select='gt(scene,0.4)'"In this expression, 0.4 is the scene change threshold.
FFmpeg will only process or output frames where the difference score
exceeds 0.4.
Selecting the Right Threshold Value
The threshold value determines the sensitivity of the filter:
- 0.1 to 0.3 (High Sensitivity): Detects subtle camera pans, fast object motion, or slight lighting shifts. Useful for slow-moving content or minimal visual shifts, but prone to false positives.
- 0.4 (Balanced Default): The standard starting point for most videos. Accurately detects most camera cuts and major transitions while ignoring minor subject movement.
- 0.5 to 0.8 (Low Sensitivity): Detects only dramatic visual changes, such as cuts between scenes with vastly different color palettes or extreme brightness shifts. Useful for reducing false positives in action-heavy footage.
Practical Commands
1. Extracting Scene Change Frames as Images
When exporting frames to images, combine the select
filter with -vsync vfr (or -fps_mode vfr in
modern FFmpeg versions) so that discarded frames are not replaced with
duplicates:
ffmpeg -i input.mp4 -vf "select='gt(scene,0.4)'" -fps_mode vfr scene_%03d.jpgTo decrease sensitivity and catch only major cuts:
ffmpeg -i input.mp4 -vf "select='gt(scene,0.6)'" -fps_mode vfr scene_%03d.jpg2. Outputting Scene Change Timestamps
To find the exact timestamps of scene cuts without extracting every
frame as an image, print the frame metadata to the console or a text
file using showinfo:
ffmpeg -i input.mp4 -filter_complex "select='gt(scene,0.4)',showinfo" -f null -Look for the pts_time values in the terminal output to
locate the detected cuts.
3. Forcing Keyframes at Scene Cuts
If you are re-encoding a video and want to insert keyframes
(I-frames) at detected scene changes, use the
-force_key_frames option:
ffmpeg -i input.mp4 -c:v libx264 -force_key_frames "expr:gte(t,n_forced*1)*gt(scene,0.4)" -c:a copy output.mp4Best Practices
- Always test on a short clip: Run your command with
-ssand-tto process a 30-second section first to confirm your threshold accurately detects real cuts without false positives. - Account for fast motion: If video content has
intense action sequences, standard thresholds like
0.3or0.4may trigger on every frame during high-motion bursts. Increase the threshold to0.5or higher to isolate true camera cuts.