How to Automate FFmpeg Cropdetect and Crop Filters
This article explains how to automate video cropping in FFmpeg by
chain-linking the cropdetect and crop filters
within a script. You will learn how to run a quick analysis pass to
extract the optimal black-bar cropping coordinates and automatically
apply those parameters to encode a cropped output video using Bash.
The Two-Step Automation Process
FFmpeg cannot dynamically apply the output of cropdetect
to a crop filter in a single command because
cropdetect outputs its findings to the console (stderr) as
the video plays, while the crop filter requires static
parameters before processing begins.
To automate this, you must use a two-step scripting approach: 1.
Analyze: Run FFmpeg with cropdetect on a
small segment of the video to find the correct coordinates. 2.
Apply: Parse those coordinates from the terminal output
and pass them into a second FFmpeg command using the crop
filter.
Step 1: Extract Crop Parameters
To avoid analyzing the entire video (which is slow), seek to a bright part of the video and analyze a few frames.
The following command seeks 1 minute into the video
(-ss 00:01:00), analyzes 100 frames
(-vframes 100), runs the cropdetect filter,
and discards the video output (-f null -) while sending the
text log to the console:
ffmpeg -ss 00:01:00 -i input.mp4 -vframes 100 -vf cropdetect -f null -The output will contain lines like this:
[parsed_video_filter_0_cropdetect @ 0x...] limit:117 round:16 x1:0 x2:1919 y1:138 y2:941 w:1920 h:800 x:0 y:142 crop=1920:800:0:142
Step 2: Automate with a Bash Script
You can automate the extraction and application of the
crop parameters using a Bash script. This script uses
grep and tail to isolate the final
crop=... string and assigns it to a variable.
Create a script named autocrop.sh:
#!/bin/bash
INPUT_FILE="input.mp4"
OUTPUT_FILE="output_cropped.mp4"
echo "Analyzing video for black borders..."
# Run cropdetect on 100 frames starting at 1 minute, extract the last 'crop=' value
CROP_VALUES=$(ffmpeg -ss 00:01:00 -i "$INPUT_FILE" -vframes 100 -vf cropdetect -f null - 2>&1 | grep -o "crop=[0-9]*:[0-9]*:[0-9]*:[0-9]*" | tail -n 1)
# Check if we successfully extracted crop values
if [ -z "$CROP_VALUES" ]; then
echo "Error: Could not detect crop parameters."
exit 1
fi
echo "Detected crop parameters: $CROP_VALUES"
echo "Cropping and encoding video..."
# Apply the detected crop parameters to the entire video
ffmpeg -i "$INPUT_FILE" -vf "$CROP_VALUES" -c:a copy "$OUTPUT_FILE"
echo "Cropping complete! Saved to $OUTPUT_FILE"Script Explanation
2>&1: Redirects the standard error (where FFmpeg outputs logs) to standard output so it can be read bygrep.grep -o "crop=[0-9]*:[0-9]*:[0-9]*:[0-9]*": Filters the terminal output to only keep text matching the formatcrop=width:height:x:y.tail -n 1: Grabs the very last crop suggestion, which is usually the most accurate after analyzing multiple frames.-vf "$CROP_VALUES": Passes the extracted string (e.g.,crop=1920:800:0:142) directly into the video filter argument of the second FFmpeg command.-c:a copy: Copies the audio stream without re-encoding to save time and preserve quality.