2011-08-14 19:56:01 +0000 2011-08-14 19:56:01 +0000
125
125

Wie kann ich Audio mit ffmpeg normalisieren?

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

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

Antworten (4)

202
202
202
2011-08-14 20:11:03 +0000

Option 1: Eingebaute Normalisierungsfilter

Aktuell verfügt ffmpeg über zwei Filter, die direkt zur Normalisierung verwendet werden können - obwohl sie schon recht fortschrittlich sind, also nicht einfach Verstärkung anwenden, um einen Spitzenwert zu erreichen. Hier sind sie:

  • loudnorm : Lautheitsnormalisierung gemäß EBU R128. Sie können ein integriertes Loudness-Ziel, ein Loudness-Bereichsziel oder den maximalen wahren Spitzenwert einstellen. Dies wird für die Veröffentlichung von Audio und Video empfohlen und wird von Rundfunkanstalten auf der ganzen Welt verwendet.
  • dynaudnorm : “intelligente” Lautheitsnormalisierung ohne Clipping, bei der die Normalisierung dynamisch auf gefensterte Teile der Datei angewendet wird. Dies kann die Charakteristik des Klangs verändern, daher sollte es mit Vorsicht angewendet werden.

Außerdem kann der Filter volume verwendet werden, um einfache Lautstärkeanpassungen vorzunehmen. Weitere Informationen finden Sie im Wiki-Eintrag Audio Volume Manipulation .

Der loudnorm-Filter kann mit einem Durchgang verwendet werden, aber es wird empfohlen, zwei Durchgänge durchzuführen, was eine genauere lineare Normalisierung ermöglicht. Dies ist ein wenig schwer zu automatisieren. Wenn Sie außerdem eine “einfache” RMS-basierte oder Spitzenwert-Normalisierung auf 0 dBFS (oder ein anderes Ziel) wünschen, lesen Sie weiter.


Option 2: Verwenden Sie das ffmpeg-normalize Tool

Ich habe ein Python-Programm zur Normalisierung von Mediendateien erstellt, das auch auf PyPi verfügbar ist . Sie müssen nur:

  • ffmpeg herunterladen (wählen Sie ein static build, Version 3. 1 oder höher)
  • fügen Sie die ausführbare Datei ffmpeg in Ihr $PATH ein, indem Sie sie z. B. in /usr/local/bin einfügen oder sein Verzeichnis zu $PATH hinzufügen
  • führen Sie pip install ffmpeg-normalize aus

  • verwenden Sie ffmpeg-normalize

Zum Beispiel:

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

Oder, um einfach eine Anzahl von Audiodateien im Stapel zu normalisieren und sie als unkomprimierte 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. Schauen Sie sich ffmpeg-normalize -h für weitere Optionen an und lesen Sie die README für einige Beispiele.

Außerdem unterstützt es das Re-Encoding mit anderen Encodern (z. B. AAC oder MP3) oder das automatische Zusammenführen des Audios zurück ins Video.


Option 3: Manuelles Normalisieren von Audio mit ffmpeg

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

Diese Anleitung ist für die Peak-Normalisierung, was bedeutet, dass der lauteste Teil in der Datei auf 0 dB gesetzt wird, statt auf einen niedrigeren Wert. Es gibt auch eine RMS-basierte Normalisierung, die versucht, die durchschnittliche Lautheit über mehrere Dateien hinweg gleich zu machen. Dazu wird nicht versucht, die maximale Lautstärke auf 0 dB zu drücken, sondern die mittlere Lautstärke auf den gewünschten dB-Wert (z. B. -26 dB).

Ermitteln Sie die anzuwendende Verstärkung

Zuerst müssen Sie den Audiostrom auf die maximale Lautstärke analysieren, um zu sehen, ob sich eine Normalisierung überhaupt lohnt:

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

Ersetzen Sie /dev/null durch NUL unter Windows.
Die Argumente -vn , -sn und -dn weisen ffmpeg an, Nicht-Audio-Streams während dieser Analyse zu ignorieren. Dadurch wird die Analyse drastisch beschleunigt.

Dies gibt etwas wie das Folgende aus:

[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 können, ist unsere maximale Lautstärke -5,0 dB, also können wir 5 dB Verstärkung anwenden. Wenn Sie einen Wert von 0 dB erhalten, dann brauchen Sie das Audio nicht zu normalisieren.

Anwenden des Lautstärkefilters:

Jetzt wenden wir den volume Filter auf eine Audiodatei an. Beachten Sie, dass das Anwenden des Filters bedeutet, dass wir den Audiostrom neu codieren müssen. Welchen Codec Sie für Audio verwenden wollen, hängt natürlich vom Originalformat ab. Hier sind einige Beispiele:

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

  • AVI-Format: Normalerweise gibt es MP3-Audio bei Videos, die in einem AVI-Container kommen:

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

In den obigen Beispielen wird der Videostream mit -c:v copy umkopiert. Wenn in Ihrer Eingabedatei Untertitel oder mehrere Videostreams vorhanden sind, verwenden Sie die Option -map 0 vor dem Ausgabedateinamen.

7
7
7
2016-05-19 14:51:16 +0000

Ich kann nicht auf die beste Nachricht zu kommentieren, so dass ist meine hässliche Bash auf der Grundlage es zu tun, dass

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
5
5
5
2015-09-12 04:57:30 +0000

Hier ist ein Skript zum Normalisieren der Tonpegel von .m4a-Dateien. Achten Sie darauf, ob die Tonpegel anfangs zu leise sind. Der endgültige Klang kann besser sein, wenn Sie in diesem Fall 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
-2
-2
-2
2019-03-21 20:27:43 +0000

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