Manually fix volume in mp3 file

I am shamelessly ripping off a superuser answer: How can I normalize audio using ffmpeg?.

Option 3: Manually normalizing audio with ffmpeg

In ffmpeg you can use the volume filter to change the volume of a track. Make sure you download a recent version of the program.

This guide is for peak normalization, meaning that it will make the loudest part in the file sit at 0 dB instead of something lower. There is also RMS-based normalization which tries to make the average loudness the same across multiple files. To do that, do not try to push the maximum volume to 0 dB, but the mean volume to the dB level of choice (e.g. -26 dB).

Find out the gain to apply

First you need to analyze the audio stream for the maximum volume to see if normalizing would even pay off:

ffmpeg -i video.avi -af "volumedetect" -vn -sn -dn -f null /dev/null

Replace /dev/null with NUL on Windows.
The -vn, -sn, and -dn arguments instruct ffmpeg to ignore non-audio streams during this analysis. This drastically speeds up the analysis.

This will output something like the following:

[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] histogram_0db: 87861

As you can see, our maximum volume is -5.0 dB, so we can apply 5 dB gain. If you get a value of 0 dB, then you don’t need to normalize the audio.

Apply the volume filter:

Now we apply the volume filter to an audio file. Note that applying the filter means we will have to re-encode the audio stream. What codec you want for audio depends on the original format, of course. Here are some examples:

  • Plain audio file: Just encode the file with whatever encoder you need:
    ffmpeg -i input.wav -af "volume=5dB" output.mp3

    Your options are very broad, of course.

Convert m4a to mp3 while preserving audio quality

If you have a set of m4a files and want to automatically convert them to mp3 so you can tag them the right way, use a snippet I wrote.

See the code in its proper formatting at

# reference:

logfile="/mnt/bgstack15/log/m4a-to-mp3.$( date -u "+%FT%H%M%SZ" ).log"

func() {
for word in "$@" ;
   echo "Entering item ${word}";
   outdir="${word}/mp3" ; mkdir "${outdir}" || exit 1 ;
   find "${word}" -type f \( -regex '.*M4A' -o -regex '.*m4a' \) | while IFS='\0' read infile ;
      test -f "${infile}" && echo "Found file: \"${infile}\"" || echo "INVALID! ${infile}"
      outfile="$( echo "${infile}" | sed -r -e "s/\.m4a/\.mp3/i" )"
      echo  ffmpeg -i \"${infile}\" -codec:v copy -codec:a libmp3lame -q:a 2 \"${outfile}\"
      yes | ffmpeg -i "${infile}" -codec:v copy -codec:a libmp3lame -q:a 2 -y "${outfile}" ; test -n "${outdir}" && /bin/mv -f "${outfile}" "${outdir}/" ;
      sleep 2 ;

time func "$@" | tee -a "${logfile}"