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


Je souhaite 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.

Quel est un exemple pratique pour accomplir ceci en utilisant ffmpeg?


87
2017-08-14 19:56


origine


Vous cherchez à avoir l'audio "normalisé". j'ai trouvé ce fil et il y a beaucoup de bonnes informations là-dedans. J'espère que cela aide! - bobsbarricades


Réponses:


Option 1: Filtres de normalisation intégrés

Le ffmpeg actuel a deux filtres qui peuvent être directement utilisés pour la normalisation - bien qu'ils soient déjà assez avancés, ils ne permettent donc pas simplement de réaliser un gain pour atteindre un niveau maximal. Les voici:

  • loudnorm: normalisation de la sonie selon EBU R128. Vous pouvez définir une cible de sonie intégrée, une cible de gamme de volume sonore ou un pic réel 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 dynamiquement aux parties du fichier fenêtrées. Cela peut changer les caractéristiques du son, il convient donc de l'appliquer avec prudence.

Également volume filtre peut être utilisé pour effectuer des ajustements de volume simples. Voir le Manipulation du volume audio Entrée wiki pour plus.

le loudnorm filtre peut être utilisé avec une seule 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 plus, si vous souhaitez une normalisation "simple" basée sur RMS ou maximale à 0 dBFS (ou toute autre cible), lisez la suite.


Option 2: utiliser le ffmpeg-normalize outil

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

  • télécharger ffmpeg (choisis un construction statique, version 3.1 ou supérieure)
  • mettre le ffmpeg exécutable dans votre $PATH soit en l'ajoutant, par exemple, /usr/local/bin, ou ajouter 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 pour normaliser par lots un certain nombre de fichiers audio et les écrire en tant que fichiers WAV non compressés 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. Jettes un coup d'oeil à ffmpeg-normalize -h pour plus d'options et vérifier la README pour quelques exemples.

En outre, il prend en charge le recodage 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 volume filtre pour modifier le volume d'une piste. Assurez-vous télécharger une version récente du programme.

Ce guide est pour de pointe la normalisation, ce qui signifie que la partie la plus forte du fichier sera placée à 0 dB au lieu de quelque chose de plus faible. Il existe également une normalisation basée sur RMS qui tente de faire la moyenne le volume est le même dans plusieurs fichiers. Pour ce faire, n'essayez pas de pousser le volume maximum à 0 dB, mais le volume moyen au niveau de choix en dB (par exemple -26 dB).

Découvrez le gain à appliquer

D'abord, vous devez analyser le flux audio pour obtenir le volume maximum pour voir si la normalisation serait rentable:

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

Remplacer /dev/null avec NUL sur Windows
le -vn, -sn, et -dn Les arguments indiquent à ffmpeg d'ignorer les flux non audio pendant cette analyse. Cela accélère considérablement l'analyse.

Cela va générer quelque chose comme ceci:

[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 maximum 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 volume filtre à un fichier audio. Notez que si vous appliquez le filtre, vous devrez ré-encoder le flux audio. Le codec que vous voulez pour l'audio dépend du format d'origine, bien sûr. Voici quelques exemples:

  • Fichier audio ordinaire: Il suffit de coder 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: Il y a généralement de l'audio MP3 avec une vidéo fournie 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. Vérifier la Guide MP3 VBR pour plus d'informations sur la définition 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 prennent également en charge VBR. Voir cette réponse et le Guide de codage AAC pour quelques conseils.

Dans les exemples ci-dessus, le flux vidéo sera copié en utilisant -c:v copy. S'il existe 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.


131
2017-08-14 20:11



Les commentaires ne sont pas destinés à une discussion approfondie; cette conversation a été déplacé pour discuter. - Journeyman Geek♦
C'est le cadeau qui continue à donner. 6 ans plus tard, il est toujours mis à jour et maintenu. Bien joué! - Jon Skarpeteig
@Jon Merci beaucoup! - slhck
L'option 3 évite-t-elle le découpage si je configure le nouveau volume pour que max_volume soit égal à zéro? c'est-à-dire en utilisant la valeur opposée initiale donnée par max_volume - rraallvv
@rraallvv Oui, ça devrait. C'est aussi ce que le ffmpeg-normalize Cet outil fonctionne lorsque vous spécifiez un niveau de 0 dB et une normalisation des pics. - slhck


Je ne peux pas commenter le meilleur message de sorte que ce soit mon bash laid sur la base 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

7
2018-05-19 14:51





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

5
2017-09-12 04:57