【发布时间】:2021-02-21 10:56:18
【问题描述】:
我正在使用我正在编写的 C# 应用程序为合唱团创建其中一个“Brady Bunch”视频,该应用程序使用 ffmpeg 进行所有繁重的工作,并且在大多数情况下它运行良好,但我无法获得音频电平恰到好处。
我现在正在做的首先是像这样“标准化”各个歌手的音频:
- 使用 ffmpeg 将音频提取到 WAV 文件中
- 使用 NAudio 将 WAV 文件加载到我的应用程序中
- 查找最大 16 位值
- 当我创建合并视频时,为此流指定一个音量,将最大值提升到 32767
所以,例如,如果我有 3 个流:流 A 的最大音频已经是 32767,流 B 的最大音频是 32000,流 C 的最大音频是 16000,那么当我合并这些视频时,我会指定
[0:a]volume=1.0,aresample=async=1:first_pts=0[aud0]
[1:a]volume=1.02,aresample=async=1:first_pts=0[aud1]
[2:a]volume=2.05,aresample=async=1:first_pts=0[aud2]
[aud0][aud1][aud2]amix=inputs=3[a]
(我有一个额外的“音量调整”,可让我根据需要调整个别歌手的音量,但对于这个问题我们可以忽略它)
我正在阅读 Audio Volume Manipulation 上的 ffmpeg wiki,接下来我将实现它,但我不知道如何处理它生成的输出。看起来我将以 dB 为单位获得平均和最大音量水平,虽然我以“是的,我在 30 年前在大学里了解到那些”的方式理解分贝,但我不知道如何使用这些值标准化我的输入视频的音频。
问题是,在 ffmpeg 输出视频中,音频电平很低。如果我在ffmpeg生成的合并视频中提取音频并查看WAV文件的过程相同,最大值仅为4904。
如何实现自动将输出音量设置为“合理”水平的算法?我意识到我可以简单地添加一个手动音量过滤器并让人工设置级别,但这将是生成合并视频、收听它、调整级别、再次合并等的很多来回。我想要我的应用程序计算出适当输出量的一种方式(可能允许人工调整)。
编辑
要求 ffmpeg 确定每个剪辑的平均和最大音量确实提供了以 dB 为单位的平均和最大音量,然后我可以使用这些值来缩放每个输入剪辑:
[0:a]volume=3.40dB,aresample=async=1:first_pts=0[aud0]
[1:a]volume=3.90dB,aresample=async=1:first_pts=0[aud1]
[2:a]volume=4.40dB,aresample=async=1:first_pts=0[aud2]
[3:a]volume=-0.00dB,aresample=async=1:first_pts=0[aud3]
但我的最后一个视频仍然出奇地安静。现在,我添加了一个手动输入的音量因子,它会在最后应用:
[aud0][aud1][aud2]amix=inputs=3[a]
[a]volume=volume=3.00[b]
所以我的问题是,实际上,我如何通过算法确定这个最终体积因子需要是多少?
更多编辑
这里有一些更深层次的东西,我只是将音量过滤器设置为 100,输出只是稍微响亮一些。这是我的过滤器,以及命令行的相关部分:
color=size=1920x1080:c=0x0000FF [base];
[0:v] scale=576x324 [clip0];
[0:a]volume=1.48,aresample=async=1:first_pts=0[aud0];
[1:v] crop=808:1022:202:276,scale=384x486 [clip1];
[1:a]volume=1.57,aresample=async=1:first_pts=0[aud1];
[2:v] crop=1160:1010:428:70,scale=558x486 [clip2];
[2:a]volume=1.66,aresample=async=1:first_pts=0[aud2];
[3:v] crop=1326:1080:180:0,scale=576x469 [clip3];
[3:a]volume=1.70,aresample=async=1:first_pts=0[aud3];
[4:a]volume=0.20,aresample=async=1:first_pts=0[aud4];
[5:a]volume=0.73,aresample=async=1:first_pts=0[aud5];
[6:v] crop=1326:1080:276:0,scale=576x469 [clip4];
[6:a]volume=1.51,aresample=async=1:first_pts=0[aud6];
[base][clip0] overlay=shortest=1:x=32:y=158 [tmp0];
[tmp0][clip1] overlay=shortest=1:x=768:y=27 [tmp1];
[tmp1][clip2] overlay=shortest=1:x=1321:y=27 [tmp2];
[tmp2][clip3] overlay=shortest=1:x=32:y=625 [tmp3];
[tmp3][clip4] overlay=shortest=1:x=672:y=625 [tmp4];
[aud0][aud1][aud2][aud3][aud4][aud5][aud6]amix=inputs=7[a];
[a]adelay=delays=200:all=1[b];
[b]volume=volume=100.00[c];
[c]asplit[a1][a2];
ffmpeg -y ....
-map "[tmp4]" -map "[a1]" -c:v libx264 "D:\voutput.mp4"
-map "[a2]" "D:\aoutput.mp3""
当我这样做时,我想要的音频会更大(响亮到足以剪辑和失真),但绝对不会响亮 100 倍。
【问题讨论】:
-
使用 dynaudnorm 过滤器效果很好,谢谢!