FFmpeg amix + 音量过滤器创建饱和输出?
Posted
技术标签:
【中文标题】FFmpeg amix + 音量过滤器创建饱和输出?【英文标题】:FFmpeg amix + volume filters create saturated output? 【发布时间】:2021-07-26 15:25:07 【问题描述】:首先,这是一个出于好奇而不是迫切需要解决的问题。我似乎通过从 FFmpeg 3.4.6 升级到 FFmpeg 4.3.1 来“修复”它。或者我认为,至少结果要好得多。
我正在尝试使用 FFmpeg amix
过滤器混合 2 个音频文件(长度相同,因此这里没有比例变化):
现在,我了解到过滤器会将每个输入音量除以 1/nb_active_inputs
(在我的情况下是 2),所以我在输出上添加了一个音量过滤器,将其音量乘以 2。我的命令基本上看起来像这样:
ffmpeg -i music.mp3 -i voice.mp3 -filter_complex amix=inputs=2:duration=first[mix];[mix]volume=2[out] -map [out] output.mp3
经过那个复杂的过滤器后,我的最终输出完全失真了。声音整体听起来非常响亮且饱和。
我不是音频专家,也不是 FFmpeg 专家,所以我认为我遗漏了一些东西。我试图了解发生了什么以及为什么我会得到这个结果,因为我在这两种情况下都使用相同的输入、过滤器和过滤器选项。只有 FFmpeg 版本不同。
我已尝试阅读两个版本的 af_amix.c
代码,但似乎找不到任何解释该差异的原因。我已经看到 4.3.1 有一个 weights
输入选项,但据我了解,如果未指定,它们默认为 1.0
。任何线索将不胜感激。
【问题讨论】:
在 amix 中还有 normalize 选项,但你至少需要 FFmpeg 4.4 或使用 git master。 【参考方案1】:您必须设置声音再现(立体声,单声道)的输入和输出方法的数量,并像这样一一设置音量:
ffmpeg -i $firstAudio -i $secondAudio -filter_complex [0:a]volume=$firstAudioVolume[A];[1:a]volume=$secondAudioVolume[B];[A][B]amerge=inputs= 2、平移=立体声|c0
还有这个使用示例:
ffmpeg -i music.mp3 -i voice.mp3 -filter_complex '[0:a]volume=3.0[A];[1:a]volume=1.0[B];[A][B]amerge=inputs=2,pan=stereo|c0<c0+c2|c1<c1+c3' output.mp3
【讨论】:
【参考方案2】:您可以相应地设置两个 mp3 文件的音量并生成新的 mp3 文件(output.mp3),如下所示:
<?php
$path = dirname(__FILE__); // Absolute directory path
$music = $path.'/background.mp3'; // Absolute mp3 input file path
$voice = $path.'/voice.mp3'; // Absolute mp3 input file path
$output = $path.'/output.mp3'; // Absolute mp3 output file path
$voice_volume = '1bB';
$bg_music_volume = '-10bB'; // -(minus) denotes decrease volume.
echo shell_exec('ffmpeg -i '.$music.' -i '.$voice.' -filter_complex "[0:0][1:0]concat=n=2:v=0:a=1,volume='.$bg_music_volume.',aformat=fltp,pan=stereo|c0=c0|c1=c1[a0];[1]volume='.$voice_volume.',aformat=fltp,pan=stereo|c0=c0|c1=c1[a1];[a0][a1]amerge,aformat=fltp[a]" -map "[a]" -strict -2 -y '.$output.'');
?>
默认音量:
-
$music(background.mp3) 值'-10dB'
$voice(voice.mp3) 值 '1dB'
您可以相应地调整音量
【讨论】:
以上是关于FFmpeg amix + 音量过滤器创建饱和输出?的主要内容,如果未能解决你的问题,请参考以下文章
使用 ffmpeg 将一个过滤器的输出多次馈送到一个过滤器的输入