Audio in Video normalisieren mit ffmpeg

Manchmal ist das Audio in einem Video relativ leise und eigentlich ist da noch richtig Luft nach oben es lauter zu machen. Ein schöner und sehr eleganter Weg ist es mit ffmpeg die Normalisierungsfunktion zu nutzen, ohne das Video selbst erneut zu encoden. Das Audio muss natürlich neu encoded werden.

Zuerst muss ermittelt werden welches der lauteste Peak (lauteste Stelle) im gesamten Audio ist

Lautstärkenermittlung – Highest Peak

ffmpeg -i Videodatei.mp4 -af "volumedetect" -vn -sn -dn -f null /dev/null

Dann steht in der Ausgabe irgendwo relativ weit oben so etwas:

[Parsed_volumedetect_0 @ 0x00000000000] mean_volume: -29.1 dB
[Parsed_volumedetect_0 @ 0x00000000000] max_volume: -3.6 dB

Das „max_volume mit -3.6 dB“ ist das Interessante für uns. Das maximale Level in der digitalen Welt ist 0dB . Alles was darüber „gedrückt“ wird, wird sehr hässlich verzerrt. Das sollte unbedingt vermieden werden!!

Lautstärkenlimit beachten!

Und vielleicht ein kleiner Sicherheitsabstand wäre auch noch ganz gut, denn beim Umwandeln über D/A (Digital/Analog) Wandler passieren auch je nach Qualität manchmal merkwürdige Dinge. Stichwort Truepeak bzw True Inter-Sample Peak Level.
Also als Empfehlung wäre hier einen Puffer von 0,5 dB bis 1 dB einzuhalten.

In unserem Beispiel von „max_volume mit -3.6 dB“ nehmen wir mal einen Puffer von 1 dB, das würde dann heissen, dass wir das max_volume um 2.6dB erhöhen: -3.6+2.6= -1dB Ziellautstärke

Lautstärkenanhebung

Der Befehl dazu lautet (Ziel Audioformat: AAC)
ffmpeg -i Videodatei.mp4 -af "volume=2.6dB" -c:v copy -c:a aac -b:a 192k VideodateiErgebnis.mp4

Alias und Function

Und in der Shell Bash ist das natürlich schöner mit einem kurzen Alias aufzurufen. Aber ein Alias ist nur ein anderer Name für ein bestehender Name. Also könnte ich dem Programm Ulrike den Namen Peter geben und egal, welchen Namen ich jetzt eingebe Ulrike oder Peter, das selbe Programm wird ausgeführt.

Da sich hier aber Aufrufparameter, wie Videodatei und die 2.6dB handelt, reicht ein Alias nicht. Dafür gibt es in der Bash die Function. Hier können dann auch die Aufrufparameter abgefragt werden.

Diese Functions weiter unten gelten immer nur für die aktuelle Session. Sobald das Fenster geschlossen oder die Bash beendet wird, ist auch die Function gelöscht. Soll die Function für immer bleiben, muss sie in der Datei .~bashrc im eigenen Homeverzeichnis definiert werden.

Lautstärke herausfinden

Der Aufruf sieht so aus myMaxvol Videodatei.mp4

myMaxvol() { ffmpeg -i "$1" -af "volumedetect" -vn -sn -dn -f null /dev/null; }

Lautstärke anheben

Der Aufruf sieht so aus: myGainvol Videodatei.mp4 2.6

myGainvol() { ffmpeg -i "$1" -af "volume=""$2""dB" -c:v copy -c:a aac -b:a 192k output.mp4 && mv output.mp4 "$1" ; }

Erklärung was hier passiert: Es wird als Parameter Videodatei.mp4 und 2.6 als Lautstärkenanhebung mitgegeben. Das Ergebnis wird in eine Datei namens output.mp4 geschrieben. Wenn die Lautstärkenanhebung erfolgreich war, dann wird die Datei output.mp4 umbenannt in die Videodatei.mp4, die damit natürlich überschrieben wird.

Wenn die Aktion schief läuft, dann liegt da eine Datei output.mp4 herum und noch die originale Datei Videodatei.mp4.

Bash Script

Vielleicht bastle ich noch ein kleine Bash Script, das automatisch die Lautstärke ermittelt, dann auch automatisch die Anhebung ermittelt und danach gleich die Lautstärkenanhebung durchführt. Und dann das ganze noch auf ein ganzes Verzeichnis anwendet.

Schaumermal.