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.jpg

To decrease sensitivity and catch only major cuts:

ffmpeg -i input.mp4 -vf "select='gt(scene,0.6)'" -fps_mode vfr scene_%03d.jpg

2. 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.mp4

Best Practices

  • Always test on a short clip: Run your command with -ss and -t to 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.3 or 0.4 may trigger on every frame during high-motion bursts. Increase the threshold to 0.5 or higher to isolate true camera cuts.