Wie kann ich Audio mit ffmpeg normalisieren?

119

Ich möchte, dass der lauteste Spitzensound in einem Movieclip so laut ist, wie es der Codec zulässt, und dass dann jeder andere Sound entsprechend verstärkt wird.

Was ist ein praktisches Beispiel, um dies mit ffmpeg zu erreichen?

Jon Skarpeteig
quelle
1
Sie möchten, dass der Ton "normalisiert" wird. Ich habe diesen Thread gefunden und es gibt dort viele gute Informationen. Ich hoffe es hilft!
bobsbarricades

Antworten:

190

Option 1: Eingebaute Normalisierungsfilter

Das aktuelle ffmpeg verfügt über zwei Filter, die direkt für die Normalisierung verwendet werden können - obwohl sie bereits ziemlich weit fortgeschritten sind, wenden sie also nicht einfach die Verstärkung an, um einen Spitzenpegel zu erreichen. Hier sind sie:

  • loudnorm: Lautheitsnormalisierung nach EBU R128. Sie können ein integriertes Lautstärkeziel, ein Lautstärkebereichsziel oder eine maximale wahre Spitze festlegen. Dies wird für die Veröffentlichung von Audio- und Videodaten empfohlen und von Rundfunkveranstaltern auf der ganzen Welt verwendet.
  • dynaudnorm: „Intelligente“ Normalisierung der Lautstärke ohne Übersteuerung, bei der die Normalisierung dynamisch auf Fensterbereiche der Datei angewendet wird. Dies kann die Klangcharakteristik verändern, weshalb Vorsicht geboten ist.

Mit dem volumeFilter können auch einfache Lautstärkeeinstellungen vorgenommen werden. Weitere Informationen finden Sie im Wiki-Eintrag Audio Volume Manipulation .

Der loudnormFilter kann mit einem Durchgang verwendet werden, es wird jedoch empfohlen, zwei Durchgänge durchzuführen, um eine genauere lineare Normalisierung zu ermöglichen. Dies ist etwas schwer zu automatisieren. Wenn Sie eine "einfache" RMS-basierte Normalisierung oder Spitzennormalisierung auf 0 dBFS (oder ein anderes Ziel) wünschen, lesen Sie weiter.


Option 2: Verwenden Sie das ffmpeg-normalizeTool

Ich habe ein Python-Programm zum Normalisieren von Mediendateien erstellt , das auch auf PyPi verfügbar ist . Sie einfach:

Zum Beispiel:

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

Oder, um einfach eine Reihe von Audiodateien im Stapel zu normalisieren und sie als unkomprimiertes WAV in einen Ausgabeordner zu schreiben:

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

Das Tool unterstützt EBU R128 (Standard), RMS und Peak. Werfen Sie einen Blick auf ffmpeg-normalize -hmehr Möglichkeiten für und überprüfen Sie die Readme für einige Beispiele.

Es unterstützt auch das Neukodieren mit anderen Kodierern (z. B. AAC oder MP3) oder das automatische Zusammenführen der Audiodaten mit dem Video.


Option 3: Audio manuell normalisieren mit ffmpeg

In ffmpeg können Sie den volumeFilter verwenden, um die Lautstärke einer Spur zu ändern. Stellen Sie sicher, dass Sie eine aktuelle Version des Programms herunterladen .

Diese Anleitung dient zur Normalisierung von Spitzenwerten , dh, der lauteste Teil der Datei wird auf 0 dB anstatt auf etwas Niedrigeres eingestellt. Es gibt auch eine RMS-basierte Normalisierung, die versucht, die durchschnittliche Lautstärke für mehrere Dateien gleich zu machen. Versuchen Sie dazu nicht, die maximale Lautstärke auf 0 dB zu stellen, sondern die mittlere Lautstärke auf den gewünschten dB-Pegel (z. B. -26 dB).

Finden Sie den zu verwendenden Gewinn heraus

Zuerst müssen Sie den Audiostream auf die maximale Lautstärke untersuchen, um festzustellen, ob sich das Normalisieren überhaupt auszahlt:

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

