moviepy音视频开发:音频剪辑基类AudioClip

☞ ░ 前往老猿Python博文目录

一、背景知识介绍

1.1、声音三要素:
  • 音调:人耳对声音高低的感觉称为音调(也叫音频)。音调主要与声波的频率有关。声波的频率高,则音调也高。
  • 音量:也就是响度。人耳对声音强弱的主观感觉称为响度。响度和声波振动的幅度有关。一般说来,声波振动幅度越大则响度也越大。
  • 音色:也就是音品。音色是人们区别具有同样响度、同样音调的两个声音之所以不同的特性,或者说是人耳对各种频率、各种强度的声波的综合反应。音色与声波的振动波形有关,或者说与声音的频谱结构有关。
    更多关于声音三要素的内容请参考《音频基础知识》。
2.1、数字音频常用概念
  1. 采样率(Sample Rate):每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。一般音乐CD的采样率是44100Hz,所以视频编码中的音频采样率保持在这个级别就完全足够了,通常视频转换器也将这个采样率作为默认设置。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,采样频率越高音质越好,但资源消耗越高。22.05kHz的采样频率是常用的, 44.1kHz已是CD音质, 超过48kHz或96kHz的采样对人耳已经没有意义
  2. 采样位数(Sample Bits):也称采样精度,有点类似颜色表示的位数,指使用数字表示声音信号的数字的二进制位数,位数越多表示声音的精度越高。1 字节(8bit) 只能表示 256 中声音值,2 字节(16bit) 可以表示 65536 个声音值等。采用位数越高声音精度越高,播放的声音与源音的差距越小,但存储开销越大
  3. 通道数(channel):也称为声道数,即声音通道的数目,分为单声道mono;立体声stereo。声道多,效果好,两个声道,说明只有左右两边有声音传过来,四声道,说明前后左右都有声音传过来。moviepy1.03的版本只支持单声道和双声道。
  4. 帧(frame):帧记录了一个声音单元,其长度为样本长度(采样位数)和通道数的乘积
  5. 码率(Bit Rate):也称为位速或比特率,指视频或音频文件在单位时间内使用的数据流量,针对编码格式,表示压缩编码后每秒的音频数据量大小。计算公式:比特率 = 采样率 x 采样位数 x 通道数,单位kbps,这里的k为1000
  6. 块(chunk):一般的音频都是分为若干个块(chunk)保存,每个chunk块包含音频的数据片段和控制信息,可能包含了块的控制信息如块的大小、声道、采样率、位深等信息以及真正的音频数据流(大小由控制头确认)等,不同格式的文件块的控制信息内容不同。在moviepy中处理音频(如保存音频)时,块就是通用的数据块,没有考虑控制信息,通过设定块大小来读写指定大小的数据。

更多关于音频参数的说明请参考《音频基础知识》、《音频 属性详解(涉及采样率、通道数、位数、比特率、帧等)》。

二、AudioClip简介

AudioClip是一个音频剪辑的基类,其父类是Clip。AudioClip带有make_frame属性,该属性根据时间参数t返回一个形如[f_t]或[f_t1,f_t2]的列表,[f_t]、[f_t1,f_t2]分别对应单声道音频numpy数组和立体声音频numpy数组。这些数组的每个元素都是为-1到1之间的浮点数。

老猿理解AudioClip对应的音频帧数据是一个列表,这个列表有如下特征:
1、列表的长度等于音频的通道数,目前仅支持1和2,即单声道和双声道;
2、列表中的元素为-1到1之间的浮点数,其精度与采样位数相关;
3、列表中元素的大小除了表示音调还表征了音量。

三、构造方法

调用语法:

__init__(self, make_frame=None, duration=None, fps=None)

参数说明:
  • make_frame:帧的构建方法,帧的构建方法用于根据时间构建帧,该方法是get_frame获取帧时调用的方法。帧的构建可以从已有剪辑中获取或变换,也可以代码自己填充;
  • duration:音频剪辑的时长
  • fps:这里的fps可以理解为音频的采用率
