ffmpegを使用してオーディオを正規化するにはどうすればよいですか?


119

ムービークリップの最大音量のサウンドをコーデックの許容範囲内でできるだけ大きくし、それに応じて他のすべてのサウンドを増幅します。

ffmpegを使用してこれを達成するための実用的な例は何ですか?


1
オーディオを「正規化」したいと考えています。このスレッドを見つけましたが、そこにはたくさんの良い情報があります。それが役に立てば幸い!
ボブスバリケード

回答:


190

オプション1:組み込みの正規化フィルター

現在のffmpegには、正規化に直接使用できる2つのフィルターがありますが、既にかなり高度であるため、単純にゲインを適用してピークレベルに到達することはありません。どうぞ:

  • loudnorm:EBU R128によるラウドネスの正規化。統合されたラウドネスターゲット、ラウドネスレンジターゲット、または最大トゥルーピークを設定できます。これは、オーディオとビデオの公開に推奨され、世界中の放送局によって使用されています。
  • dynaudnorm:クリッピングのない「インテリジェントな」ラウドネス正規化。ファイルのウィンドウ部分に動的に正規化を適用します。これにより音の特性が変わる可能性があるため、注意して適用する必要があります。

また、volumeフィルターを使用して簡単な音量調整を実行することもできます。詳細については、Audio Volume Manipulation wikiエントリをご覧ください。

このloudnormフィルターは1パスで使用できますが、2パスを実行することをお勧めします。これにより、より正確な線形正規化が可能になります。これは自動化が少し難しいです。また、0 dBFS(またはその他のターゲット)への「単純な」RMSベースまたはピーク正規化が必要な場合は、先に進んでください。


オプション2:ffmpeg-normalizeツールを使用する

私が作成したメディアファイルを正規化するPythonプログラム同様には、PyPI上で利用可能に。あなたは単に:

例えば:

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

または、多数のオーディオファイルを単にバッチ正規化し、それらを非圧縮WAVとして出力フォルダーに書き込むには:

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

このツールは、EBU R128(デフォルト)、RMS、およびピークをサポートしています。見てffmpeg-normalize -hより多くのオプションのため、チェックREADMEをいくつかの例のために。

また、他のエンコーダー(AACやMP3など)による再エンコード、またはオーディオのビデオへの自動マージをサポートします。


オプション3:オーディオを手動で正規化する ffmpeg

ffmpegでは、volumeフィルターを使用してトラックの音量を変更できます。必ず最新バージョンのプログラムをダウンロードしてください。

このガイドは、ピークの正規化を目的としています。つまり、ファイル内の最も音量の大きい部分を低くするのではなく、0 dBにします。また、複数のファイルで平均音量を同じにしようとするRMSベースの正規化もあります。これを行うには、最大音量を0 dBに押し上げるのではなく、選択したdBレベル(たとえば-26 dB)に平均音量を押します。

適用するゲインを見つける

最初に、オーディオストリームを分析して最大音量を求め、正規化が報われるかどうかを確認する必要があります。

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

交換する/dev/nullNULWindows上で。、、および引数は、この分析中に非オーディオストリームを無視するようにffmpegのを指示します。これにより、分析が大幅に高速化されます。
-vn-sn-dn

これにより、次のようなものが出力されます。

[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

ご覧のとおり、最大音量は-5.0 dBなので、5 dBのゲインを適用できます。0 dBの値を取得した場合、オーディオを正規化する必要はありません。

ボリュームフィルターを適用します。

次に、volumeフィルターをオーディオファイルに適用します。フィルタを適用すると、オーディオストリームを再エンコードする必要があることに注意してください。もちろん、オーディオに必要なコーデックは、元の形式によって異なります。ここではいくつかの例を示します。

  • プレーンオーディオファイル:必要なエンコーダーでファイルをエンコードするだけです。

    ffmpeg -i input.wav -af "volume=5dB" output.mp3
    

    もちろん、選択肢は非常に広いです。

  • AVI形式:通常、AVIコンテナに入っているビデオ付きのMP3オーディオがあります。

    ffmpeg -i video.avi -af "volume=5dB" -c:v copy -c:a libmp3lame -q:a 2 output.avi
    

    ここでは、品質レベル2を選択しました。値の範囲は0〜9以下で、より良いことを意味します。品質設定の詳細については、MP3 VBRガイドを参照してください。-b:a 192kたとえば、で固定ビットレートを設定することもできます。

  • MP4形式: MP4コンテナを使用すると、通常はAACオーディオが見つかります。ffmpegのビルトインAACエンコーダーを使用できます。

    ffmpeg -i video.mp4 -af "volume=5dB" -c:v copy -c:a aac -b:a 192k output.mp4
    

    ここでは、他のAACエンコーダーも使用できます。それらのいくつかもVBRをサポートしています。いくつかのヒントについては、この回答AACエンコーディングガイドをご覧ください。

上記の例では、ビデオストリームはを使用してコピーされ-c:v copyます。入力ファイルに字幕がある場合、または複数のビデオストリームがある場合は-map 0、出力ファイル名の前にオプションを使用します。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
ジャーニーマンオタク

7
これは贈り続ける贈り物です。6年後、それはまだ更新され維持されています。よくやった!
ジョンスカルペテイグ

max_volumeがゼロになるように新しいボリュームを設定した場合、オプション3はクリッピングを回避しますか?すなわち、max_volume
rraallvv

@rraallvvはい、そうすべきです。ffmpeg-normalize0 dBのレベルとピーク正規化を指定すると、これもツールの機能です。
-slhck

loudnorm(または他の)フィルターを使用するには:ffmpeg -i input.wav -filter:a loudnorm output.wav
Joschua

7

私はそれを行うためにそれに基づいて私のsoいバッシュであるため、最高のメッセージにコメントすることはできません

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

.m4aファイルのサウンドレベルを正規化するスクリプトを次に示します。サウンドレベルが静かすぎて開始できない場合は注意してください。その場合、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

-2

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


2
これを他の回答と比較して、あなたの投稿が役に立つと思われる文脈的および説明的な情報を欠いていることが明確であることを願っています。「メンコーダー」とは何ですか?質問に答える上でどのような役割を果たしますか?
music2myear

2
回答を編集して、このコードが質問に回答する理由を説明してください。コードのみの回答は、ソリューションを教えていないため推奨されません。
DavidPostill
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.