FFmpeg · Command Guide
How to Batch Convert Multiple Videos With FFmpeg
Running the same conversion across a whole folder of files, instead of typing the command once per file.
Running the same conversion across a whole folder of files, instead of typing the command once per file.
The command
for f in *.mov; do
ffmpeg -i "$f" -c:v libx264 -crf 20 -c:a aac "${f%.mov}.mp4"
doneWhat each flag does
| for f in *.mov; do ... done | A shell loop that runs once per file matching the pattern — standard bash/zsh syntax on macOS and Linux. |
| "$f" | The current file in the loop, quoted to handle filenames with spaces. |
| "${f%.mov}.mp4" | Strips the .mov extension and appends .mp4, so output.mov becomes output.mp4 instead of output.mov.mp4. |
Where this goes wrong
Forgetting to quote $f breaks on any filename containing a space, which is extremely common with screen recordings and phone exports that get auto-named with spaces.
Windows (PowerShell) equivalent
Get-ChildItem *.mov | ForEach-Object {
ffmpeg -i $_.FullName -c:v libx264 -crf 20 -c:a aac ($_.BaseName + ".mp4")
}After the command
Batch processing works for uniform conversions. The moment each video needs different captions or content, that's a different kind of automation — which is what a template with AI-filled content is for.
See the templatesCommon questions
Can I run these conversions in parallel to go faster?+
Yes, with GNU parallel or by backgrounding each job (
& in bash) — but FFmpeg encoding is CPU-intensive, so parallelizing beyond your core count won't help and may slow things down.What if my files have different original formats mixed together?+
The loop pattern
*.mov only matches that extension — change it to match multiple types, or loop over all files and let FFmpeg fail gracefully on non-video files.How do I avoid overwriting files if I run this twice?+
Add a check for the output file's existence before running FFmpeg, or add
-n to the FFmpeg command, which skips instead of overwriting if the output already exists.