如何使用ffmpeg规范音频?


119

我希望影片剪辑中最大的峰值声音要达到编解码器允许的最大声音,然后将其他所有声音都相应地放大。

为了使用ffmpeg完成此操作,有什么实际示例?


1
您正在寻求使音频“标准化”。我找到了这个线程,那里有很多很好的信息。希望能帮助到你!
bobsbarricades

Answers:


189

选项1:内置标准化过滤器

当前的ffmpeg具有两个可以直接用于归一化的滤波器-尽管它们已经相当先进,所以它们不能简单地应用增益来达到峰值。他们来了:

  • loudnorm:根据EBU R128进行响度归一化。您可以设置一个集成的响度目标,响度范围目标或最大真实峰值。建议用于发布音频和视频,全世界的广播公司都在使用它。
  • dynaudnorm:“智能”响度归一化,不进行裁剪,它在文件的窗口部分动态应用归一化。这可能会改变声音的特性,因此应谨慎使用。

同样,该volume过滤器可用于执行简单的音量调节。有关更多信息,请参见音频音量操作 Wiki条目。

loudnorm过滤器可与一个通一起使用,但建议进行两次通过,这使得能够更精确线性规范化。这有点难以自动化。另外,如果您希望“简单”的基于RMS或峰值归一化为0 dBFS(或任何其他目标),请继续阅读。


选项2:使用ffmpeg-normalize工具

我创建了一个Python程序来规范媒体文件该程序也可以在PyPi上使用。您只需:

  • 下载ffmpeg(选择静态版本3.1或更高版本)
  • ffmpeg可执行文件$PATH添加到您的文件中,方法是将其添加到/usr/local/bin,或将其目录添加到$PATH
  • pip install ffmpeg-normalize
  • 采用 ffmpeg-normalize

例如:

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更多选项,并查看自述文件中的一些示例。

此外,它支持使用其他编码器(例如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

在Windows上替换/dev/nullNUL
-vn-sn-dn参数指示的ffmpeg这个分析过程中忽略非音频流。这大大加快了分析速度。

这将输出如下内容:

[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在输出文件名前使用该选项。


评论不作进一步讨论;此对话已转移至聊天
Journeyman Geek

7
这是不断给予的礼物。6年后,它仍在更新和维护。做得好!
Jon Skarpeteig '17

如果我将新音量设置为max_volume为零,选项3是否可以避免剪切?即使用由max_volume给定的相反值初始值
rraallvv

@rraallvv是的,应该。ffmpeg-normalize当您将电平指定为0 dB并进行峰值归一化时,工具也将执行此操作。
slhck

7

我无法评论最好的消息,所以这是基于它的丑陋打击

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复制tmp.avi

mencoder -ovc复制-oac复制tmp.avi-原始音频-af volnorm = 1 -oac mp3lame -lameopts cbr:preset = 192 -srate 48000 -o“ output.mp3”

rm -f tmp.avi


2
将此与此处的其他答案进行比较,我希望您的帖子很明显缺少能使之有用的上下文和解释性信息。什么是“编码器”?它在回答问题时起什么作用?
music2myear

2
您能否编辑您的答案以解释此代码为何回答问题?不鼓励仅使用代码的答案,因为它们不会教导解决方案。
DavidPostill
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.