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" done

What each flag does

for f in *.mov; do ... doneA 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 templates

Common 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.