How can I normalize audio using ffmpeg?












96














I want the loudest peak sound in a movie clip to be as loud as the codec allows, then have every other sound amplified accordingly.



What's a practical example in order to accomplish this using ffmpeg?










share|improve this question




















  • 1




    You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
    – bobsbarricades
    Aug 14 '11 at 20:02


















96














I want the loudest peak sound in a movie clip to be as loud as the codec allows, then have every other sound amplified accordingly.



What's a practical example in order to accomplish this using ffmpeg?










share|improve this question




















  • 1




    You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
    – bobsbarricades
    Aug 14 '11 at 20:02
















96












96








96


67





I want the loudest peak sound in a movie clip to be as loud as the codec allows, then have every other sound amplified accordingly.



What's a practical example in order to accomplish this using ffmpeg?










share|improve this question















I want the loudest peak sound in a movie clip to be as loud as the codec allows, then have every other sound amplified accordingly.



What's a practical example in order to accomplish this using ffmpeg?







audio ffmpeg






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 2 '14 at 13:55









Sathyajith Bhat

52.6k29154252




52.6k29154252










asked Aug 14 '11 at 19:56









Jon Skarpeteig

596157




596157








  • 1




    You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
    – bobsbarricades
    Aug 14 '11 at 20:02
















  • 1




    You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
    – bobsbarricades
    Aug 14 '11 at 20:02










1




1




You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
– bobsbarricades
Aug 14 '11 at 20:02






You're looking to have the audio 'normalized.' I found this thread and there's lots of good information in there. Hope it helps!
– bobsbarricades
Aug 14 '11 at 20:02












3 Answers
3






active

oldest

votes


















146














Option 1: Built-in Normalization Filters



Current ffmpeg has two filters that can be directly used for normalization – although they are already quite advanced, so they do not simply apply gain to reach a peak level. Here they are:





  • loudnorm: loudness normalization according to EBU R128. You can set an integrated loudness target, a loudness range target, or maximum true peak. This is recommended for publishing audio and video and it is used by broadcasters all over the world.


  • dynaudnorm: “intelligent” loudness normalization without clipping, which applies normalization dynamically over windowed portions of the file. This may change the characteristics of the sound, so it should be applied with caution.


Also, the volume filter can be used to perform simple volume adjustments. See the Audio Volume Manipulation wiki entry for more.



The loudnorm filter can be used with one pass, but it is recommended to perform two passes, which enables more accurate linear normalization. This is a little hard to automate. Also, if you want a “simple” RMS-based or peak normalization to 0 dBFS (or any other target), read on.





Option 2: Use the ffmpeg-normalize tool



I created a Python program to normalize media files, available on PyPi as well. You simply:





  • download ffmpeg (choose a static build, version 3.1 or higher)

  • put the ffmpeg executable in your $PATH by either adding it in, for example, /usr/local/bin, or adding its directory to $PATH

  • Run pip install ffmpeg-normalize

  • Use ffmpeg-normalize


For example:



ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k


Or, to simply batch-normalize a number of audio files and write them as uncompressed WAV to an output folder:



ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav


The tool supports EBU R128 (default), RMS and peak. Have a look at ffmpeg-normalize -h for more options and check the README for some examples.



Also, it supports re-encoding with other encoders (e.g., AAC or MP3), or automatic merging of the audio back into the video.





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.




  • AVI format: Usually there's MP3 audio with video that comes in an AVI container:



    ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi


    Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.




  • MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.



    ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4


    Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.




In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.






share|improve this answer























  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Journeyman Geek
    Apr 14 '17 at 3:18






  • 4




    This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
    – Jon Skarpeteig
    Aug 7 '17 at 21:04










  • @Jon Thanks, much appreciated!
    – slhck
    Aug 7 '17 at 21:24










  • Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
    – rraallvv
    Oct 26 '17 at 0:38










  • @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
    – slhck
    Oct 27 '17 at 7:43



















7














