Comment puis-je normaliser l'audio en utilisant ffmpeg?

119

Je veux que le son de crête le plus fort dans un clip soit aussi fort que le permet le codec, puis que tous les autres sons soient amplifiés en conséquence.

Qu'est-ce qu'un exemple pratique pour accomplir cela en utilisant ffmpeg?

Jon Skarpeteig
la source
1
Vous souhaitez que l'audio soit «normalisé». J'ai trouvé ce fil et il y a plein de bonnes informations. J'espère que ça aide!
bobsbarricades

Réponses:

190

Option 1: filtres de normalisation intégrés

Current ffmpeg a deux filtres qui peuvent être directement utilisés pour la normalisation - bien qu’ils soient déjà assez avancés, ils ne se contentent donc pas d’appliquer un gain pour atteindre un niveau maximal. Les voici:

  • loudnorm: normalisation de la sonie selon EBU R128. Vous pouvez définir une cible de volume intégrée, une cible de plage de volume ou un pic maximal maximal. Ceci est recommandé pour la publication audio et vidéo et est utilisé par les diffuseurs du monde entier.
  • dynaudnorm: Normalisation «intelligente» de la sonie sans écrêtage, qui applique la normalisation de manière dynamique aux parties fenêtrées du fichier. Cela peut modifier les caractéristiques du son, il convient donc de l’appliquer avec prudence.

En outre, le volumefiltre peut être utilisé pour effectuer de simples ajustements de volume. Voir l' entrée du wiki Manipulation du volume audio pour plus d'informations.

Le loudnormfiltre peut être utilisé en une passe, mais il est recommandé d'effectuer deux passes, ce qui permet une normalisation linéaire plus précise. C'est un peu difficile à automatiser. De même, si vous souhaitez une normalisation «simple» basée sur RMS ou une normalisation de crête à 0 dBFS (ou toute autre cible), lisez la suite.


Option 2: Utiliser l' ffmpeg-normalizeoutil

J'ai créé un programme Python pour normaliser les fichiers multimédias , également disponible sur PyPi . Vous simplement:

  • téléchargez ffmpeg (choisissez une version statique , version 3.1 ou supérieure)
  • mettre l' ffmpegexécutable dans votre $PATHen l'ajoutant, par exemple /usr/local/bin, ou en ajoutant son répertoire à$PATH
  • Courir pip install ffmpeg-normalize
  • Utilisation ffmpeg-normalize

Par exemple:

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

Ou, simplement, normalisez par lots un certain nombre de fichiers audio et écrivez-les au format WAV non compressé dans un dossier de sortie:

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

L'outil prend en charge EBU R128 (par défaut), RMS et Peak. Jetez un œil à ffmpeg-normalize -hplus d'options et consultez le fichier README pour quelques exemples.

En outre, il prend en charge le ré-encodage avec d'autres encodeurs (par exemple, AAC ou MP3) ou la fusion automatique de l'audio dans la vidéo.


Option 3: Normaliser manuellement l’audio avec ffmpeg

Dans ffmpeg, vous pouvez utiliser le volumefiltre pour modifier le volume d’une piste. Assurez-vous de télécharger une version récente du programme.

Ce guide concerne la normalisation des pics , ce qui signifie que la partie la plus forte du fichier reste à 0 dB au lieu de quelque chose de plus bas. Il existe également une normalisation basée sur RMS qui essaie de rendre le volume moyen identique pour plusieurs fichiers. Pour ce faire, n'essayez pas de pousser le volume maximum à 0 dB, mais le volume moyen au niveau souhaité (par exemple -26 dB).

Découvrez le gain à appliquer

Vous devez d’abord analyser le flux audio pour déterminer le volume maximum et voir si la normalisation serait rentable:

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

Remplacez /dev/nullpar NULWindows.
Le -vn, -sn, et -dnarguments instruisent ffmpeg d'ignorer les flux audio non au cours de cette analyse. Cela accélère considérablement l'analyse.

Cela produira quelque chose comme ce qui suit:

