Parallel Process MP4 Files Using FFmpeg and Bash
Processing video files sequentially can be incredibly slow, especially when dealing with a large directory of high-resolution MP4s. This guide provides a robust, straight-to-the-point Bash script that uses FFmpeg to process multiple MP4 files simultaneously. By utilizing background processes and controlling the maximum number of parallel jobs, you can maximize your CPU usage and drastically reduce your total encoding time.
The Bash Script
Save the following script as parallel_ffmpeg.sh. This
script scans the current directory for .mp4 files,
processes them in parallel up to a specified limit, and saves the output
to a designated directory.
#!/bin/bash
# Define the maximum number of parallel FFmpeg processes
MAX_JOBS=4
# Define the output directory
OUTPUT_DIR="./processed_videos"
mkdir -p "$OUTPUT_DIR"
# Loop through all MP4 files in the current directory
for file in *.mp4; do
# Check if files exist to prevent errors in empty directories
[ -e "$file" ] || continue
echo "Starting: $file"
# Run FFmpeg in the background (&)
# Modify the FFmpeg parameters here to fit your specific needs
ffmpeg -y -i "$file" -c:v libx264 -crf 23 -c:a aac "$OUTPUT_DIR/${file%.mp4}_processed.mp4" -nostdin -loglevel error &
# Keep track of active background jobs
# If the limit is reached, wait before spawning more
while [ $(jobs -r | wc -l) -ge "$MAX_JOBS" ]; do
sleep 1
done
done
# Wait for all remaining background processes to complete
wait
echo "All MP4 files have been processed."How to Run the Script
Make the script executable: Open your terminal and run the following command in the directory where you saved the script:
chmod +x parallel_ffmpeg.shExecute the script: Place the script in the directory containing your MP4 files and run it:
./parallel_ffmpeg.sh
Key Components Explained
MAX_JOBS=4: Controls how many FFmpeg processes run at the same time. Set this based on your CPU cores. For example, if you have an 8-core processor, you might set this to4or6to avoid system freezing.&(at the end of the FFmpeg command): This sends the FFmpeg command to the background, allowing the Bash loop to immediately move to the next file without waiting for the current one to finish.jobs -r | wc -l: This checks the number of currently running background jobs. If the count meets or exceedsMAX_JOBS, the script pauses for 1 second before checking again.-nostdin: This flag is crucial when running FFmpeg in the background. It prevents FFmpeg from trying to read from standard input, which can stall background processes.${file%.mp4}_processed.mp4: This extracts the original filename without the.mp4extension and appends_processed.mp4to the output file, avoiding overwriting the source file.