使用 ffmpeg 将 5.1 正确缩混为立体声

for*_*rin 46 audio ffmpeg stereo 5.1

我有一个来自电影的 5.1 音轨,其中左前和右前包含音乐,中间包含对话。在 VLC 中播放 5.1 曲目可以很好地将所有内容融合在一起。

我正在尝试使用 将 5.1 音轨转换为立体声ffmpeg -ac 2,但是生成的立体声混音比本地播放 5.1 音轨的音量要弱得多。

添加-af "pan=stereo|c0=FL|c1=FR"会产生正确的音量,但由于不包括中央声道,因此没有对话。

所以解决方案可能是将左/中/右混合成立体声,然后丢弃后端低音炮通道?(我猜这里...)

所以问题是:如何将 ffmpeg 缩混 5.1 以与 VLC 相同的方式制作立体声,最终结果具有相同的强劲音量?

Has*_*ziz 59

这个问题的答案从此变得有点混乱,其中许多包含冗余信息,而另一些则完全不准确。这个答案试图简化这些答案中的信息,同时消除其中的问题。

最重要的是,值得记住的是,Gregory 的答案(目前该问题的最高投票答案)与使用-ac 2switch没有什么不同——更多内容见下文。


将 5.1 声道音频流缩混为立体声 -ac 2

FFmpeg 具有将 5.1 音轨缩混为立体声的内置功能,这也是 FFmpeg 自己的文档推荐的解决方案:

注意:ffmpeg 集成了一个默认的向下混音(和向上混音)系统,-ac除非您有非常特殊的需求,否则该系统应该优先于(选项)而不是平移过滤器。

-ac 2开关的工作原理是将源 6 通道流中的前 5 个通道(左后、右后、左前、右前和中心前)的前 5 个通道按比例混合到输出立体声流的左前和右前通道中:

在此处输入图片说明

这样做时,使用此选项时,来自 LFE 通道(5.1 中的.1,保留给低音炮并用于深沉的低频效果)的音频将被完全丢弃

不幸的是,在我的测试-ac 2中,音乐和对话的整体水平与源最不同,使其成为我测试的所有公式中输出最差的缩混公式,尽管您可能会对其进行测试并发现它为您提供完全足够的缩混以满足您的需求,在这种情况下,使用任何其他公式对您来说都是多余的。


要在-ac 2 转码的情况下对 DTS 轨道进行缩混(即保持其编解码器和扩展名相同):

ffmpeg -i "sourcetrack.dts" -c:a dca -ac 2 "stereotrack.dts"
Run Code Online (Sandbox Code Playgroud)

正如 Mephisto 在他的回答中指出的那样,如果对话和音乐对你来说听起来很平衡,但只是缺乏音量,你可以在增加音量的同时对流进行缩混:

ffmpeg -i "sourcetrack.dts" -c:a dca -ac 2 -vol 425 "stereotrack.dts"
Run Code Online (Sandbox Code Playgroud)

对于-vol开关,源中的 100% 音量相当于整数值 256,使用大于此值的值将增加音频流的整体音量。但是,请注意,这样做过多可能会导致失真或伪像,尤其是在其较大声部分。

要将音频流缩混为立体声并将其转码为 AC3 编解码器,例如:

ffmpeg -i "sourcetrack.dts" -c:a ac3 -ac 2 "stereotrack.ac3"
Run Code Online (Sandbox Code Playgroud)

使用自定义混合算法将 5.1 声道音频流缩混为立体声

如果您想要更高质量的缩混,或者您绝对必须将 LFE 流包含在您的输出中,您可以使用 FFmpeg 的音频过滤器开关 ( -af) 使用自定义混合公式对音频进行缩混。

使用 ATSC 公式缩混(Gregory 的回答)

截至发布此答案时,此问题的最高投票答案是Gregory's,它将ATSC 规范(请参阅第 7.8.2 节,下混为两个通道)中的公式放入FFmpeg 音频过滤器中。该规范本身直接与FFmpeg 主题相关的文档相关联,这表明它很可能与 FFmpeg 已经为其-ac 2开关实现的公式相同。如果这是真的,那么在 Gregory 的答案中输入整个公式与使用-ac 2switch没有什么不同,因此是浪费时间。

我决定通过使用Gregory 的答案中-ac 2-af过滤器和过滤器重新编码相同的输入音频来对此进行测试(可以在此答案的脚注中看到所使用的确切命令)。

然后我比较了生成的输出文件的大小,发现它们逐字节大小相同:

