FFMPEG amix过滤器卷问题与不同持续时间的输入

时间:2016-02-19 15:41:02

标签: audio ffmpeg mix

我注意到ffmpeg amix过滤器在特定情况下没有输出好的结果。如果输入文件的持续时间相同,它可以正常工在这种情况下,音量会以恒定值下降,可以使用",volume=2"来修复。

在我的情况下,我使用不同持续时间的文件。结果量不好。第一个混合流导致最低量,最后一个流量最高。您可以在图像上看到音量随时间线性增加。

enter image description here

我的命令:

ffmpeg -i temp_0.mp4 -i user_2123_10.mp4  -i user_2123_3.mp4  -i user_2123_4.mp4  
-i user_2123_7.mp4  -i user_2123_5.mp4  -i user_2123_1.mp4  -i user_2123_8.mp4  
-i user_2123_0.mp4  -i user_2123_6.mp4  -i user_2123_9.mp4  -i user_2123_2.mp4  
-i user_2123_11.mp4 -filter_complex "[1:a]adelay=34741.0[aud1];
[2:a]adelay=18241.0[aud2];[3:a]adelay=20602.0[aud3];
[4:a]adelay=27852.0[aud4];[5:a]adelay=22941.0[aud5];
[6:a]adelay=13142.0[aud6];[7:a]adelay=29810.0[aud7];
[8:a]adelay=12.0[aud8];[9:a]adelay=25692.0[aud9];
[10:a]adelay=32143.002[aud10];[11:a]adelay=16101.0[aud11];
[12:a]adelay=40848.0[aud12];
[0:a][aud1][aud2][aud3][aud4][aud5][aud6][aud7]
[aud8][aud9][aud10][aud11]
[aud12]amix=inputs=13:duration=first:dropout_transition=0" 
-vcodec copy -y temp_1.mp4

可以通过在每个剪辑的开头和结尾应用静音来修复,然后它们将具有相同的持续时间,并且音量将处于相同的水平。

请建议我如何使用amix混合多个输入并确保音量不变。

9 个答案:

答案 0 :(得分:7)

amix将每个输入的音量缩放1/n,其中n = no。有效投入。对每个音频帧评估。因此,当输入输出时,剩余输入的音量将缩小一个较小的量,因此它们的音量会增加。

如其他答案所示,更改所有早期输入的dropout_transition是一种方法,但我认为这将导致粗调音量。更好的方法是在amix之后规范化音频。

目前,您有两个选项,loudnormdynaudnorm过滤器。后者要快得多

语法是在amix之后添加它,所以

[aud11][aud12]amix=inputs=13:duration=first:dropout_transition=0,dynaudnorm"

如果您想调整参数以获得最大音量或RMS模式标准化,请阅读文档。等

答案 1 :(得分:3)

尝试使用乘法:

"amix=inputs="+ chunks.length + ":duration=first:dropout_transition=3,volume=" + chunks.length

答案 2 :(得分:2)

解决方案,我发现的是按“降序”顺序指定每个轨道的音量,然后不使用归一化过滤器。

我使用此示例,在此示例中,我在不同位置连接了相同的音频文件:

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

更多详细信息,请参见此图像。第一条是正常混合,第二条是指定音量的混合。第三是原始曲目。如我们所见,第二音轨的音量似乎正常。

