Làm cách nào tôi có thể bình thường hóa âm thanh bằng ffmpeg?


119

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ì?


1
Bạn đang muốn có âm thanh 'bình thường hóa'. Tôi tìm thấy chủ đề này và có rất nhiều thông tin tốt trong đó. Hy vọng nó giúp!
bobsbarricades

Câu trả lời:


190

Tùy chọn 1: Bộ lọc chuẩn hóa tích hợp

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, volumebộ 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ộ loudnormlọ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.


Tùy chọn 2: Sử dụng ffmpeg-normalizecô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:

  • tải xuống ffmpeg (chọn bản dựng tĩnh , phiên bản 3.1 trở lên)
  • đưa ffmpegtệp thực thi vào của bạn $PATHbằ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
  • Chạy pip install ffmpeg-normalize
  • Sử dụng 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.


Tùy chọn 3: Âm thanh chuẩn hóa thủ công với ffmpeg

Trong ffmpeg, bạn có thể sử dụng volumebộ 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).

Tìm hiểu mức tăng để áp dụng

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/nullbằng NULtrên Windows.
Các -vn, -snvà 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.

Áp dụng bộ lọc âm lượng:

Bây giờ chúng tôi áp dụng volumebộ 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àyhướ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 0trước tên tệp đầu ra.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Journeyman Geek

7
Đây là món quà không ngừng đưa ra. 6 năm sau, và nó vẫn đang được cập nhật và duy trì. Làm tốt!
Jon Skarpeteig

Có phải tùy chọn 3 tránh cắt nếu tôi đặt âm lượng mới để max_volume bằng không? tức là sử dụng giá trị ngược lại ban đầu được cung cấp bởi max_volume
rraallvv

@rraallvv Vâng, nó nên. Đó cũng là những gì ffmpeg-normalizecông cụ làm, khi bạn chỉ định mức 0 dB và mức chuẩn hóa cao nhất.
slhck

Để sử dụng loudnormbộ lọc (hoặc khác):ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua

7

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

5

Đâ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

-2

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


2
So sánh điều này với các câu trả lời khác ở đây, tôi hy vọng rằng bài đăng của bạn thiếu thông tin theo ngữ cảnh và giải thích sẽ làm cho nó hữu ích. "Bộ mã hóa" là gì và nó đóng vai trò gì trong việc trả lời câu hỏi?
nhạc2myear

2
Bạn có thể vui lòng chỉnh sửa câu trả lời của mình để đưa ra lời giải thích tại sao mã này trả lời câu hỏi không? Các câu trả lời chỉ có mã không được khuyến khích , vì chúng không dạy giải pháp.
DavidPostill
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.