Basically “batch mastering” is what broadcasters do to ensure a consistent level and color of their program. (That’s mostly done on the live audio stream but tools exist to do that offline).
ffmpeg apparently includes a loudness normalizer that takes into account the edge case where peaks are too high to apply an upward gain offset without clipping. I’ve never used it but i guess it works.
See http://k.ylo.ph/2016/04/04/loudnorm.html
Put that in a simple shell script to work over an entire folder and voilà.
But this will only fix the problem of level discrepancies between files, not large dynamic changes inside a single file. For that you want some kind of AGC.
Feeding your previously loudness-normalized files into stereotool will provide you AGC, multiband compression, etc. There is a command line version (and for our purpose here, it’s free i think) that you can use in a script too.
edit. looking into it it seems that stereotool does r128 normalization so the ffmpeg two-pass stuff from above can be skipped.
(actually i was planning to set up some kind of automated processing chain at work so i will look into that… in september.)