在此处输入图片说明

最后,我在 Audacity 中打开了两个输出文件,并比较了它们的波形以确认它们是相同的(点击放大):

在此处输入图片说明

因此,格雷戈里的答案中详述的 ATSC 公式与 FFmpeg 已经实现的公式相同,这似乎是非常确定的,并且当它不执行任何操作时,使用它是完全多余的-ac 2,并且是一个更麻烦的命令。

在不丢弃 LFE 通道的情况下进行缩混(Dave_750 的回答)

在答案中包含的几个中,这是唯一一个似乎将 LFE 通道混合到输出立体声而不是完全丢弃它的缩混公式,因此,确保来自源的声音最少的是丢失。

整体音量比做的更高更饱满-ac 2,但仍然低于下面的 Nightmode Dialogue 缩混。然而,音乐电平比 Nightmode Dialogue 缩混更接近源,并且由于包含 LFE 音轨,在使用此缩混公式时增加输出音量可以创建一个输出流,听起来比所有其他源都更真实 5.1 源我测试的公式。

如果您有能力,我强烈建议您使用此缩混公式和 Nightmode Dialogue 缩混对您的音频流进行编码,并仔细比较两者的波形以确定哪个更好。

要使用此公式将 5.1 音轨缩混为立体声并将其音量级别增加到 425(其中 256 是原始源音量级别的 100%):

ffmpeg -i "sourcetrack.dts" -c dca -vol 425 -af "pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE" "outputstereo.dts"
Run Code Online (Sandbox Code Playgroud)

与 Robert Collier 的 Nightmode Dialogue 进行缩混(Shane Harrelson 的回答)

Robert CollierDoom9论坛上创建并由Shane Harrelson 在他的回答中提供的 Nightmode Dialogue 公式产生比-ac 2switch更好的缩混——而不是过于安静的对话,它将它们带回到更接近于来源。

来自 Robert Collier 对混合的描述:

使用 eac3to 将许多 DTS 电影轨道从 5.1 转换为 2.0 后,我发现默认的 eac3to 通道映射会导致非常安静的对话以及过于嘈杂的音乐和动作场景。尽管 eac3to 通道下混系数有科学依据,但由于对话音量低,它们在实践中通常听起来不太好。此预设适用于那些寻求清晰对话的人,左右声道音乐仍可听,但背景更多。

正如您所看到的 - 前中心(对话)现在正确进入并保持原始水平 - 而音乐和爆炸仍然是背景效果并且不会压倒您。此预设解决了您在观看 DTS 5.1 转换为 2.0 电影时必须不断摆弄音量旋钮才能听到对话的问题。(特别适合在不想吵醒别人但又想听对话的夜晚看电影)。

不幸的是,这个缩混公式的音乐比 5.1 源中的音乐要低得多(考虑到 Collier 创建“夜间模式”混音的意图,这很可能是设计上的)并且由于 LFE 音轨完全丢失,整体输出音频没有声音像 Dave_750 的公式一样饱满或接近音源并提高音量

但是,如果出于某种原因您想避免提高流的整体音量,那么夜间模式对话可能是您的最佳选择 - 尽管如此,我再次强烈建议将您的音频流编码为两者并仔细比较两者的波形.

要在 FFmpeg 中使用 Nightmode Dialogue 公式进行缩混:

ffmpeg -i "sourcetrack.dts" -c dca -af "pan=stereo|FL=FC+0.30*FL+0.30*BL|FR=FC+0.30*FR+0.30*BR" "stereotrack.dts" 
Run Code Online (Sandbox Code Playgroud)

塔克的回答

这个答案只是将 Shane Harrelson 的答案中的 Nightmode Dialogue 缩混公式放入一个命令中,以转换 MKV 容器中的音频流。虽然此答案中给出的命令可以在这样的音频流上正常工作,但将其调整为独立的音轨会产生错误:

过滤和流复制不能一起使用

这是因为在缩混时无法复制音频编解码器 - 就像 FFmpeg 对输出流所做的所有其他更改一样,缩混需要重新编码轨道以应用更改。

此命令还包括一个冗余-ac 2开关,FFmpeg 会忽略该开关。


测试命令

为了证明我为此答案进行的测试的可靠性,以下是我用来测试每​​个缩混公式的所有命令。

用于-ac 2选项的测试命令:

ffmpeg -i "signed16bitPCM.wav" -c pcm_s16le -ac 2 "Audio 1 (-ac 2).wav"
Run Code Online (Sandbox Code Playgroud)

