How to batch convert mp4 to dnxhd with ffmpeg?

I usually do this manually, but I now have to convert a lot of .mp4 file so I’d like to ideally batch convert them all.

What I usually do is ffmpeg -i INPUT_FILE.mp4 -c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le OUTPUT_FILE.mov

How do I do this for multiple files in one go?

You can loop over all the mp4 files in bash, then perform the command you want:

#!/bin/bash
for file in *.mp4
do
ffmpeg -i ${file} -c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le ${file}.mov
done
1 Like

It appears to be working exactly as expected. Thank you.

1 Like

If you’re not maxing out your CPU doing one file at a time, you can use parallel to run concurrent jobs. Make sure you have GNU parallel installed, then just put parallel in front of the command in the for loop: parallel ffmpeg ...

Parallel will more or less max out your CPU.

2 Likes

But I am.

Thanks for the tip, though.

Just a little heads-up:

If you, god forbid, have spaces or special characters in your file names you need to double quote the variable.

ffmpeg -i "${file}" -c:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p -c:a pcm_s16le "${file%.*}".mov

One thing, though. the resulting files are named .mp4.mov. Is there anyway the script can replace the extension .mp4 with .mov ?

I already took care of that in my earlier example:

${file%.*}.mov instead of ${file}.mov

This uses bash’s internal string manipulations [look for the Substring Removal section].

In this specific case: file holds name.mp4 the % part tells bash that something needs to be stripped from the end. The .* tells bash that everything after the . (dot) needs to be removed. You now need to add the mov extension to the string that is left.

EDIT: This isn’t greedy btw. A file named x.y.z.mp4 will be renamed to x.y.z.mov. If you do need to be greedy use %%.* x.y.z.mp4 will now end up as x.mov

1 Like

Thank you so much!

1 Like