How to fix low-volume audio/video files with FFMPEG (for normalization) and/or Audacity (for Dynamic Range Compression)

Because my Internet connection is very cranky, I download online videos and play them offline on my WDTV media player. The WDTV remote does not have volume control. After I installed the wdlxtv open-source firmware, it has lost function of the Mute button. Now, there is no way to increase or decrease the volume without getting up from the chair.

Different videos have different volume levels. I wrote a Nautilus Action Configuration and a bash script to normalize audio and video files before I copied them to WDTV.

# Detect the max volume from this command
ffmpeg -y -i "$1/$2" -af "volumedetect" -an -vn -y -f null /dev/null

# Re-encode audio with this command after setting the DB level and output file name
ffmpeg -y -i "$1/$2" -af "volume=`echo $sDBLevel`dB" -c:a libmp3lame -b:a 128k "$sOutputFileName"

This worked fine for most files. Some video files continued to have low volume even though they were already normalized and couldn’t be normalized further. I then learned that this required the use of something called Dynamic Range Compression (DRC). DRC tries retains the waveform structure of the audio stream but compresses them against a threshold. Unfortunately, I compiled my FFMPEG binaries in 2013 and it did not seem to have filters for DRC. I cannot compile the latest FFMPEG source code because my Linux system is from 2010.

Instead, I choose the Dynamic Range Compressor option in Audacity. You load an audio file, select Compression from the Effects menu, adjust the settings and click OK to compress the audio and export it to a new MP3 file. This step couldn’t be automated.

I then used FFMPEG to replace the low-volume audio stream in the video with the compressed audio file generated by Audacity. In the FFMPEG command, I used to -i operators for two input files – the original video file and the new compressed audio file. I used the -map operator to copy the first stream of the first input file and the 3rd stream from the second input file to create a new video file. The second stream containing low-volume audio is dropped.

# Identify the streams in the input files
ffmpeg -i How_Low_Can_I_Go.mp4 -i "How_Low_Can_I_Go[COMPRESSED].mp3"

# Copy the video stream (0:0) without reencoding, drop 
# the second stream (0:1), use the third stream (1:0) for audio
ffmpeg -i How_Low_Can_I_Go.mp4 -i "How_Low_Can_I_Go[COMPRESSED].mp3" \
    -map 0:0 -map 1:0 \
    -vcodec copy -acodec copy \



Make a comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s