Batch Process MP4 Files in Parallel Using FFmpeg
Processing video files one by one can be time-consuming, but you can
significantly reduce encoding times by leveraging modern multi-core
processors to process multiple files at the same time. This guide shows
how to write a clean, reliable Bash script that uses ffmpeg
alongside xargs to concurrently encode or modify every MP4
file in a specified directory while safely handling filenames that
contain spaces.
The Bash Script
Create a script named process_videos.sh and add the
following code:
#!/usr/bin/env bash
# Define input and output directories
INPUT_DIR="./input"
OUTPUT_DIR="./output"
# Set the maximum number of concurrent processes (e.g., 4 or use $(nproc) for all cores)
MAX_JOBS=4
# Create output directory if it does not exist
mkdir -p "$OUTPUT_DIR"
# Export variables and the processing function so subshells can access them
export OUTPUT_DIR
process_video() {
input_file="$1"
filename=$(basename -- "$input_file")
output_file="$OUTPUT_DIR/${filename%.mp4}_processed.mp4"
echo "Starting: $filename"
# Replace this ffmpeg command with your desired options
ffmpeg -v error -stats -y -i "$input_file" \
-c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k \
"$output_file"
echo "Completed: $filename"
}
export -f process_video
# Find all MP4 files and pass them to xargs for parallel execution
find "$INPUT_DIR" -maxdepth 1 -type f -name "*.mp4" -print0 | \
xargs -0 -n 1 -P "$MAX_JOBS" -I {} bash -c 'process_video "$@"' _ {}
echo "All files processed successfully."How It Works
MAX_JOBS: Controls how many instances offfmpegrun simultaneously. You can set this manually or replace the value with$(nproc)to automatically match the number of available CPU threads.find ... -print0: Scans the input folder for files ending in.mp4and outputs them separated by a null byte (\0). This ensures filenames containing spaces, tabs, or special characters are passed without breaking.xargs -0 -n 1 -P "$MAX_JOBS":-0instructsxargsto read null-terminated input.-n 1passes exactly one file at a time to the command.-P "$MAX_JOBS"enables parallel processing, keeping up to the designated number of worker processes running at once until the queue is finished.
ffmpeg -v error -stats: Suppresses non-critical log output to keep the terminal readable, while-statsprovides active encoding progress for each running process.
Running the Script
Make the script executable and run it from your terminal:
chmod +x process_videos.sh
./process_videos.sh