enter image description here

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0[a];[1]adelay=2000|2000[b];[2]adelay=4000|4000[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-no-volume.mp3

ffmpeg -vn -i test.mp3 -i test.mp3 -i test.mp3 -filter_complex "[0]adelay=0|0,volume=3[a];[1]adelay=2000|2000,volume=2[b];[2]adelay=4000|4000,volume=1[c];[a][b][c]amix=inputs=3:dropout_transition=0" -q:a 1 -acodec libmp3lame -y amix-volume.mp3

我真的不明白为什么混音会改变音量。无论如何;一段时间以来,我一直在四处寻找解决方案。

答案 3 :(得分:2)

我遇到了同样的问题,但是找到了解决方案!

首先是问题:我不得不将背景音乐文件与3种不同的TTS语音片段混合在一起,并以不同的延迟开始。最后,背景声音非常响亮。

我尝试了建议的答案,但是它对我不起作用,最终音量仍然高得多。所以我的想法是:“所有输入都必须具有相同的长度,以便每次混合时都激活相同数量的音频”

在所有设置了Whole_len和-shortest选项的TTS输入上执行apad对我来说很有效。

示例调用:

ffmpeg -y 
       -nostats 
       -hide_banner 
       -v quiet 
       -hwaccel auto 
       -f image2pipe 
       -i pipe:0 
       -i bgAudio.aac 
       -i TTS1.mp3 
       -i TTS2.mp3 
       -i TTS3.mp3 
       -filter_complex [1:a]loudnorm=I=-16:TP=-1.5:LRA=11:linear=false[a0];[2:a]loudnorm=I=-16:TP=-1.5:LRA=11:linear=false:dual_mono=true,adelay=7680|7680,apad=whole_len=2346240[a1];[3:a]loudnorm=I=-16:TP=-1.5:LRA=11:linear=false:dual_mono=true,adelay=14640|14640,apad=whole_len=2346240[a2];[4:a]loudnorm=I=-16:TP=-1.5:LRA=11:linear=false:dual_mono=true,adelay=3240|3240,apad=whole_len=2346240[a3];[a0][a1][a2][a3]amix=inputs=4:dropout_transition=0,asplit=6[audio0][audio1][audio2][audio3][audio4][audio5];[0:v]format=yuv420p,split=6[1080p][720p][480p][360p][240p][144p] 
       -map [audio0] -map [1080p] -s 1920x1080 -shortest out1080p.mp4 
       -map [audio1] -map [720p] -s 1280x720 -shortest out720p.mp4 
       -map [audio2] -map [480p] -s 858x480 -shortest out480p.mp4 
       -map [audio3] -map [360p] -s 640x360 -shortest out360p.mp4 
       -map [audio4] -map [240p] -s 426x240 -shortest out240p.mp4 
       -map [audio5] -map [144p] -s 256x144 -shortest out144p.mp4

希望有人帮忙!

答案 4 :(得分:1)

抱歉,不发送ffmpeg输出。

毕竟我们最后通过在C ++中编写small util来混合音频。但首先我们将mp4转换为原始(pcm)格式。这对我们来说效果很好,甚至需要为原始中间文件增加硬盘空间。

代码如下所示:

short addSounds(short a, short b) {
    double da = a;
    da /= 65536.0;
    da += 0.5;
    double db = b;
    db /= 65536.0;
    db += 0.5;
    double z = 0;
    if (da < 0.5 && db < 0.5) {
        z = 2 * da*db;
    }
    else {
        z = 2 * ( da + db ) - 2 * da* db - 1;
    }
    z -= 0.5;
    z *= 65536.0;
    return (short)z;
}

答案 5 :(得分:1)

解决方案似乎是“前置放大器”或乘法的组合,正如Maxim所说,并且您必须设置dropout_transition >= max delay + max input length(或非常高的数字):

amix=inputs=13:dropout_transition=1000,volume=13

注意:

  • amix无论如何都必须重新取样,因此添加volume过滤器(默认情况下重新采样也会浮动)没有任何缺点。
    而且由于我们使用的是浮子,因此没有剪裁,并且(几乎)没有精度损失。
  • 我要对@Mulvya进行分析,但他们的解决方案令人沮丧地非数学
  • 我原本试图用sox来做这件事,这太慢了。 Sox的remix过滤器具有-m开关,可禁用1/n调整。
  • 虽然速度更快,但ffmpeg似乎正在为同一任务使用更多内存。 YMMV - 我没有彻底测试这个,因为我最终确定了一个使用pyduboverlay函数的小python脚本,并且只将最终输出文件和一个段保存在内存中(而ffmpeg)并且sox似乎将所有段保留在内存中。

答案 6 :(得分:1)

我将向您展示我的代码。

"amix="+inputs.size()+",volume="+(inputs.size()+1)/2+"[mixout]\""

我不使用代码dropout_transition=0,因为它会引起您遇到的问题。

但是我也发现随着输入大小的增加,音量会降低的问题。

所以我把音量调大了。

答案 7 :(得分:1)

最新版本的 FFMPEG 包含 normalize 过滤器的 amix 参数,您可以使用它来关闭不断变化的归一化。 Here's the documentation for it.

您的 amix 过滤器字符串可以更改为:

[aud12]amix=inputs=13:normalize=0

答案 8 :(得分:0)

尝试将辍学过渡更改为第一次输入的持续时间:

duration=first:dropout_transition=_duration_of_the_first_input_in_seconds_

这是我的ffmpeg命令:

ffmpeg -y -i long.wav -i short.wav  -filter_complex "[1:a]adelay=6000|6000[a1];[1:a]adelay=10000|10000[a2];[1:a]adelay=14000|14000[a3];[1:a]adelay=18000|18000[a4];[1:a]adelay=21000|21000[a5];[1:a]adelay=25500|25500[a6];[0:a][a1][a2][a3][a4][a5][a6]amix=inputs=7:duration=first:dropout_transition=32[aout]" -map "[aout]" -ac 2 -b:a 192k -ar 44100 output.mp3

see two dropout transitions as screenshot