moviepy音视频开发:使用volumex调节音量大小及其花式用法

☞ ░ 前往老猿Python博文目录

一、概述

音频数据的音量体现为声音的振幅,振幅越大则声音越大,具体到音频帧数据上,体现为声音的绝对值越大则振幅越大音量越大,调节音量大小的本质是调整帧数据的绝对值大小。

在moviepy中,音频数据可以来源于数组、生成数组的函数或FFMPEG音频文件、视频文件等,moviepy中音频的数据会都是没有压缩编码的原始音频帧数据流。音频帧数据体现为一维数组(单声道)或二维数组(双声道),数组中的元素为-1到1之间的浮点数。

音量大小调整就是将原始音频数据的绝对值大小进行调整,moviepy中提供了volumex函数用于方便的进行音量大小调整。

二、volumex

调用语法:

volumex(clip, factor)

说明:

  • clip:需要调整音量的源剪辑,可以是音频剪辑,也可以是视频剪辑
  • factor:音量调整倍数,为浮点数,当音频为立体声时,还可以是一个两个浮点数组成的列表,这样可以为左右声道指定不同的调整因子
  • volumex没有改变源剪辑的大小,而是在源剪辑的拷贝上调整音量,返回值为该调整音量的剪辑
  • 由于moviepy中限定了音频帧数据为【-1,1】之间的浮点数,因此volumex倍乘factor之后的音频帧数据,超出0.99的值被强制置为0.99,小于-0.99的值被强制置为-0.99,因此volumex调整音量大小后,并不等于乘以多少倍音量就增大多少倍,而只是将低音量的部分放大,而高音量的就调整少或者不调整,这样就会导致源音频中低音部分被放大高音部分没调整,就可能导致音频杂音变大,当factor足够大时,原音频的原声可能就基本无法听清楚

三、volumex调用方法

volumex的调用方式有四种:

  • volumex导入后可以直接用函数形式调用,如:
from moviepy.audio.fx.volumex import volumex

volumex(video,2)
  • 在VideoClip和AudioClip的实例中作为实例方法直接调用,注意不能是二者的派生子类, 这是因为在moviepy.editor执行了如下语句:
for method in [
          "afx.audio_fadein",
          "afx.audio_fadeout",
          "afx.audio_normalize",
          "afx.volumex",
          "transfx.crossfadein",
          "transfx.crossfadeout",
          "vfx.crop",
          "vfx.fadein",
          "vfx.fadeout",
          "vfx.invert_colors",
          "vfx.loop",
          "vfx.margin",
          "vfx.mask_and",
          "vfx.mask_or",
          "vfx.resize",
          "vfx.rotate",
          "vfx.speedx"
          ]:

    exec("VideoClip.%s = %s" % (method.split('.')[1], method))
    
    for method in ["afx.audio_fadein",
               "afx.audio_fadeout",
               "afx.audio_loop",
               "afx.audio_normalize",
               "afx.volumex"
              ]:
              
    exec("AudioClip.%s = %s" % (method.split('.')[1], method))

将这些函数动态赋值给了VideoClip和AudioClip的同名实例变量,但这些实例变量是在moviepy.editor中定义的,因此在VideoClip或AudioClip的派生子类如VideoFileClip、AudioFileClip中不能这样使用。

  • 通过“afx.函数名”方式调用
    这是因为在moviepy.editor通过import moviepy.audio.fx.all as afx中将这些函数都加载到了afx模块下,因此可以直接通过afx.函数名方式调用
  • 通过剪辑基类Clip的fx方法调用volumex,如:video.fx(volumex,2)
注意:
  1. volumex调用的处理是基于原剪辑的拷贝进行处理的,因此必须保存返回值,用返回的剪辑作为操作结果剪辑
  2. volumex函数既可以对音频剪辑操作、也可以对视频剪辑操作

四、volumex几种花式用法

在使用volumex调整音量时,比较理想的音频音量调整方法是,如果是缩小音量就用volumex乘以一个小于1的浮点数,如果是调增音量,则判断当前音频中是否有音频帧达到最大值,如果达到了就不调整,没达到就按最大音量调整到1的方式来设置调整因子factor,这样不会导致音频整体变音严重。

下面介绍老猿想到的几种volumex函数的特例用法:

  1. 参考音频的最大音量x进行音量调整,如果x小于1,就以1除以x作为调整因子factor,这样就将确实增大音量又不会导致声音失真。可以认为这种处理方式就是将一个音量变小了音频恢复音频的正常音量,这个操作moviepy中提供了音频处理函数audio_normalize,因此可以直接使用audio_normalize来完成,具体可参考《moviepy音视频开发:audio_normalize调整剪辑音量大小到正常》;
  2. 当factor为0(含数组0)时,可以将整个音频静音;
  3. 对于立体声分别设置左右声道的调整因子,特别地可以通过一个因子设置为0将一个声道静音;
  4. 当factor为-1时,音频的播放感知没有变化,这是因为音频原始帧数据,正负值仅表示音频波基于平衡位置上下的振动幅度,没有改变音调、音量甚至音色。

五、案例

下面的代码将右声道静音,左声道音量调整为原来的一半:

from  moviepy.editor import *
from moviepy.audio.fx.volumex import volumex

if __name__ == '__main__':
    audio = AudioFileClip(r"F:\music\slqg.mp3")

    #audio = afx.volumex(audio,[0.5,0])
    audio = audio.volumex([0.5,0])

    audio.write_audiofile(r"f:\music\audio_volumex.mp3")

注释的代码行和其下面的代码行可以相互替换。

更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《moviepy音视频开发专栏》。

关于收费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!

☞ ░ 前往老猿Python博文目录

猜你喜欢

转载自blog.csdn.net/LaoYuanPython/article/details/107755370