I can not comment on the best message so that is my ugly bash based on it to do that



ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
grep "max_volume" original.txt > original1.tmp
sed -i 's|: -|=|' original1.tmp
if [ $? = 0 ]
then
sed -i 's| |rn|' original.tmp
sed -i 's| |rn|' original.tmp
sed -i 's| |rn|' original.tmp
sed -i 's| |rn|' original.tmp
grep "max_volume" original1.tmp > original2.tmp
sed -i 's|max_volume=||' original2.tmp
yourscriptvar=$(cat "./original2.tmp")dB
rm result.mp3
ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
fi





share|improve this answer





























    5














    Here's a script to normalize sound levels of .m4a files. Watch out if the sound levels are too quiet to start with. The final sound can be better if you use something like Audacity in that case.



    #!/bin/bash

    # Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
    # Parameters: $1 should be the name of the directory containing input .m4a files.
    # $2 should be the output directory.

    INPUTDIR=$1
    OUTPUTDIR=$2

    <<"COMMENT"

    # For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
    # and
    # https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
    ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

    ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
    # output: max_volume: -10.3 dB

    ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume|Duration'
    # Output:
    # Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
    # [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

    ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
    # Output: -10.3

    ffmpeg -i test.m4a 2>&1 | grep Audio
    # output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

    ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
    # output: 170

    # This works, but I get a much smaller output file. The sound levels do appear normalized.
    ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

    # Operates quietly.
    ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

    COMMENT

    # $1 (first param) should be the name of a .m4a input file, with .m4a extension
    # $2 should be name of output file, with extension
    function normalizeAudioFile {
    INPUTFILE=$1
    OUTPUTFILE=$2

    DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

    # We're only going to increase db level if max volume has negative db level.
    # Bash doesn't do floating comparison directly
    COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
    if [ ${COMPRESULT} -eq 1 ]; then
    DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
    BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

    # echo $DBLEVEL
    # echo $BITRATE

    ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

    else
    echo "Already at max db level:" $DBLEVEL "just copying exact file"
    cp ${INPUTFILE} ${OUTPUTFILE}
    fi
    }

    for inputFilePath in ${INPUTDIR}/*; do
    inputFile=$(basename $inputFilePath)
    echo "Processing input file: " $inputFile
    outputFilePath=${OUTPUTDIR}/$inputFile
    normalizeAudioFile ${inputFilePath} ${outputFilePath}
    done





    share|improve this answer





















      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "3"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f323119%2fhow-can-i-normalize-audio-using-ffmpeg%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      146














      Option 1: Built-in Normalization Filters



      Current ffmpeg has two filters that can be directly used for normalization – although they are already quite advanced, so they do not simply apply gain to reach a peak level. Here they are:





      • loudnorm: loudness normalization according to EBU R128. You can set an integrated loudness target, a loudness range target, or maximum true peak. This is recommended for publishing audio and video and it is used by broadcasters all over the world.


      • dynaudnorm: “intelligent” loudness normalization without clipping, which applies normalization dynamically over windowed portions of the file. This may change the characteristics of the sound, so it should be applied with caution.


      Also, the volume filter can be used to perform simple volume adjustments. See the Audio Volume Manipulation wiki entry for more.



      The loudnorm filter can be used with one pass, but it is recommended to perform two passes, which enables more accurate linear normalization. This is a little hard to automate. Also, if you want a “simple” RMS-based or peak normalization to 0 dBFS (or any other target), read on.





      Option 2: Use the ffmpeg-normalize tool



      I created a Python program to normalize media files, available on PyPi as well. You simply:





      • download ffmpeg (choose a static build, version 3.1 or higher)

      • put the ffmpeg executable in your $PATH by either adding it in, for example, /usr/local/bin, or adding its directory to $PATH

      • Run pip install ffmpeg-normalize

      • Use ffmpeg-normalize


      For example:



      ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k


      Or, to simply batch-normalize a number of audio files and write them as uncompressed WAV to an output folder:



      ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav


      The tool supports EBU R128 (default), RMS and peak. Have a look at ffmpeg-normalize -h for more options and check the README for some examples.



      Also, it supports re-encoding with other encoders (e.g., AAC or MP3), or automatic merging of the audio back into the video.





      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.




      • AVI format: Usually there's MP3 audio with video that comes in an AVI container:



        ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi


        Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.




      • MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.



        ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4


        Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.




      In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.






      share|improve this answer























      • Comments are not for extended discussion; this conversation has been moved to chat.
        – Journeyman Geek
        Apr 14 '17 at 3:18






      • 4




        This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
        – Jon Skarpeteig
        Aug 7 '17 at 21:04










      • @Jon Thanks, much appreciated!
        – slhck
        Aug 7 '17 at 21:24










      • Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
        – rraallvv
        Oct 26 '17 at 0:38










      • @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
        – slhck
        Oct 27 '17 at 7:43
















      146














      Option 1: Built-in Normalization Filters



      Current ffmpeg has two filters that can be directly used for normalization – although they are already quite advanced, so they do not simply apply gain to reach a peak level. Here they are:





      • loudnorm: loudness normalization according to EBU R128. You can set an integrated loudness target, a loudness range target, or maximum true peak. This is recommended for publishing audio and video and it is used by broadcasters all over the world.


      • dynaudnorm: “intelligent” loudness normalization without clipping, which applies normalization dynamically over windowed portions of the file. This may change the characteristics of the sound, so it should be applied with caution.


      Also, the volume filter can be used to perform simple volume adjustments. See the Audio Volume Manipulation wiki entry for more.



      The loudnorm filter can be used with one pass, but it is recommended to perform two passes, which enables more accurate linear normalization. This is a little hard to automate. Also, if you want a “simple” RMS-based or peak normalization to 0 dBFS (or any other target), read on.





      Option 2: Use the ffmpeg-normalize tool



      I created a Python program to normalize media files, available on PyPi as well. You simply:





      • download ffmpeg (choose a static build, version 3.1 or higher)

      • put the ffmpeg executable in your $PATH by either adding it in, for example, /usr/local/bin, or adding its directory to $PATH

      • Run pip install ffmpeg-normalize

      • Use ffmpeg-normalize


      For example:



      ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k


      Or, to simply batch-normalize a number of audio files and write them as uncompressed WAV to an output folder:



      ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav


      The tool supports EBU R128 (default), RMS and peak. Have a look at ffmpeg-normalize -h for more options and check the README for some examples.



      Also, it supports re-encoding with other encoders (e.g., AAC or MP3), or automatic merging of the audio back into the video.





      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.




      • AVI format: Usually there's MP3 audio with video that comes in an AVI container:



        ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi


        Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.




      • MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.



        ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4


        Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.




      In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.






      share|improve this answer























      • Comments are not for extended discussion; this conversation has been moved to chat.
        – Journeyman Geek
        Apr 14 '17 at 3:18






      • 4




        This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
        – Jon Skarpeteig
        Aug 7 '17 at 21:04










      • @Jon Thanks, much appreciated!
        – slhck
        Aug 7 '17 at 21:24










      • Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
        – rraallvv
        Oct 26 '17 at 0:38










      • @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
        – slhck
        Oct 27 '17 at 7:43














      146












      146








      146






      Option 1: Built-in Normalization Filters



      Current ffmpeg has two filters that can be directly used for normalization – although they are already quite advanced, so they do not simply apply gain to reach a peak level. Here they are:





      • loudnorm: loudness normalization according to EBU R128. You can set an integrated loudness target, a loudness range target, or maximum true peak. This is recommended for publishing audio and video and it is used by broadcasters all over the world.


      • dynaudnorm: “intelligent” loudness normalization without clipping, which applies normalization dynamically over windowed portions of the file. This may change the characteristics of the sound, so it should be applied with caution.


      Also, the volume filter can be used to perform simple volume adjustments. See the Audio Volume Manipulation wiki entry for more.



      The loudnorm filter can be used with one pass, but it is recommended to perform two passes, which enables more accurate linear normalization. This is a little hard to automate. Also, if you want a “simple” RMS-based or peak normalization to 0 dBFS (or any other target), read on.





      Option 2: Use the ffmpeg-normalize tool



      I created a Python program to normalize media files, available on PyPi as well. You simply:





      • download ffmpeg (choose a static build, version 3.1 or higher)

      • put the ffmpeg executable in your $PATH by either adding it in, for example, /usr/local/bin, or adding its directory to $PATH

      • Run pip install ffmpeg-normalize

      • Use ffmpeg-normalize


      For example:



      ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k


      Or, to simply batch-normalize a number of audio files and write them as uncompressed WAV to an output folder:



      ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav


      The tool supports EBU R128 (default), RMS and peak. Have a look at ffmpeg-normalize -h for more options and check the README for some examples.



      Also, it supports re-encoding with other encoders (e.g., AAC or MP3), or automatic merging of the audio back into the video.





      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.




      • AVI format: Usually there's MP3 audio with video that comes in an AVI container:



        ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi


        Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.




      • MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.



        ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4


        Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.




      In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.






      share|improve this answer














      Option 1: Built-in Normalization Filters



      Current ffmpeg has two filters that can be directly used for normalization – although they are already quite advanced, so they do not simply apply gain to reach a peak level. Here they are:





      • loudnorm: loudness normalization according to EBU R128. You can set an integrated loudness target, a loudness range target, or maximum true peak. This is recommended for publishing audio and video and it is used by broadcasters all over the world.


      • dynaudnorm: “intelligent” loudness normalization without clipping, which applies normalization dynamically over windowed portions of the file. This may change the characteristics of the sound, so it should be applied with caution.


      Also, the volume filter can be used to perform simple volume adjustments. See the Audio Volume Manipulation wiki entry for more.



      The loudnorm filter can be used with one pass, but it is recommended to perform two passes, which enables more accurate linear normalization. This is a little hard to automate. Also, if you want a “simple” RMS-based or peak normalization to 0 dBFS (or any other target), read on.





      Option 2: Use the ffmpeg-normalize tool



      I created a Python program to normalize media files, available on PyPi as well. You simply:





      • download ffmpeg (choose a static build, version 3.1 or higher)

      • put the ffmpeg executable in your $PATH by either adding it in, for example, /usr/local/bin, or adding its directory to $PATH

      • Run pip install ffmpeg-normalize

      • Use ffmpeg-normalize


      For example:



      ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k


      Or, to simply batch-normalize a number of audio files and write them as uncompressed WAV to an output folder:



      ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav


      The tool supports EBU R128 (default), RMS and peak. Have a look at ffmpeg-normalize -h for more options and check the README for some examples.



      Also, it supports re-encoding with other encoders (e.g., AAC or MP3), or automatic merging of the audio back into the video.





      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.




      • AVI format: Usually there's MP3 audio with video that comes in an AVI container:



        ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi


        Here we chose quality level 2. Values range from 0–9 and lower means better. Check the MP3 VBR guide for more info on setting the quality. You can also set a fixed bitrate with -b:a 192k, for example.




      • MP4 format: With an MP4 container, you will typically find AAC audio. We can use ffmpeg's build-in AAC encoder.



        ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4


        Here you can also use other AAC encoders. Some of them support VBR, too. See this answer and the AAC encoding guide for some tips.




      In the above examples, the video stream will be copied over using -c:v copy. If there are subtitles in your input file, or multiple video streams, use the option -map 0 before the output filename.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 25 at 11:48

























      answered Aug 14 '11 at 20:11









      slhck

      159k47441464




      159k47441464












      • Comments are not for extended discussion; this conversation has been moved to chat.
        – Journeyman Geek
        Apr 14 '17 at 3:18






      • 4




        This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
        – Jon Skarpeteig
        Aug 7 '17 at 21:04










      • @Jon Thanks, much appreciated!
        – slhck
        Aug 7 '17 at 21:24










      • Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
        – rraallvv
        Oct 26 '17 at 0:38










      • @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
        – slhck
        Oct 27 '17 at 7:43


















      • Comments are not for extended discussion; this conversation has been moved to chat.
        – Journeyman Geek
        Apr 14 '17 at 3:18






      • 4




        This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
        – Jon Skarpeteig
        Aug 7 '17 at 21:04










      • @Jon Thanks, much appreciated!
        – slhck
        Aug 7 '17 at 21:24










      • Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
        – rraallvv
        Oct 26 '17 at 0:38










      • @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
        – slhck
        Oct 27 '17 at 7:43
















      Comments are not for extended discussion; this conversation has been moved to chat.
      – Journeyman Geek
      Apr 14 '17 at 3:18




      Comments are not for extended discussion; this conversation has been moved to chat.
      – Journeyman Geek
      Apr 14 '17 at 3:18




      4




      4




      This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
      – Jon Skarpeteig
      Aug 7 '17 at 21:04




      This is the gift that keeps on giving. 6 years later, and it's still being updated and maintained. Well done!
      – Jon Skarpeteig
      Aug 7 '17 at 21:04












      @Jon Thanks, much appreciated!
      – slhck
      Aug 7 '17 at 21:24




      @Jon Thanks, much appreciated!
      – slhck
      Aug 7 '17 at 21:24












      Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
      – rraallvv
      Oct 26 '17 at 0:38




      Does option 3 avoid clipping if I set the new volume so max_volume is zero? i.e. using the opposite value initial given by max_volume
      – rraallvv
      Oct 26 '17 at 0:38












      @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
      – slhck
      Oct 27 '17 at 7:43




      @rraallvv Yes, it should. That's also what the ffmpeg-normalize tool does, when you specify a level of 0 dB and peak-normalization.
      – slhck
      Oct 27 '17 at 7:43













      7














      I can not comment on the best message so that is my ugly bash based on it to do that



      ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
      grep "max_volume" original.txt > original1.tmp
      sed -i 's|: -|=|' original1.tmp
      if [ $? = 0 ]
      then
      sed -i 's| |rn|' original.tmp
      sed -i 's| |rn|' original.tmp
      sed -i 's| |rn|' original.tmp
      sed -i 's| |rn|' original.tmp
      grep "max_volume" original1.tmp > original2.tmp
      sed -i 's|max_volume=||' original2.tmp
      yourscriptvar=$(cat "./original2.tmp")dB
      rm result.mp3
      ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
      ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
      fi





      share|improve this answer


























        7














        I can not comment on the best message so that is my ugly bash based on it to do that



        ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
        grep "max_volume" original.txt > original1.tmp
        sed -i 's|: -|=|' original1.tmp
        if [ $? = 0 ]
        then
        sed -i 's| |rn|' original.tmp
        sed -i 's| |rn|' original.tmp
        sed -i 's| |rn|' original.tmp
        sed -i 's| |rn|' original.tmp
        grep "max_volume" original1.tmp > original2.tmp
        sed -i 's|max_volume=||' original2.tmp
        yourscriptvar=$(cat "./original2.tmp")dB
        rm result.mp3
        ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
        ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
        fi





        share|improve this answer
























          7












          7








          7






          I can not comment on the best message so that is my ugly bash based on it to do that



          ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
          grep "max_volume" original.txt > original1.tmp
          sed -i 's|: -|=|' original1.tmp
          if [ $? = 0 ]
          then
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          grep "max_volume" original1.tmp > original2.tmp
          sed -i 's|max_volume=||' original2.tmp
          yourscriptvar=$(cat "./original2.tmp")dB
          rm result.mp3
          ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
          ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
          fi





          share|improve this answer












          I can not comment on the best message so that is my ugly bash based on it to do that



          ffmpeg -i sound.mp3 -af volumedetect -f null -y nul &> original.txt
          grep "max_volume" original.txt > original1.tmp
          sed -i 's|: -|=|' original1.tmp
          if [ $? = 0 ]
          then
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          sed -i 's| |rn|' original.tmp
          grep "max_volume" original1.tmp > original2.tmp
          sed -i 's|max_volume=||' original2.tmp
          yourscriptvar=$(cat "./original2.tmp")dB
          rm result.mp3
          ffmpeg -i sound.mp3 -af "volume=$yourscriptvar" result.mp3
          ffmpeg -i result.mp3 -af volumedetect -f null -y nul &> result.txt
          fi






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered May 19 '16 at 14:51









          Sebastien Willemijns

          7112




          7112























              5














              Here's a script to normalize sound levels of .m4a files. Watch out if the sound levels are too quiet to start with. The final sound can be better if you use something like Audacity in that case.



              #!/bin/bash

              # Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
              # Parameters: $1 should be the name of the directory containing input .m4a files.
              # $2 should be the output directory.

              INPUTDIR=$1
              OUTPUTDIR=$2

              <<"COMMENT"

              # For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
              # and
              # https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
              ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

              ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
              # output: max_volume: -10.3 dB

              ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume|Duration'
              # Output:
              # Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
              # [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

              ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
              # Output: -10.3

              ffmpeg -i test.m4a 2>&1 | grep Audio
              # output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

              ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
              # output: 170

              # This works, but I get a much smaller output file. The sound levels do appear normalized.
              ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

              # Operates quietly.
              ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

              COMMENT

              # $1 (first param) should be the name of a .m4a input file, with .m4a extension
              # $2 should be name of output file, with extension
              function normalizeAudioFile {
              INPUTFILE=$1
              OUTPUTFILE=$2

              DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

              # We're only going to increase db level if max volume has negative db level.
              # Bash doesn't do floating comparison directly
              COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
              if [ ${COMPRESULT} -eq 1 ]; then
              DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
              BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

              # echo $DBLEVEL
              # echo $BITRATE

              ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

              else
              echo "Already at max db level:" $DBLEVEL "just copying exact file"
              cp ${INPUTFILE} ${OUTPUTFILE}
              fi
              }

              for inputFilePath in ${INPUTDIR}/*; do
              inputFile=$(basename $inputFilePath)
              echo "Processing input file: " $inputFile
              outputFilePath=${OUTPUTDIR}/$inputFile
              normalizeAudioFile ${inputFilePath} ${outputFilePath}
              done





              share|improve this answer


























                5














                Here's a script to normalize sound levels of .m4a files. Watch out if the sound levels are too quiet to start with. The final sound can be better if you use something like Audacity in that case.



                #!/bin/bash

                # Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
                # Parameters: $1 should be the name of the directory containing input .m4a files.
                # $2 should be the output directory.

                INPUTDIR=$1
                OUTPUTDIR=$2

                <<"COMMENT"

                # For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
                # and
                # https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
                ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

                ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
                # output: max_volume: -10.3 dB

                ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume|Duration'
                # Output:
                # Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
                # [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

                ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
                # Output: -10.3

                ffmpeg -i test.m4a 2>&1 | grep Audio
                # output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

                ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
                # output: 170

                # This works, but I get a much smaller output file. The sound levels do appear normalized.
                ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

                # Operates quietly.
                ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

                COMMENT

                # $1 (first param) should be the name of a .m4a input file, with .m4a extension
                # $2 should be name of output file, with extension
                function normalizeAudioFile {
                INPUTFILE=$1
                OUTPUTFILE=$2

                DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

                # We're only going to increase db level if max volume has negative db level.
                # Bash doesn't do floating comparison directly
                COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
                if [ ${COMPRESULT} -eq 1 ]; then
                DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
                BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

                # echo $DBLEVEL
                # echo $BITRATE

                ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

                else
                echo "Already at max db level:" $DBLEVEL "just copying exact file"
                cp ${INPUTFILE} ${OUTPUTFILE}
                fi
                }

                for inputFilePath in ${INPUTDIR}/*; do
                inputFile=$(basename $inputFilePath)
                echo "Processing input file: " $inputFile
                outputFilePath=${OUTPUTDIR}/$inputFile
                normalizeAudioFile ${inputFilePath} ${outputFilePath}
                done





                share|improve this answer
























                  5












                  5








                  5






                  Here's a script to normalize sound levels of .m4a files. Watch out if the sound levels are too quiet to start with. The final sound can be better if you use something like Audacity in that case.



                  #!/bin/bash

                  # Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
                  # Parameters: $1 should be the name of the directory containing input .m4a files.
                  # $2 should be the output directory.

                  INPUTDIR=$1
                  OUTPUTDIR=$2

                  <<"COMMENT"

                  # For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
                  # and
                  # https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
                  # output: max_volume: -10.3 dB

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume|Duration'
                  # Output:
                  # Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
                  # [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
                  # Output: -10.3

                  ffmpeg -i test.m4a 2>&1 | grep Audio
                  # output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

                  ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
                  # output: 170

                  # This works, but I get a much smaller output file. The sound levels do appear normalized.
                  ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

                  # Operates quietly.
                  ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

                  COMMENT

                  # $1 (first param) should be the name of a .m4a input file, with .m4a extension
                  # $2 should be name of output file, with extension
                  function normalizeAudioFile {
                  INPUTFILE=$1
                  OUTPUTFILE=$2

                  DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

                  # We're only going to increase db level if max volume has negative db level.
                  # Bash doesn't do floating comparison directly
                  COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
                  if [ ${COMPRESULT} -eq 1 ]; then
                  DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
                  BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

                  # echo $DBLEVEL
                  # echo $BITRATE

                  ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

                  else
                  echo "Already at max db level:" $DBLEVEL "just copying exact file"
                  cp ${INPUTFILE} ${OUTPUTFILE}
                  fi
                  }

                  for inputFilePath in ${INPUTDIR}/*; do
                  inputFile=$(basename $inputFilePath)
                  echo "Processing input file: " $inputFile
                  outputFilePath=${OUTPUTDIR}/$inputFile
                  normalizeAudioFile ${inputFilePath} ${outputFilePath}
                  done





                  share|improve this answer












                  Here's a script to normalize sound levels of .m4a files. Watch out if the sound levels are too quiet to start with. The final sound can be better if you use something like Audacity in that case.



                  #!/bin/bash

                  # Purpose: Use ffmpeg to normalize .m4a audio files to bring them up to max volume, if they at first have negative db volume. Doesn't process them if not. Keeps bitrate same as source files.
                  # Parameters: $1 should be the name of the directory containing input .m4a files.
                  # $2 should be the output directory.

                  INPUTDIR=$1
                  OUTPUTDIR=$2

                  <<"COMMENT"

                  # For ffmpeg arguments http://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg
                  # and
                  # https://kdecherf.com/blog/2012/01/14/ffmpeg-converting-m4a-files-to-mp3-with-the-same-bitrate/
                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume
                  # output: max_volume: -10.3 dB

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep 'max_volume|Duration'
                  # Output:
                  # Duration: 00:00:02.14, start: 0.000000, bitrate: 176 kb/s
                  # [Parsed_volumedetect_0 @ 0x7f8531e011a0] max_volume: -10.3 dB

                  ffmpeg -i test.m4a -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1
                  # Output: -10.3

                  ffmpeg -i test.m4a 2>&1 | grep Audio
                  # output: Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 170 kb/s (default)

                  ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
                  # output: 170

                  # This works, but I get a much smaller output file. The sound levels do appear normalized.
                  ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental output.m4a

                  # Operates quietly.
                  ffmpeg -i test.m4a -af "volume=10.3dB" -c:v copy -c:a aac -strict experimental -b:a 192k output.m4a -loglevel quiet

                  COMMENT

                  # $1 (first param) should be the name of a .m4a input file, with .m4a extension
                  # $2 should be name of output file, with extension
                  function normalizeAudioFile {
                  INPUTFILE=$1
                  OUTPUTFILE=$2

                  DBLEVEL=`ffmpeg -i ${INPUTFILE} -af "volumedetect" -f null /dev/null 2>&1 | grep max_volume | awk -F': ' '{print $2}' | cut -d' ' -f1`

                  # We're only going to increase db level if max volume has negative db level.
                  # Bash doesn't do floating comparison directly
                  COMPRESULT=`echo ${DBLEVEL}'<'0 | bc -l`
                  if [ ${COMPRESULT} -eq 1 ]; then
                  DBLEVEL=`echo "-(${DBLEVEL})" | bc -l`
                  BITRATE=`ffmpeg -i ${INPUTFILE} 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`

                  # echo $DBLEVEL
                  # echo $BITRATE

                  ffmpeg -i ${INPUTFILE} -af "volume=${DBLEVEL}dB" -c:v copy -c:a aac -strict experimental -b:a ${BITRATE}k ${OUTPUTFILE} -loglevel quiet

                  else
                  echo "Already at max db level:" $DBLEVEL "just copying exact file"
                  cp ${INPUTFILE} ${OUTPUTFILE}
                  fi
                  }

                  for inputFilePath in ${INPUTDIR}/*; do
                  inputFile=$(basename $inputFilePath)
                  echo "Processing input file: " $inputFile
                  outputFilePath=${OUTPUTDIR}/$inputFile
                  normalizeAudioFile ${inputFilePath} ${outputFilePath}
                  done






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 12 '15 at 4:57









                  Chris Prince

                  15112




                  15112






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Super User!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f323119%2fhow-can-i-normalize-audio-using-ffmpeg%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                      Alcedinidae

                      RAC Tourist Trophy