功能说明:

构造方法用于使用参数同名的实例变量记录参数传入的make_frame、duration和fps,如果make_frame非空则会通过make_frame获取开始位置的音频帧后获取音频的通道数记录到实例变量nchannels属性,如果duration非空,则会同时更新实例变量duration和end。

四、iter_chunks方法

iter_chunks方法返回一个迭代器,通过这个迭代器可以返回一个包含音频剪辑内容块的数组。

调用语法:

iter_chunks(self, chunksize=None, chunk_duration=None, fps=None,quantize=False, nbytes=2, logger=None)

参数说明:
  • chunksize:块的大小
  • chunk_duration:块包含的音频时长,其值不为None时,则chunksize=chunk_duration*fps向下取整,如果chunksize有值也被计算值覆盖
  • fps:块输出的采样频率,如果为None则等于剪辑的fps属性
  • quantize:是否量化处理,如果为True,则将音频帧对应的音频数据进行如下处理:
  1. 将每个元素的大小超出[-0.99,0.99]这个范围的,则大于0.99的被设置为0.99,小于-0.99的被设置为-0.99
  2. 将每个元素的值乘以2的n次方,n的计算方法为:n=采样位数-1采用位数=nbytes*8
  3. 取整返回
  • nbytes:音频采用位数,缺省值为2字节即16位
  • logger:是否开启日志,字符串类型,"bar"表示进度条、None 表示不设置、或任何程序日志记录器的名字

返回的迭代器包含的数据块数=(fps*剪辑的时长)/chunksize+1,这个方法可以在需要对音频剪辑进行变换处理时使用。

五、to_soundarray方法

to_soundarray方法将音频片段转换为一个可以使用pygame播放或者使用wav格式保存的数组。

调用语法:

to_soundarray(self, tt=None, fps=None, quantize=False, nbytes=2, buffersize=50000)

参数说明:
  • tt:为时间浮点数或时间浮点数的列表,用于获取对应时间的音频数据
  • fps:采用频率,如果为None则等于剪辑的fps属性
  • quantize:是否量化处理,请参见iter_chunks方法参数说明
  • nbytes:音频采用位数,缺省值为2字节即16位
  • buffersize:缓冲区大小,从剪辑中转换时,该大小即为处理块的大小

返回值为一个音频数据的np一维数组或二维数组,分别对应tt为时间浮点数或时间浮点数的列表两种情况。如果quantize为False,返回数组的元素为【-1,1】之间的浮点数,否则为整数(请参见iter_chunks方法参数说明)。

六、max_volume方法

max_volume方法是取音频剪辑的最大音量,最大音量也就是音频数组元素绝对值的最大值。

调用语法:max_volume(self, stereo=False, chunksize=50000, logger=None)
说明:
  • stereo:是否立体声,该参数为True且剪辑的声道数为2才会在处理时作为立体声处理,否则作为单声道处理

在老猿的验证环境下,max_volume存在两个BUG,详细的情况请参考《moviepy音视频剪辑:AudioClip的max_volume方法报TypeError: bad operand type for abs(): ‘list‘错》、《moviepy AudioClip的max_volume方法报错ValueError: operands could not be broadcast together with shapes(2,)》的介绍。

七、write_audiofile方法

write_audiofile方法用于将音频剪辑的内容输出到指定文件,该方法替换了低版本的to_audiofile方法。

