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?
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 s’appliquent pas simplement pour obtenir un gain afin d’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 de volume «intelligent» sans découpage, 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 filtre volume
peut être utilisé pour effectuer de simples ajustements de volume. Voir l’entrée wiki Audio Volume Manipulation pour plus d’informations.
Le filtre loudnorm
peut être utilisé avec un seul passage, mais il est recommandé d'effectuer deux passages, 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.
ffmpeg-normalize
J'ai créé un programme Python pour normaliser les fichiers multimédias , disponible sur PyPi également . Vous simplement:
ffmpeg
dans votre $PATH
en l'ajoutant, par exemple, à /usr/local/bin
ou en ajoutant son répertoire à $PATH
pip install ffmpeg-normalize
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 (valeur par défaut), RMS et Peak. Jetez un coup d'œil à ffmpeg-normalize -h
pour plus d'options et examinez 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.
ffmpeg
Dans ffmpeg, vous pouvez utiliser le filtre volume
pour modifier le volume d’une piste. Assurez-vous de télécharger une version récente du programme.
Ce guide concerne la normalisation crête, 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 la sonorité moyenne identique sur plusieurs fichiers. Pour ce faire, n'essayez pas de pousser le volume maximum à 0 dB, mais le volume moyen au niveau de dB souhaité (par exemple -26 dB).
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/null
par NUL
sous Windows.
Les arguments -vn
, -sn
et -dn
indiquent à ffmpeg d'ignorer les flux non audio 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.
Nous appliquons maintenant le filtre volume
à 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 standard: Encodez simplement le fichier avec le codeur dont vous avez besoin:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Vos options sont très larges, bien sûr.
Format AVI: Généralement, les fichiers audio MP3 avec vidéo sont fournis 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 binaire 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 this answer et le AAC encoding guide pour quelques astuces.
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 0
avant le nom du fichier de sortie.
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
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