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

  1. 2>&1: Redirects the standard error (where FFmpeg outputs logs) to standard output so it can be read by grep.
  2. grep -o "crop=[0-9]*:[0-9]*:[0-9]*:[0-9]*": Filters the terminal output to only keep text matching the format crop=width:height:x:y.
  3. tail -n 1: Grabs the very last crop suggestion, which is usually the most accurate after analyzing multiple frames.
  4. -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.
  5. -c:a copy: Copies the audio stream without re-encoding to save time and preserve quality.