Tôi muốn âm thanh đỉnh lớn nhất trong một đoạn phim phát ra lớn như codec cho phép, sau đó có mọi âm thanh khác được khuếch đại tương ứng.
Một ví dụ thực tế để thực hiện điều này bằng cách sử dụng ffmpeg là gì?
Tôi muốn âm thanh đỉnh lớn nhất trong một đoạn phim phát ra lớn như codec cho phép, sau đó có mọi âm thanh khác được khuếch đại tương ứng.
Một ví dụ thực tế để thực hiện điều này bằng cách sử dụng ffmpeg là gì?
Câu trả lời:
Ffmpeg hiện tại có hai bộ lọc có thể được sử dụng trực tiếp để chuẩn hóa - mặc dù chúng đã khá tiên tiến, vì vậy chúng không chỉ đơn giản áp dụng mức tăng để đạt mức cao nhất. Họ đây rồi:
loudnorm
: chuẩn hóa độ ồn theo EBU R128. Bạn có thể đặt mục tiêu độ ồn tích hợp, mục tiêu phạm vi âm lượng hoặc mức cực đại thực sự tối đa. Điều này được khuyến nghị để xuất bản âm thanh và video và nó được sử dụng bởi các đài truyền hình trên toàn thế giới.dynaudnorm
: Chuẩn hóa độ ồn thông minh mà không bị cắt, mà áp dụng chuẩn hóa động trên các phần cửa sổ của tệp. Điều này có thể thay đổi các đặc tính của âm thanh, vì vậy nó nên được áp dụng một cách thận trọng.Ngoài ra, volume
bộ lọc có thể được sử dụng để thực hiện điều chỉnh âm lượng đơn giản. Xem mục wiki Thao tác âm lượng âm thanh để biết thêm.
Bộ loudnorm
lọc có thể được sử dụng với một lần vượt qua, nhưng nên thực hiện hai lần qua, cho phép chuẩn hóa tuyến tính chính xác hơn. Điều này là một chút khó khăn để tự động hóa. Ngoài ra, nếu bạn muốn một chuẩn hóa đơn giản hoặc dựa trên đỉnh RMS đơn giản của RMS thành 0 dBFS (hoặc bất kỳ mục tiêu nào khác), hãy đọc tiếp.
ffmpeg-normalize
công cụTôi đã tạo một chương trình Python để chuẩn hóa các tệp phương tiện , cũng có sẵn trên PyPi . Bạn đơn giản:
ffmpeg
tệp thực thi vào của bạn $PATH
bằng cách thêm nó vào, ví dụ /usr/local/bin
, hoặc thêm thư mục của nó vào$PATH
pip install ffmpeg-normalize
ffmpeg-normalize
Ví dụ:
ffmpeg-normalize input.mp4 -o output.mp4 -c:a aac -b:a 192k
Hoặc, chỉ đơn giản là chuẩn hóa hàng loạt một số tệp âm thanh và ghi chúng dưới dạng WAV không nén vào thư mục đầu ra:
ffmpeg-normalize *.m4a -of /path/to/outputFolder -ext wav
Công cụ hỗ trợ EBU R128 (mặc định), RMS và đỉnh. Hãy xem ffmpeg-normalize -h
để có thêm tùy chọn và kiểm tra README cho một số ví dụ.
Ngoài ra, nó hỗ trợ mã hóa lại với các bộ mã hóa khác (ví dụ AAC hoặc MP3) hoặc tự động hợp nhất âm thanh trở lại vào video.
ffmpeg
Trong ffmpeg, bạn có thể sử dụng volume
bộ lọc để thay đổi âm lượng của bản nhạc. Hãy chắc chắn rằng bạn tải xuống một phiên bản gần đây của chương trình.
Hướng dẫn này là để chuẩn hóa tối đa , có nghĩa là nó sẽ làm cho phần to nhất trong tệp nằm ở 0 dB thay vì một cái gì đó thấp hơn. Ngoài ra còn có chuẩn hóa dựa trên RMS cố gắng làm cho độ ồn trung bình giống nhau trên nhiều tệp. Để làm điều đó, đừng cố đẩy âm lượng tối đa đến 0 dB, nhưng âm lượng trung bình đến mức dB được chọn (ví dụ -26 dB).
Trước tiên, bạn cần phân tích luồng âm thanh cho âm lượng tối đa để xem nếu bình thường hóa thậm chí sẽ trả hết:
ffmpeg -i video.avi -af "volumedetect" -vn -sn -dn -f null /dev/null
Thay thế /dev/null
bằng NUL
trên Windows.
Các -vn
, -sn
và các -dn
đối số hướng dẫn ffmpeg bỏ qua các luồng không âm thanh trong quá trình phân tích này. Điều này quyết liệt tăng tốc độ phân tích.
Điều này sẽ tạo ra một cái gì đó như sau:
[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
Như bạn có thể thấy, âm lượng tối đa của chúng tôi là -5.0 dB, vì vậy chúng tôi có thể áp dụng mức tăng 5 dB. Nếu bạn nhận được giá trị 0 dB, thì bạn không cần phải chuẩn hóa âm thanh.
Bây giờ chúng tôi áp dụng volume
bộ lọc cho một tập tin âm thanh. Lưu ý rằng áp dụng bộ lọc có nghĩa là chúng ta sẽ phải mã hóa lại luồng âm thanh. Tất nhiên, loại codec nào bạn muốn cho âm thanh phụ thuộc vào định dạng ban đầu. Dưới đây là một số ví dụ:
Tệp âm thanh đơn giản: Chỉ cần mã hóa tệp bằng bất kỳ bộ mã hóa nào bạn cần:
ffmpeg -i input.wav -af "volume=5dB" output.mp3
Lựa chọn của bạn là rất rộng, tất nhiên.
Định dạng AVI: Thông thường có âm thanh MP3 với video đi kèm trong thùng chứa AVI:
ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
Ở đây chúng tôi đã chọn mức chất lượng 2. Giá trị nằm trong khoảng từ 0 trừ9 và thấp hơn có nghĩa là tốt hơn. Kiểm tra hướng dẫn MP3 VBR để biết thêm thông tin về cài đặt chất lượng. Bạn cũng có thể đặt bitrate cố định với -b:a 192k
, ví dụ.
Định dạng MP4: Với bộ chứa MP4, thông thường bạn sẽ tìm thấy âm thanh AAC. Chúng tôi có thể sử dụng bộ mã hóa AAC tích hợp của ffmpeg.
ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4
Tại đây bạn cũng có thể sử dụng các bộ mã hóa AAC khác. Một số trong số họ hỗ trợ VBR, quá. Xem câu trả lời này và hướng dẫn mã hóa AAC để biết một số mẹo.
Trong các ví dụ trên, luồng video sẽ được sao chép qua sử dụng -c:v copy
. Nếu có phụ đề trong tệp đầu vào của bạn hoặc nhiều luồng video, hãy sử dụng tùy chọn -map 0
trước tên tệp đầu ra.
ffmpeg-normalize
công cụ làm, khi bạn chỉ định mức 0 dB và mức chuẩn hóa cao nhất.
loudnorm
bộ lọc (hoặc khác):ffmpeg -i input.wav -filter:a loudnorm output.wav
Tôi không thể nhận xét về thông điệp tốt nhất vì vậy đó là bash xấu xí của tôi dựa trên nó để làm điều đó
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
Đây là một tập lệnh để bình thường hóa mức âm thanh của các tệp .m4a. Xem ra nếu mức độ âm thanh quá yên tĩnh để bắt đầu. Âm thanh cuối cùng có thể tốt hơn nếu bạn sử dụng thứ gì đó như Audacity trong trường hợp đó.
#!/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 sao chép 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