Chcę, aby najgłośniejszy dźwięk szczytowy w klipie filmowym był tak głośny, na jaki pozwala kodek, a następnie odpowiednio wzmacniał każdy inny dźwięk.
Jaki jest praktyczny przykład, aby to osiągnąć za pomocą ffmpeg?
Chcę, aby najgłośniejszy dźwięk szczytowy w klipie filmowym był tak głośny, na jaki pozwala kodek, a następnie odpowiednio wzmacniał każdy inny dźwięk.
Jaki jest praktyczny przykład, aby to osiągnąć za pomocą ffmpeg?
Odpowiedzi:
Obecny ffmpeg ma dwa filtry, których można bezpośrednio użyć do normalizacji - chociaż są one już dość zaawansowane, więc nie stosują tylko wzmocnienia, aby osiągnąć poziom szczytowy. Tutaj są:
loudnorm
: normalizacja głośności zgodnie z EBU R128. Możesz ustawić zintegrowany docelowy poziom głośności, docelowy zakres głośności lub maksymalny prawdziwy szczyt. Jest to zalecane do publikowania audio i wideo i jest wykorzystywane przez nadawców na całym świecie.dynaudnorm
: „Inteligentna” normalizacja głośności bez obcinania, która dynamicznie stosuje normalizację do okienkowanych części pliku. Może to zmienić charakterystykę dźwięku, dlatego należy zachować ostrożność.Ponadto, volume
filtr może być używany do wykonywania prostych regulacji głośności. Zobacz wpis wiki Manipulacja głośnością audio, aby uzyskać więcej.
loudnorm
Filtr może być stosowany z jednym przejściem, ale zaleca się, aby wykonać dwa cykle, które umożliwia bardziej precyzyjne normalizację liniowej. Jest to trochę trudne do zautomatyzowania. Ponadto, jeśli chcesz „prostej” opartej na RMS lub szczytowej normalizacji do 0 dBFS (lub dowolnego innego celu), czytaj dalej.
ffmpeg-normalize
narzędziaStworzyłem program Python do normalizacji plików multimedialnych , dostępny również na PyPi . Po prostu:
ffmpeg
plik wykonywalny w swoim pliku, $PATH
dodając go na przykład /usr/local/bin
lub dodając do niego katalog$PATH
pip install ffmpeg-normalize
ffmpeg-normalize
Na przykład:
ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k
Lub, aby zwyczajnie wsadowo znormalizować kilka plików audio i zapisać je jako nieskompresowany plik 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. Sprawdź ffmpeg-normalize -h
więcej opcji i sprawdź README, aby zobaczyć kilka przykładów.
Ponadto obsługuje ponowne kodowanie za pomocą innych koderów (np. AAC lub MP3) lub automatyczne scalanie audio z powrotem w wideo.
ffmpeg
W ffmpeg możesz użyć volume
filtra, aby zmienić głośność ścieżki. Upewnij się, że pobierasz najnowszą wersję programu.
Ten przewodnik służy do normalizacji szczytów , co oznacza, że najgłośniejsza część pliku będzie ustawiona na 0 dB zamiast czegoś niższego. Istnieje również normalizacja oparta na RMS, która stara się, aby średnia głośność była taka sama dla wielu plików. Aby to zrobić, nie próbuj zwiększać maksymalnej głośności do 0 dB, ale średnią głośność do wybranego poziomu dB (np. -26 dB).
Najpierw musisz przeanalizować strumień audio pod kątem maksymalnej głośności, aby zobaczyć, czy normalizacja się w ogóle opłaciłaby:
ffmpeg -i video.avi -af "volumedetect" -vn -sn -dn -f null /dev/null
Wymień /dev/null
się NUL
w systemie Windows.
Argumenty -vn
, -sn
i -dn
instruują ffmpeg, aby ignorował strumienie inne niż audio podczas tej analizy. To drastycznie przyspiesza analizę.
Spowoduje to wyświetlenie czegoś takiego:
[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 uzyskasz wartość 0 dB, nie musisz normalizować dźwięku.
Teraz stosujemy volume
filtr do pliku audio. Pamiętaj, że zastosowanie filtra oznacza, że będziemy musieli ponownie zakodować strumień audio. Wybór kodeku audio zależy oczywiście od jego oryginalnego formatu. Oto kilka przykładów:
Zwykły plik audio: wystarczy zakodować plik dowolnym koderem, którego potrzebujesz:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Twoje opcje są oczywiście bardzo szerokie.
Format AVI: zazwyczaj w formacie AVI jest plik audio MP3 z wideo:
ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
Tutaj wybraliśmy poziom jakości 2. Zakres wartości od 0–9 i niższy oznacza lepszy. Sprawdź MP3 VBR instrukcji , aby uzyskać więcej informacji na temat ustawiania jakości. Możesz także ustawić na przykład stały bitrate -b:a 192k
za pomocą.
Format MP4: W kontenerze MP4 zwykle znajdziesz dźwięk AAC. Możemy użyć wbudowanego kodera AAC ffmpeg.
ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4
Tutaj możesz także użyć innych koderów AAC. Niektóre z nich obsługują również VBR. Zobacz tę odpowiedź i przewodnik po kodowaniu AAC, aby uzyskać kilka wskazówek.
W powyższych przykładach strumień wideo zostanie skopiowany za pomocą -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.
ffmpeg-normalize
narzędzie, gdy określisz poziom 0 dB i szczytową normalizację.
Nie mogę komentować najlepszej wiadomości, więc jest to mój brzydki bash oparty na tym, 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
Oto skrypt normalizujący poziomy dźwięku plików .m4a. Uważaj, czy poziomy głośności są zbyt ciche, aby zacząć. Ostateczny dźwięk może być lepszy, jeśli w takim przypadku użyjesz czegoś takiego jak Audacity.
#!/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
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 -sate 48000 -o "output.mp3"
rm -f tmp.avi