Convert a Windows Folder With a One-Line For Loop FFmpeg Command

I just finished my Produce Videos with FFmpeg course which I recorded with Camtasia, edited in Adobe Premiere Pro, and output in the Adobe Media Encoder (AME). I outputted from AME at about 10 Mbps to ensure quality, but now I’m left with 3 GB of files to upload. I know the data rate is unnecessarily high, but AME doesn’t offer a mode like Constant Rate Factor which will ensure quality at a much lower bitrate.

So, I created a one-line batch file to encode these files to CRF using FFmpeg. Here’s the command:

for %%a in (*.mp4) DO ffmpeg -i "%%a" -crf 23 "output\%%~na_crf.mp4"

Here’s an explanation of the commands:

for – calls the “for loop,” which applies the command to all specified files or folders.

%%a – This identifies the “variable” you’ll encode throughout the string. Use a single % sign when working directly in the command prompt; use %% when working with a batch file. Note that you can use either lower case or upper case letters, but it must be a letter and you have to be consistent with all mentions.

(*.mp4) – this is the “set” of files, in this case, all MP4 files in the folder I’m running the batch in. To call multiple sets, list them separately like this (*.mp4 *.mov *.avi).

DO – this starts the FFmpeg command.

ffmpeg -i “%%a” – this calls FFmpeg and identifies the files to be encoded, essentially all the files in the set (e.g. all MP4 files).

– crf 23 – this is the FFmpeg command which will encode all files to CRF 23 quality level. FFmpeg will pass through the audio which is fine here, so I’m not specifying audio parameters.

“output\%%~na_crf.mp4” – Two things going on here. First, I’m sending the files to the output folder I created (FFmpeg won’t create it for you; you have to create it beforehand). That’s because I’m producing new MP4 files that FFmpeg would encode recursively if I save them to the same folder. If the file extension was different, I wouldn’t have to send the files to a different folder. Second, the “%%~na_crf.mp4” designation removes the extension from the file name and adds _crf. So, file “lesson1.mp4” becomes “lesson1_crf.mp4,” not “lesson1.mp4_crf.mp4.” I’m adding the _crf designation to help me keep track of the different versions but it’s not essential.

Note that I cover how to convert a folder of files in Ubuntu in the Streaming Media article entitled, How to Automate FFmpeg and Bento4 With Bash Scripts.

Here are some sources I found useful in my research:

Windows Pro IT Center – For Loops  

Rob van der Woude’s Scripting Pages – FOR loops

Stack Overflow: How to do a for loop in Windows command line?

Windows Command Line – FOR loop in Windows

About Jan Ozer

I help companies train new technical hires in streaming media-related positions; I also help companies optimize their codec selections and encoding stacks, and evaluate new encoders and codecs.

Check Also

Got a Successful Per-Title or New Codec Implementation Story to Share? Here’s Your Chance

I’m exceptionally pleased to return to in-person teaching at Streaming Media East, which will be held …