用于 Gregory 答案的测试命令:

ffmpeg -i "signed16bitPCM.wav" -c pcm_s16le -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "Audio 2 (ATSC Algorithm Downmix).wav"
Run Code Online (Sandbox Code Playgroud)

用于 Dave_750 答案的测试命令:

ffmpeg -i "signed16bitPCM.wav" -c pcm_s16le -vol 425 -af "pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE" "Audio 4 (Dave750 Downmix).wav"
Run Code Online (Sandbox Code Playgroud)

用于 Shane Harrelson 答案的测试命令:

ffmpeg -i "signed16bitPCM.wav" -c pcm_s16le -af "pan=stereo|FL=FC+0.30*FL+0.30*BL|FR=FC+0.30*FR+0.30*BR" "Audio 3 (Nightmode Dialogue Downmix).wav"
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,“.wav”完全未压缩,因此*所有*这些缩混将具有完全相同的大小(精确到字节),无论如何。你可以拥有完全的静音,并且如果长度相同的话,它仍然会是相同的大小(并且采样率、位深度等也相同) (3认同)
  • 我认为使用“pan”的公式的建议命令不起作用。ffmpeg 输出一个错误,例如“不能混合命名和编号通道”,我发现这意味着“c4”符号不能与“FL”、“LFE”等一起使用。 (3认同)
  • 令人印象深刻的洞察力!感谢您花时间分享此内容。奇怪的是,“-ac 2”一开始就给了我一个较差的结果,这促使了最初的发布。我会再试一次,如果可能的话,分享一个 5.1 的摘录,它在内置的缩混中并没有给出令人满意的结果。也很高兴知道您可以在不转码的情况下进行缩混! (2认同)
  • 这是我在此网站上看到的最彻底的答案之一。 +1 (2认同)
  • @etudes 等人,音量直接添加到音频过滤器中,如 -af "volume=#.#" 其中 #.# 是乘数,1.0 不会有任何变化。 Dave_750 的答案示例的音频过滤器变为: -af "volume=1.66,pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707* BR+0.5*LFE" (2认同)
  • @HashimAziz 所有答案/“测试命令”都会产生错误“不能混合命名和编号通道”。根据 ffmpeg pan 文档,您不能将通道名称(如 c0、c1)与扬声器名称(FL、FR)混合!https://ffmpeg.org/ffmpeg-filters.html#pan 看起来你的 c4 和 c5 应该是 BL 和 BR (2认同)
  • 我现在已经更新了此答案中的所有命令,以使用通道号而不是名称来尝试(以编程方式)修复 SL/SR 和 BL/BR 问题,尽管我感觉它们无论如何都有单独的通道号 - 不确定的方法,因为这些实际上没有记录在任何地方。如果这仍然无法添加后置和侧置通道音频,我将恢复最后几次编辑,只编辑所有命令以在 SL/SR 通道上执行与 BL/BR 通道相同的操作。 (2认同)

Gre*_*ory 32

我发现 Shane 提供的答案提供了太少的其他频道和太多的中心。带耳机的电影听起来不平衡,所有对话都没有足够的背景音乐/效果。

根据ATSC 标准(第 7.8 节,第 91 页),以下公式用于将 5.1 缩混为传统立体声(与矩阵相反):

Lo = 1.0 * L + clev * C + slev * Ls ;
Ro = 1.0 * R + clev * C + slev * Rs ;
Run Code Online (Sandbox Code Playgroud)

根据上述文件中的表 5.9 和 5.10,clev 和 slev 应为 0.707,假设中心/环绕混合级别为 0。这些表中提供了其他值以减少中心混合的数量,我没有找到有用。

考虑到这一点,以下 ffmpeg 选项可产生具有可听对话的良好平衡声音。请注意,不需要指定音频通道。

-af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR"
Run Code Online (Sandbox Code Playgroud)

关于使用小于号的说明,来自pan filter 文档

