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

Jak mogę znormalizować dźwięk używając ffmpeg?

Chcę, aby najgłośniejszy szczytowy dźwięk w klipie filmowym był tak głośny, jak pozwala na to kodek, a następnie każdy inny dźwięk był odpowiednio wzmocniony.

Jaki jest praktyczny przykład, aby to osiągnąć używając ffmpeg?

Odpowiedzi (4)

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

Opcja 1: Wbudowane filtry normalizujące

Obecny ffmpeg ma dwa filtry, które mogą być bezpośrednio użyte do normalizacji - chociaż są one już dość zaawansowane, więc nie stosują po prostu wzmocnienia, aby osiągnąć poziom szczytowy. Oto one:

  • loudnorm : normalizacja głośności zgodnie z EBU R128. Można ustawić zintegrowany cel głośności, cel zakresu głośności lub maksymalny prawdziwy poziom szczytowy. Jest to zalecane dla publikowania audio i wideo i jest używane przez nadawców na całym świecie.
  • dynaudnorm : “inteligentna” normalizacja głośności bez obcinania, która stosuje normalizację dynamicznie nad okienkowymi fragmentami pliku. Może to zmienić charakterystykę dźwięku, więc powinno być stosowane z ostrożnością.

Również filtr volume może być użyty do wykonania prostej regulacji głośności. Zobacz wpis wiki Audio Volume Manipulation aby dowiedzieć się więcej.

Filtr loudnorm może być użyty z jednym przejściem, ale zalecane jest wykonanie dwóch przejść, co umożliwia dokładniejszą normalizację liniową. Jest to trochę trudne do zautomatyzowania. Ponadto, jeśli chcesz “prostej” normalizacji opartej na RMS lub normalizacji szczytowej do 0 dBFS (lub dowolnego innego celu), czytaj dalej.


Opcja 2: Użyj narzędzia ffmpeg-normalize

Stworzyłem program w Pythonie do normalizacji plików multimedialnych , dostępny również na PyPi . Wystarczy:

  • pobrać ffmpeg (wybrać static build, wersja 3. 1 lub wyższa)
  • umieścić plik wykonywalny ffmpeg w swoim katalogu $PATH, dodając go np. do /usr/local/bin lub dodając jego katalog do $PATH
  • uruchomić pip install ffmpeg-normalize
  • użyć ffmpeg-normalize

Na przykład:

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

Albo, aby po prostu znormalizować partiami pewną liczbę plików audio i zapisać je jako nieskompresowane WAV do folderu wyjściowego:

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

Narzędzie obsługuje EBU R128 (domyślnie), RMS i peak. Zajrzyj na stronę ffmpeg-normalize -h po więcej opcji i sprawdź README po kilka przykładów.

Wspiera również ponowne kodowanie za pomocą innych koderów (np. AAC lub MP3), lub automatyczne łączenie dźwięku z powrotem do wideo.


Opcja 3: Ręczna normalizacja dźwięku za pomocą ffmpeg

W ffmpeg możesz użyć filtra volume do zmiany głośności ścieżki. Upewnij się, że pobierzesz najnowszą wersję programu.

Ten przewodnik jest dla szczytowej normalizacji, co oznacza, że sprawi, że najgłośniejszy fragment w pliku będzie miał 0 dB zamiast czegoś niższego. Istnieje również normalizacja oparta na RMS, która próbuje uczynić średnią głośność taką samą w wielu plikach. Aby to zrobić, nie staraj się przesunąć maksymalnej głośności do 0 dB, ale średnią głośność do wybranego poziomu dB (np. -26 dB).

Ustal wzmocnienie, jakie należy zastosować

Najpierw należy przeanalizować strumień audio pod kątem maksymalnej głośności, aby sprawdzić, czy normalizacja w ogóle się opłaci:

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

Zamień /dev/null na NUL w systemie Windows.
Argumenty -vn , -sn i -dn nakazują ffmpegowi ignorowanie strumieni innych niż audio podczas tej analizy. To drastycznie przyspiesza analizę.

Spowoduje to wyświetlenie czegoś takiego jak poniżej:

[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

Jak widać, nasza maksymalna głośność wynosi -5,0 dB, więc możemy zastosować wzmocnienie 5 dB. Jeśli uzyskamy wartość 0 dB, to nie ma potrzeby normalizowania dźwięku.

Zastosuj filtr głośności:

Teraz zastosujemy filtr volume do pliku audio. Zauważ, że zastosowanie filtra oznacza, że będziemy musieli ponownie zakodować strumień audio. To, jaki kodek chcesz zastosować dla dźwięku, zależy oczywiście od jego oryginalnego formatu. Oto kilka przykładów:

  • Plain audio file: Po prostu zakoduj plik za pomocą dowolnego kodera, którego potrzebujesz:

  • FormatAVI: Zwykle jest tam dźwięk MP3 z wideo, które jest w kontenerze AVI:

  • Format MP4: Z kontenerem MP4, zwykle znajdziesz dźwięk AAC. Możemy użyć wbudowanego w ffmpeg kodera AAC.

W powyższych przykładach, strumień wideo zostanie skopiowany przy użyciu -c:v copy. Jeśli w pliku wejściowym są napisy lub wiele strumieni wideo, użyj opcji -map 0 przed nazwą pliku wyjściowego.

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

Nie mogę skomentować najlepszej wiadomości, więc to jest mój brzydki bash oparty na nim, aby to zrobić

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

Oto skrypt do normalizacji poziomów dźwięku w plikach .m4a. Uważaj, jeśli poziomy dźwięku są zbyt ciche na początku. Ostateczny dźwięk może być lepszy, jeśli użyjesz czegoś takiego jak Audacity w takim przypadku.

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