[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

Comme vous pouvez le constater, notre volume maximal est de -5,0 dB. Nous pouvons donc appliquer un gain de 5 dB. Si vous obtenez une valeur de 0 dB, vous n'avez pas besoin de normaliser l'audio.

Appliquez le filtre de volume:

Maintenant, nous appliquons le volumefiltre à un fichier audio. Notez que l'application du filtre signifie que nous devrons ré-encoder le flux audio. Le codec que vous voulez pour l'audio dépend du format original, bien sûr. Voici quelques exemples:

  • Fichier audio simple: Il suffit d’encoder le fichier avec l’encodeur dont vous avez besoin:

    ffmpeg -i input.wav -af "volume=5dB" output.mp3
    

    Vos options sont très larges, bien sûr.

  • Format AVI: il existe généralement des fichiers audio MP3 avec vidéo dans un conteneur AVI:

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

    Ici, nous avons choisi le niveau de qualité 2. Les valeurs vont de 0 à 9 et moins signifie mieux. Consultez le guide MP3 VBR pour plus d’informations sur le réglage de la qualité. Vous pouvez également définir un débit fixe avec -b:a 192k, par exemple.

  • Format MP4: Avec un conteneur MP4, vous trouverez généralement l’audio AAC. Nous pouvons utiliser l'encodeur AAC intégré de ffmpeg.

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

    Ici, vous pouvez également utiliser d'autres encodeurs AAC. Certains d'entre eux supportent également VBR. Voir cette réponse et le guide de codage AAC pour des conseils.

Dans les exemples ci-dessus, le flux vidéo sera copié à l'aide de -c:v copy. S'il y a des sous-titres dans votre fichier d'entrée ou plusieurs flux vidéo, utilisez l'option -map 0devant le nom du fichier de sortie.

slhck
la source
Les commentaires ne sont pas pour une discussion prolongée; cette conversation a été déplacée pour discuter .
Journeyman Geek
7
C'est le cadeau qui continue à donner. 6 ans plus tard, il est toujours mis à jour et maintenu. Bien joué!
Jon Skarpeteig
L'option 3 évite-t-elle l'écrêtage si je configure le nouveau volume de sorte que max_volume vaut zéro? c'est-à-dire en utilisant la valeur initiale opposée donnée par max_volume
rraallvv
@rraallvv Oui, ça devrait. C'est également ce que fait l' ffmpeg-normalizeoutil lorsque vous spécifiez un niveau de 0 dB et une normalisation de crête.
Slhck
Pour utiliser le loudnormfiltre (ou autre):ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua
7

Je ne peux pas commenter le meilleur message, alors c’est ma laide bash qui me permet de le faire.

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| |\r\n|' original.tmp
 sed -i 's| |\r\n|' original.tmp
 sed -i 's| |\r\n|' original.tmp
 sed -i 's| |\r\n|' 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
Sébastien Willemijns
la source
5

Voici un script pour normaliser les niveaux sonores des fichiers .m4a. Faites attention si les niveaux sonores sont trop faibles pour commencer. Le son final peut être meilleur si vous utilisez quelque chose comme Audacity dans ce cas.

#!/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
Chris Prince
la source
-2

ffmpeg -i image.jpg -i "entrée.mp3" -acodec copie tmp.avi

mencoder -ovc copie -oac copie tmp.avi -de rawaudio -af volnorm = 1 -oac mp3lame -lameopts cbr: preset = 192 -srate 48000 -o "output.mp3"

rm -f tmp.avi

Maquelan Hurlement
la source
2
En comparant cela avec les autres réponses ici, j'espère qu'il est clair que votre message manque d'informations contextuelles et explicatives qui le rendraient utile. Qu'est-ce que "mencoder" et quel rôle joue-t-il dans la réponse à la question?
music2myear
2
Pourriez-vous modifier votre réponse afin d'expliquer pourquoi ce code répond à la question? Les réponses codées uniquement sont découragées car elles n'enseignent pas la solution.
DavidPostill