如果通道规范中的“=”被“<”替换,则该规范的增益将被重新归一化,使总数为 1,从而避免削波噪声。

  • 您在此处链接的 ATSC 标准是从 [FFmpeg wiki on the topic](https://trac.ffmpeg.org/wiki/AudioChannelManipulation#a5.1stereo) 链接的,因此这里使用的公式是FFmpeg 用它的 `ac -2` 开关实现的相同。换句话说,使用这个过滤器和使用 `ac -2` 的唯一区别是输入更多。 (5认同)
  • @Hashim 不仅打字。对基础进行彻底解释的答案客观上比“输入这个以获得那个”要好。 (3认同)

小智 11

试试这个缩混:

-ac 2 -af "pan=stereo|FL=FC+0.30*FL+0.30*BL|FR=FC+0.30*FR+0.30*BR" 
Run Code Online (Sandbox Code Playgroud)

正如Robert Collier在 Doom9 论坛中所建议的那样

  • 为一部 5.1 电影试过这个,至少输出立体声对我来说听起来完全没问题。清晰的对话和其他任何东西似乎都没有丢失。如果具有 VLC 知识的人可以准确分享默认 5.1 到 2.0 缩混中所做的工作,那就太好了。 (4认同)
  • 所有这些选项是什么意思?如果您解释它们,人们将能够使用您的答案来解决不同的问题,而不仅仅是复制粘贴。 (2认同)
  • @DavidRicherby -ac = 音频通道(立体声 2 个),-af = 音频过滤器 (2认同)
  • @DavidRicherby:音频过滤器(-af)内的选项是:FL=Front-left; BL=左后;FC=前中;FR=前右;BR=右后。浮点数是线性因子,用于减少 (&lt;1) 或增加 (&gt;1) 倍增通道的音量。FL=FC+0.30*FL+0.30*BL 是将 Front-left 声道设置为 Front-Center 声道加上 30% 的 Front-left 和 30% 的 Back-left 声道。 (2认同)
  • FWIW:我发现与音乐和环境声音相比,这种混合使对话变得太大声。Tarc 的回答中给出的技术上更正确的组合让我更满意。所以我想你可能必须尝试最适合你的方法,这取决于具体情况。 (2认同)

小智 5

因此,通过将@Shane Harrelson 的回答与 @Jordan Harris对另一个问题的回答结合起来(打开惰性模式),这里需要将input_51.mkv(5.1) 转换为output_stereo.mkv(立体声):

ffmpeg -i input_51.mkv -c:v copy \
    -ac 2 -af "pan=stereo|FL=FC+0.30*FL+0.30*BL|FR=FC+0.30*FR+0.30*BR" \
    output_stereo.mkv
Run Code Online (Sandbox Code Playgroud)

-c:v copy部分意味着视频流没有被触及(我猜视频解码器设置正在被复制)。如果没有它,将需要更长的时间。为了完整性,只需重复上面的答案,-ac 2意味着两个音频通道并-af指定一个音频过滤器。

稍微研究了一下该命令后,我发现它正在设置两个立体声通道的组成方式;(左前声道FL)取自原始FC(前中)加上0.30*FL(左前的 30%)加上0.30*BL(左后的 30%),依此类推。


小智 5

这是一个老问题了,但为我指明了正确的方向并想分享我的结果:

-af "pan=stereo|FL=0.5*FC+0.707*FL+0.707*BL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.5*LFE"
Run Code Online (Sandbox Code Playgroud)

将 FC 和 LFE 的一半放入左侧和右侧,两个扬声器的有效音量总计为 1。使用 .707 * 前/后左/右将这些通道降低到一个良好的水平,这样它们就不会压倒中心。


Vic*_*tor 5

RFC 7845 第 5.1.1.5 节具有各种立体声缩混的系数,可保留 LFE。

$ ffmpeg -i INFILE -c:a libopus -b:a 256k -af "pan=stereo|OUTDEFS" OUTFILE
Run Code Online (Sandbox Code Playgroud)

INFILE和替换OUTFILE为文件名,并将 和OUTDEFS替换为下面的定义(换行符替换为空格):

5.1 环绕声缩混至立体声

FL、FC、FR、BL、BR、LFE -> FL、FR

FL = 0.374107*FC + 0.529067*FL + 0.458186*BL + 0.264534*BR + 0.374107*LFE |
FR = 0.374107*FC + 0.529067*FR + 0.458186*BR + 0.264534*BL + 0.374107*LFE
Run Code Online (Sandbox Code Playgroud)

7.1 环绕声

FL、FC、FR、SL、SR、BL、BR、LFE -> FL、FR

FL = 0.274804*FC + 0.388631*FL + 0.336565*SL + 0.194316*SR + 0.336565*BL + 0.194316*BR + 0.274804*LFE |
FR = 0.274804*FC + 0.388631*FR + 0.336565*SR + 0.194316*SL + 0.336565*BR + 0.194316*BL + 0.274804*LFE
Run Code Online (Sandbox Code Playgroud)

6.1 环绕声

FL、FC、FR、SL、SR、BC、LFE -> FL、FR

FL = 0.321953*FC + 0.455310*FL + 0.394310*SL + 0.227655*SR + 278819*BC + 0.321953*LFE |
FR = 0.321953*FC + 0.455310*FR + 0.394310*SR + 0.227655*SL + 278819*BC + 0.321953*LFE
Run Code Online (Sandbox Code Playgroud)

5.0环绕声

FL、FC、FR、BL、BR -> FL、FR

FL = 0.460186*FC + 0.650802*FL + 0.563611*BL + 0.325401*BR |
FR = 0.460186*FC + 0.650802*FR + 0.563611*BR + 0.325401*BL
Run Code Online (Sandbox Code Playgroud)

四声道

佛罗里达、法国、保加利亚、巴西 -> 佛罗里达、法国

FL = 0.422650*FL + 0.366025*BL + 0.211325*BR |
FR = 0.422650*FR + 0.366025*BR + 0.211325*BL
Run Code Online (Sandbox Code Playgroud)

线性环绕声道

FL、FC、FR -> FL、FR

FL = 0.414214*FC + 0.585786*FL |
FR = 0.414214*FC + 0.585786*FR
Run Code Online (Sandbox Code Playgroud)

RFC 解释了他们如何选择系数:

实现可以使用图 4 到 9 中的矩阵,使用通道映射系列 1(第 5.1.1.2 节)实现多通道文件的缩混,已知这可以为立体声提供可接受的结果。3 和 4 通道的矩阵经过归一化,因此每个系数行的总和为 1,以避免削波。对于 5 个或更多通道,它们被标准化为 2,作为削波和动态范围减小之间的折衷。

在这些矩阵中,左前通道和右前通道通常直接通过。当环绕声道在左右立体声声道之间分配时,会选择系数,使其平方和为 1,这有助于保持感知强度。后声道的混合更加分散或衰减,以保持对前声道的关注。


根据这个答案,也可以使用-ac 2-lfe_mix_level <level>包含 LFE。

$ ffmpeg -i INFILE -c:a libopus -b:a 256k -ac 2 -lfe_mix_level 1 OUTFILE
Run Code Online (Sandbox Code Playgroud)


小智 5

我在这里回顾了答案,虽然哈希姆·阿齐兹(Hashim Aziz)做了精彩的总结,但我在自己进行调查后才注意到缺少一件事。ffmpeg 可识别两种 5.1 布局(请参阅 参考资料ffmpeg -layouts)。5.1, 和5.1(side)。一些录音设备等使用后者,其中没有BL和 BR 通道,而是 SL 和 SR。

在脚本中使用 BL/BR 不会引发错误:它们只是沉默。我确实没有找到一种方法来检测它,但不需要。可以添加不存在的通道(同样,一组或另一组始终为空):

Gregory's ATSC formula (ffmpeg -ac 2)  FL<1.0*FL+0.707*FC+0.707*BL+0.707*SL|FR<1.0*FR+0.707*FC+0.707*BR+0.707*SR
Robert Collier's Nightmode Dialogue    FL=FC+0.30*FL+0.30*BL+0.30*SL|FR=FC+0.30*FR+0.30*BR+0.30*SR
Dave_750                               FL=0.5*FC+0.707*FL+0.707*BL+0.707*SL+0.5*LFE|FR=0.5*FC+0.707*FR+0.707*BR+0.707*SR+0.5*LFE
RFC 7845 Section 5.1.1.5               FL=0.374107*FC+0.529067*FL+0.458186*BL+0.458186*SL+0.264534*BR+0.264534*SR+0.374107*LFE|FR=0.374107*FC+0.529067*FR+0.458186*BR+0.458186*SR+0.264534*BL+0.264534*SL+0.374107*LFE
Run Code Online (Sandbox Code Playgroud)

5.1或者只使用频道号(与和匹配5.1(side)):

5.1            FL+FR+FC+LFE+BL+BR
5.1(side)      FL+FR+FC+LFE+SL+SR
               c0+c1+c2+ c3+c4+c5
Run Code Online (Sandbox Code Playgroud)

我个人选择了 Dave 的公式(RFC 在我的使用中排名第二)并使用通道号:

ffmpeg.exe -i input51.mkv -c:s copy -c:v copy -c:a libopus -b:a 104k -af "pan=stereo|FL<0.5*c2+0.707*c0+0.707*c4+0.5*c3|FR<0.5*c2+0.707*c1+0.707*c5+0.5*c3" output20.mkv
Run Code Online (Sandbox Code Playgroud)