Ersetzen Sie /dev/nullunter NULWindows durch.
Das -vn, -snund -dnArgumente anweisen ffmpeg zu ignorieren Nicht-Audio - Streams während dieser Analyse. Dies beschleunigt die Analyse drastisch.

Dadurch wird etwa Folgendes ausgegeben:

[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

Wie Sie sehen, beträgt unsere maximale Lautstärke -5,0 dB, sodass wir eine Verstärkung von 5 dB anwenden können. Wenn Sie einen Wert von 0 dB erhalten, müssen Sie das Audio nicht normalisieren.

Wenden Sie den Volumenfilter an:

Jetzt wenden wir den volumeFilter auf eine Audiodatei an. Beachten Sie, dass das Anwenden des Filters bedeutet, dass wir den Audiostream neu codieren müssen. Welcher Codec für Audio gewünscht wird, hängt natürlich vom Originalformat ab. Hier sind einige Beispiele:

  • Einfache Audiodatei: Codieren Sie die Datei einfach mit dem von Ihnen benötigten Encoder:

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

    Ihre Möglichkeiten sind natürlich sehr breit.

  • AVI-Format: Normalerweise ist MP3-Audio mit Video in einem AVI-Container enthalten:

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

    Hier haben wir die Qualitätsstufe 2 gewählt. Werte zwischen 0 und 9 bedeuten besser. Weitere Informationen zum Einstellen der Qualität finden Sie im MP3 VBR-Handbuch . Sie können beispielsweise auch eine feste Bitrate einstellen -b:a 192k.

  • MP4-Format: Bei einem MP4-Container finden Sie normalerweise AAC-Audio. Wir können den eingebauten AAC-Encoder von ffmpeg verwenden.

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

    Hier können Sie auch andere AAC-Geber verwenden. Einige von ihnen unterstützen auch VBR. In dieser Antwort und im AAC-Codierungshandbuch finden Sie einige Tipps.

In den obigen Beispielen wird der Videostream mit kopiert -c:v copy. Wenn Ihre Eingabedatei Untertitel oder mehrere Videostreams enthält, verwenden Sie die Option -map 0vor dem Ausgabedateinamen.

slhck
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Geselle Geek
7
Dies ist das Geschenk, das immer weiter gibt. 6 Jahre später, und es wird immer noch aktualisiert und gewartet. Gut gemacht!
Jon Skarpeteig
Vermeidet Option 3 das Beschneiden, wenn ich das neue Volume so einstelle, dass max_volume Null ist? dh mit dem entgegengesetzten Wert initial von max_volume
rraallvv 26.10.17
@rraallvv Ja, das sollte es. Das macht das ffmpeg-normalizeTool auch, wenn Sie einen Pegel von 0 dB und eine Spitzennormalisierung festlegen.
Slhck
So verwenden Sie den loudnorm(oder einen anderen) Filter:ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua vor
7

Ich kann die beste Nachricht nicht kommentieren, so dass meine hässliche Bash darauf basiert, das zu tun

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
Sebastien Willemijns
quelle
5

Hier ist ein Skript zum Normalisieren der Lautstärke von .m4a-Dateien. Achten Sie darauf, dass die Lautstärke zu leise ist. Der endgültige Sound kann besser sein, wenn Sie in diesem Fall so etwas wie Audacity verwenden.

#!/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
quelle
-2

ffmpeg -i image.jpg -i "input.mp3" -acodec copy tmp.avi

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

rm -f tmp.avi

Maquelan Howl
quelle
2
Wenn ich das mit den anderen Antworten hier vergleiche, hoffe ich, dass es Ihrem Beitrag an kontextbezogenen und erklärenden Informationen mangelt, die es nützlich machen würden. Was ist "Mencoder" und welche Rolle spielt er bei der Beantwortung der Frage?
music2myear
2
Könnten Sie bitte Ihre Antwort bearbeiten , um zu erklären, warum dieser Code die Frage beantwortet? Nur-Code-Antworten werden nicht empfohlen , da sie die Lösung nicht vermitteln.
DavidPostill