FFmpeg:如何在音频文件中创建动态音量变化?

5

我正在进行一个项目,需要动态地更改音频文件的音量。

例如,我有一个名为xyz.mp3的音频文件(20秒的音频文件)。 我需要设置它的音量如下:

Time Range (in Seconds)     ||     Volume Percentage (in %)
-------------------------------------------------------------------    
    0 - 4                   ||           100
                            ||
    4 - 8                   ||    change from 100 - 20 (dynamically)
                            ||
    8 - 12                  ||           20
                            ||           
    12 - 16                 ||    change from 20 - 100 (dynalically)
                            ||
    16 - 20                 ||           100       

现在,我知道要更改音频中特定时间的音量,可以使用以下命令:
ffmpeg -i in.mp3 -af volume=20:enable='between(t,8,12)' out.mp3

但是当我使用音量效果时,它并没有动态地改变音量。它只是直接将音量从100更改为20,而不像淡入淡出一样逐渐改变。

当我使用afade命令时,如下所示:

ffmpeg -i in.mp3 -af afade=t=in:ss=4:d=8,afade=t=out:st=12:d=16 out.mp3

或者
ffmpeg -i in.mp3 -af afade=enable='between(t,4,8)':t=in:ss=4:d=4,afade=enable='between(t,12,16)':t=out:st=12:d=4 out.mp3

但是看起来afade即使我使用ffmpeg 3.0.1版本也不能多次工作。

由于afade只能单次工作,我还将音频分成4秒的部分,并添加了淡入淡出效果,然后再将它们组合在一起,但是每个片段之间会有一些毫秒的间隔。有人知道更好的方法吗?请帮帮我...

更新1:

这是我使用的代码:

"volume='" +
            "between(t,0,8)+(1-0.8*(t-8)/4)*" +        // full
            "between(t,8.01,11.99)+0.1*" +             // change from HIGH -> LOW
            "between(t,12,16)+(0.1+0.8*(t-16)/4)*" +   // low
            "between(t,16.01,19.99)+1*" +              // change from LOW -> HIGH   -
            "between(t,20,24)+(1-0.8*(t-24)/4)*" +     // full
            "between(t,24.01,27.99)+0.1*"+             // change from HIGH -> LOW   -
            "between(t,28,32)+(0.1+0.8*(t-32)/4)*" +   // low
            "between(t,32.01,35.99)+1*" +              // change from LOW -> HIGH  -
            "between(t,36,40)+(1-0.8*(t-40)/4)*" +     // full
            "between(t,40.01,43.99)+0.1*"+             // change from HIGH -> LOW   -
            "between(t,44,48)+(0.1+0.8*(t-48)/4)*" +   // low
            "between(t,48.01,51.99)+" +                // change from LOW -> HIGH -
            "between(t,52,56)" +                       // high
            "':eval=frame";

在这段代码中,我在初始化音频以更改音量的那些地方遇到了一小段时间差(几毫秒)。
更新2 好的,我明白了,我只需要将时间值更改为19.9999和16.0001之类的值,就可以解决问题。谢谢Gyaan先生。
1个回答

5

使用

volume='between(t,0,4)+(1-0.8*(t-4)/4)*between(t,4.01,7.99)+0.2*between(t,8,12)+(0.2+0.8*(t-12)/4)*between(t,12.01,15.99)+between(t,16,20)':eval=frame

好的,等一下我会尝试一下...在那之前,你能否请再解释一下这行代码吗? - ankushalg
1
音量表达式包含一组链接的表达式,其结果应用于具有给定时间戳的音频帧。请参见http://ffmpeg.org/ffmpeg-utils.html#Expression-Evaluation。 - Gyan
嗨,Gyan先生,我已经测试了这段代码,并发现它可以工作并改变音量,但最终的音频中会产生一些小间隙(波动)。我正在更新我的问题,并在此添加我使用的方法... - ankushalg
音频中的间隙就像某种干扰。观众很容易就能发现。请检查我的代码,帮我找到错误。 - ankushalg
间隔可能会发生,因为例如时间范围between(t,4.01,7.99)等于3.98而不是4。我认为它之前的部分应该说(t-4)/3.98)*be… - WoodrowShigeru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接