Normalize audio in movies, using FFmpeg and Sox, in Windows

Submitted by 1024gr on 22 February, 2012 - 11:38

Evereybody has once in a while tried to view a movie, in which the sound is really low!

After some hours of tryouts, using ffmpeg ( http://ffmpeg.org/download.html ) and SoX ( http://sox.sourceforge.net/ -> Sourceforge's File Release System) I created the following batch script for Windows. In order to work, we must have put the ffmpeg.exe file and the sox.exe along with the batch file. Then we just drag'n'drop a movie file on to the batch file, which contaings the following:

echo off

echo Script by http://1024.gr

cd /d %~dp0

echo Extracting audio..

ffmpeg.exe -i %1 -ac 2 -y %1_clean.wav

echo Extracting video..

ffmpeg.exe -i %1 -map 0:0 -vcodec copy -y %1_clean.avi

echo Getting max amplitude..

sox %1_clean.wav -n stat -v 2> %1_apl.txt

Set /P apl_value= < %1_apl.txt

echo Normalizing audio.. gain: %apl_value%

sox --show-progress -v %apl_value% %1_clean.wav %1_norm.wav

echo Creating new video file..

ffmpeg.exe -i %1_clean.avi -i %1_norm.wav -vcodec copy %1

echo Cleaning..

del %1_clean.wav

del %1_clean.avi

del %1_norm.wav

del %1_apl.txt

pause

And let's explain:

echo off: From now on, we disable echoing!

cd /d %~dp0: We change current directory to the one containing the batch file, whatever the direcotry of the movie is. This is needed to find the ffmpeg and sox executables. The movie file name comes with full path!

EDIT: The previous command can be replaced by "pushd %~dp0" and a "popd" has to be added before last command (pause). With this change, we will be able to execute multiple files from a different batch file.

ffmpeg.exe -i %1 -ac 2 -y %1_clean.wav: We extract the audio from the movie (the first one if there are multiple audio streams), and convert it to uncompressed, 2 channel audio stream. This is needed to for SoX to work without eny problems. It is propable that also other encoding may work, however more than 2 channel will fail.

ffmpeg.exe -i %1 -map 0:0 -vcodec copy -y %1_clean.avi: We extract the video part, needed to easilly merge it again with the normalised audio, onto the same movie file. We assume that video stream, is the first stream of the file (0:0) which is the case for almost all videos.

sox %1_clean.wav -n stat -v 2> %1_apl.txt: We execute the SoX onto the clean audio, so as to get the maximum amplitude gain it can get. This is saveed in file ..apl.txt

Set /P apl_value= < %1_apl.txt: We save the previous number to a variable. It is needed for the following steps.

echo Normalizing audio.. gain: %apl_value%: We echo the new gain, because the user may don't want to continue with the normalization. For example, if this number is 1.05, which means that we can gain only 5% of the audio, it is really low and there won't be any difference. If, however, for example we get a number of 1.9 we should definitely continue as the audio will almost double in amplitude!

ffmpeg.exe -i %1_clean.avi -i %1_norm.wav -vcodec copy %1: We continue to try to merge the video stream with the normalised audio stream, while encoding it with libmp3 (it is selected automatically because of the video stream). Because we haven't used the -y flag, while trying to write on the original movie file, ffmpeg prompts to continue/overwrite. At this point we can see from the gain, previously mentioned, if we want to continue, by pressing Y, or not, by pressing n.

Then, we delete all temporary files, whatever the desicion is (Y or n).

All temporary files are created with the movie prefix. This gives us the advantage to use the batch normalisation script simultanesly. :)

Comments

Do a search for a frrewaee program called VirtualDub. It's a good, small program for recompressing video files but it also lets you save just the audio file from the video (File->Save WAV).References :

An idea I found from here is to add a sound between some steps. For example, I added

rundll32 user32.dll,MessageBeep MB_ICONEXCLAMATION

before the last ffmpeg.exe ... so as to know when to switch to that window (while I am doing something else) and press "y" to overwrite the video file! Check the link I mention to see what other windows default sound values you can put instead of MB_ICONEXCLAMATION.