一、前言
前面的博客对 音频切割工具ffmpeg的使用 以及 获取音频基本信息简易切割 等作出了总结,本文将对音频精准切分作出原理分析以及技术落地总结。
“音频精准切分”是个什么概念?我们当前对音频的切分需求大部分上是秒级别的切分如下1所示(使用ffmpeg的切分,不懂得可以看前面的博客),少有会到百毫秒级别的切分,但如果到毫秒级的切分呢?有人说了,像2一样不就行了,把精度设置更高一些。可是事实结果真的是这样吗?能得到想要的结果吗?当然是否定的!
各个音频切割软件,都不能直接对mp3音频文件作出百毫秒级以下的音频切分。接下来我们将分析这样情况出现的原因,和我们如何对mp3音频作出精准切分对策。
1. ffmpeg -y -i input.mp3 -ss 0 -t 5.2 outpath.mp3
2. ffmpeg -y -i input.mp3 -ss 0.001 -t 5.223 outpath.mp3
二、音频属性介绍——mp3,wav
当前我们最常见的音频格式是mp3音频,MP3作为一个有损压缩的音频格式,它都有哪些属性呢?如下:
1.mp3 属性:44.1KHZ, 128kb/s, 双声道
采样率——44.1KHZ,每秒钟对音频的采样频次。
通道数——双声道(立体音)左右耳听到差异的声音。
采样位数 采样样本幅度量化,衡量声音波动变化的一个
参数,也可以说是声卡的分辨率。即纵轴刻度的精确度。
——1 字节(也就是8bit) 只能记录 256 个数, 也就是只能将振幅划分成 256 个等级;
——2 字节(也就是16bit) 可以细到 65536 个数, CD 标准
比特率(码率)——128kb/s,每秒钟占多少kb。
比特率=采样率*采样位数*通道数
如下图所示,采样率即是一秒钟对音频的采样频次(横坐标的密度),而采样位数则是对采样高度的量化即是纵坐标密度的刻画。
MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3 的全称应为MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group)在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即 Layer-1、Layer2、Layer3,且分别对应MP1、MP2、MP3 这三种声音文件。
如何计算MP3帧的长度呢
以下为mpeg压缩格式的每帧数据的采样点,可以看出mp3格式的每帧采样点为1152个
| MPEG 1 | MPEG 2 | MPEG 2.5 |
Layer 1 | 384 | 384 | 384 |
Layer 2 | 1152 | 1152 | 1152 |
Layer 3 | 1152 | 576 | 576 |
而一个音频音频帧的播放时长计算为:
音频帧的播放时间=每帧对应的采样样本的个数/采样频率(单位为s)
因此我们可以算出,如果我们定义一个mp3的采样率为44.1khz,则一个mp3音频帧的长度为,1152 /44100 *1000 =26.122ms。
wav
wav格式的音频则是无压缩的音频格式,并没有严格规定它的基本单位,也就是音频帧的具体概念,博主当前并没有找到wav格式的音频对音频帧中数据采样点的限制,因此猜测wav的每帧对应采样样本个数可以为极低,而音频帧数很高,从而导致以下的公式,每帧长度便会很小。
三、精准切分音频解决方案
上述第二节,我们已经分说明了MP3格式以及wav格式中每帧长度计算,其中MP3格式每帧长度约为26ms,因此在对MP3音频切分时,精确度就不可能超过26ms,因为要对音频数据进行保护。所以我们如果在切分时很有可能会造成26ms左右数据块切割丢失的情况。如下图所示,在30ms和85ms之间进行的切分,就会导致两个数据块造成损失。
那么我们如何对才能更精准的对音频进行切分呢,显然减少音频帧的长度是一个很直接的办法,但是我们MP3音频已经固定死的每帧采样点、和我们音频每秒采样率,显然减少音频每帧长度这条路在MP3格式上是行不通的。
因此我们考虑到wav是非压缩格式的音频文件,可以采用将MP3转换为wav,精准切分后,再将wav转换为MP3即可。经过测试,精确度可达到1ms,显然符合了我们的初衷。
不可避免的问题:wav格式的音频长度可以为精确至毫秒级,但wav转换至mp3之后,为了补全mp3音频的帧,依旧会出现几十毫秒级的长度的误差,但对于当前应用没有影响。
四、总结
在解决音频精准切分的路子上走了几步,发现音频的切分也不是一个很容易完成的工作,通过上述方案:
MP3转wav,wav精准切分,wav转MP3这种笨方法可以完成MP3音频的精准切分,但同时也抛出了一个问题,那就是wav格式的音频到底有没有音频帧的概念?如果有,他们的音频帧中每帧采样点是多少呢?还望大家共同探讨。