调用语法:write_audiofile(self, filename, fps=None, nbytes=2, buffersize=2000, codec=None, bitrate=None, ffmpeg_params=None, write_logfile=False, verbose=True, logger='bar')
参数说明:
  • filename:文件名,类型包括文件如mp3、wav、ogg、m4a等都可以
  • fps:帧率,与音频采样率含义相同,每秒编码的帧数,如果为None且音频剪辑设置了fps则以剪辑额的fps属性值作为输出,否则以缺省值44100输出
  • nbytes:音频的采用的位数
  • buffersize:输出缓冲区大小,以该大小作为输出时数据读取块的大小
  • bitrate:码率,音频比特率
  • codec:用于音频编码的编解码器,如果没有指定则系统根据输出文件名类型来确认。默认值为“libmp3lame”,除非视频扩展名为“ogv”或“webm”,在这2种情况下,默认值为“libvorbis”。 如果是16位wav音频设置为 ‘pcm_s16le’、32位wav音频则设置为 ‘pcm_s32le’
  • write_logfile:如果为True,将为音频输出记录日志文件。日志文件将以“.log”结尾,包含输出文件的名称
  • verbose:已经废弃使用,留下来是为了兼容性,以前用于打开/关闭消息。现在使用logger=None。
  • ffmpeg_params:需额外传递的其他ffmpeg参数,用列表传递,形如:[’-option1’,‘value1’,’-option2’,‘value2’]
  • logger:字符串类型,"bar"表示进度条、None 表示不设置、或任何程序日志记录器的名字

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

关于收费专栏

本文为免费专栏文章,本文对应收费专栏文章《moviepy音视频开发:音频剪辑基类AudioClip详解》。与本文章内容对比,收费专栏部分文章内容介绍更深入或案例更多。

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

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

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

跟老猿学Python、学5G!

☞ ░ 前往老猿Python博文目录
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是代码实现: ```c++ #include<iostream> using namespace std; // 定义抽象类Shape class Shape { public: virtual double calArea() = 0; // 纯虚函数 }; // 定义三角形类Triangle class Triangle : public Shape { public: double base, height; Triangle(double b, double h) { base = b; height = h; } double calArea() { return 0.5 * base * height; } }; // 定义矩形类Rectangle class Rectangle : public Shape { public: double length, width; Rectangle(double l, double w) { length = l; width = w; } double calArea() { return length * width; } }; // 定义正方形类Square class Square : public Shape { public: double side; Square(double s) { side = s; } double calArea() { return side * side; } }; // 定义圆形类Circle class Circle : public Shape { public: double radius; Circle(double r) { radius = r; } double calArea() { return 3.14 * radius * radius; } }; // 定义函数fun,输出图形面积 void fun(Shape* s) { cout << "通过基类指针调用,面积为:" << s->calArea() << endl; } void fun(Shape& s) { cout << "通过基类对象引用调用,面积为:" << s.calArea() << endl; } int main() { // 定义Triangle、Rectangle、Square、Circle类的对象 double b, h, l, w, s, r; cout << "请输入三角形的底和高:" << endl; cin >> b >> h; Triangle tri(b, h); cout << "请输入矩形的长和宽:" << endl; cin >> l >> w; Rectangle rec(l, w); cout << "请输入正方形的边长:" << endl; cin >> s; Square squ(s); cout << "请输入圆形的半径:" << endl; cin >> r; Circle cir(r); // 分别调用fun函数输出各种图形的面积 cout << "计算三角形面积:" << endl; fun(&tri); fun(tri); cout << "计算长方形面积:" << endl; fun(&rec); fun(rec); cout << "计算正方形面积:" << endl; fun(&squ); fun(squ); cout << "计算圆形面积:" << endl; fun(&cir); fun(cir); return 0; } ``` 运行结果: ``` 请输入三角形的底和高: 5 7 请输入矩形的长和宽: 4 5 请输入正方形的边长: 6.7 请输入圆形的半径: 3.4 计算三角形面积: 通过基类指针调用,面积为:17.5 通过基类对象引用调用,面积为:17.5 计算长方形面积: 通过基类指针调用,面积为:20 通过基类对象引用调用,面积为:20 计算正方形面积: 通过基类指针调用,面积为:44.89 通过基类对象引用调用,面积为:44.89 计算圆形面积: 通过基类指针调用,面积为:36.3168 通过基类对象引用调用,面积为:36.3168 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LaoYuanPython

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值