大家好,我是Angus,最近突然被组里的大佬拉去支持一个拍照翻译、语音翻译、文本翻译的项目,负责语音翻译部分的开发,一开始觉得没啥难度,觉得还是简单切切图,写写逻辑,但是后面遇到了一系列棘手的问题,解决了之后,觉得挺有意义,决定写篇文章和大家分享下。
需求
用户在支付宝小程序中的语音翻译界面,按住语音按钮,开启麦克风,完成语音输入,录音完成后,将用户输入的语音,同时转成语音和文本进行翻译。
当时心想,除了注意一些边界条件,不就是在录音完成以后,把数据按照接口定义的类型传给后端,拿到返回的数据再在前端展示,这不是有手就行?起飞。于是马上开始开发起来。
问题出现
当我迅速把页面切好后,决定先写个简单的逻辑,先把接口调通再说,于是乎打开有道的翻译接口文档(这个项目我们并没有后端,因为有道的AI自然语言翻译服务,能支持我们所有的需求),看到了下面的接口参数定义,嗯,参数有点多...
当写到format这个参数的时候,觉得事情开始不对劲了起来,这个语音文件的格式,只支持wav,咋和支付宝小程序录音API返回给我的语音文件格式有点不一样,然后迅速打开支付宝小程序开发文档,看一下开始录音时的demo和需要传的参数。
let recorderManager = my.getRecorderManager();
recorderManager.start({
duration: 600000,
format:aac
})
支付宝录音API返回的音频只支持AAC和MP3格式,愣是没有WAV,开始有一丝丝慌了起来。
逛了一下支付宝小程序的社区,想到了一些解决方案:
(1)官方能不能增加wav录音格式(官方给出暂时不考虑)。好,官方很硬
(2)让后端能不能支持格式为aac/mp3格式的音频(后端推不动)
(3)有一个工具ffmpeg(安装) 命令行转(不满足需求)
麻了,这不坠机了?
分析和解决问题
已知支付宝录音API返回的mp3/aac格式的音频文件,有道翻译接口需要的是格式为wav的音频文件,那只能将支付宝小程序返回的mp3/aac的音频文件转换成有道需要的wav格式的音频文件就行了,嗯,看起来很简单,应该有这种库吧。自己在一些开源社区找到了很多库,也有一些符合要求的库,于是和组里的大佬们交流了一下,大佬推荐了一个库,支持转换音频的格式,github有一个开源库js-mp3,可以将MP3的arraybuffer转换成pcm格式的arraybuffer。好家伙,这一句话触及我知识盲区了...
啥是pcm?
PCM:PCM(Pulse Code Modulation----脉冲编码调制)。所谓PCM编码就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。PCM数据是最原始的音频数据,完全无损。
那pcm和wav有啥关系?
WAV是使用PCM编码的一种音频格式。但是这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换成WMA。简单来说,PCM加上头信息就是WAV格式的音频。
非常好,看到了胜利的曙光,起飞。
安装完这个包后,马上开始coding。
写了一个简单的demo,可以将mp3格式的音频转换成pcm,nice。
于是马上在项目中开发起来,三下五除二写完,开始调试,果不其然失败了,绝望。
分析js-mp3转码不成功的原因
MP3有几种格式
下载ultraEdit对MP3文件头分析。
音频数据帧
每个帧都有4 字节帧头 + 2 字节CRC校验(存在是否由帧头决定)+ 数据(MAIN_DATA)
Ø 帧头
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
一顿分析后,得出总结,js-mp3这个包只支持采样率为32k的音频转码,导致录音文件体积过大,不满足有道接口2M之内的需求。
问题来了,啥是采样率?
音频采样率是指录音设备在一秒钟内对声音信号的采样次数,采样频率越高声音的还原就越真实越自然。在当今的主流采集卡上,采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级,22.05KHz只能达到FM广播的声音品质,44.1KHz则是理论上的CD音质界限,48KHz则更加精确一些。
于是想着能不能有一个包能将js-mp3转码后的音频采样率降下来,使音频文件体积减小,满足接口2M之内的要求。此时再次向组里的大佬们求助,又推荐了一个包pcm-util,可以将降低音频的采样率。
// 和录音的格式一样
const fromFormat = {
channels: 1,
sampleRate: 32000,
interleaved: true,
float: false,
samplesPerFrame: 1152,
signed: true
}
// 目标音频的格式
const toFormat = {
channels: 1,
sampleRate: 16000,
bitDepth: 8,
interleaved: true,
float: false,
samplesPerFrame: 576,
signed: true
}
var pcmAB = pcm.convert(pcmArrayBuffer, fromFormat, toFormat)
迅速在项目中开发了起来,一顿操作后,终于在真机中听到了那句翻译成英文的hello,我发誓,这辈子没听过这么好听的“hello”...
总结
对于需求和功能
不能小看任何一个需求,有时候你觉得很简单,其实里面的坑多的一批,尤其对于我们这种应届生,感觉对于任何需求,都得保持一种谨慎的姿态,对于需求的要有一定深度的理解,千万不能想当然的去做。
任何一个功能的实现,都必须经过下面的步骤。
- 需求分析(包括需求调研,需求讨论,需求确定,接口确认)
- 功能设计(设计该功能实现细节,要用到什么技术方案等)
- 功能实现(从软件代码技术层面实现功能)
- 功能测试(包括开发自测,提交测试,业务测试)
- 需求上线(业务验收,验收是否通过,代码是否回退)
关于心态
千万不能慌,不会就问,切记自己一个人瞎琢磨,办法总比问题多,沉着冷静逐一击破。
关于音频知识的拓展
音频是什么
声音是由物体振动产生的,振动的快慢(频率)决定了声音的音调(男高音,男低音),振动的幅度决定了声音的大小(音量|响度),振动的物体的特性决定了声音的音色。音调、音量和音色称为声音的三要素。
声音可以用模拟信号来表示的,模拟信号的概念如下:
模拟信号是指用连续变化的物理量表示的信息,其信号的幅度,或频率,或相位随时间作连续变化,或在一段连续的时间间隔内,其代表信息的特征量可以在任意瞬间呈现为任意数值的信号。
横轴是时间
模拟信号是连续的,在传输时特别容易受干扰,所以在模拟信号在传输时经常要转化成不连续的数字信号。转化的过程主要包括:采样、量化、编码等过程。
你可以把采样理解为打点,在0-1s内打48000个点,就采样了48000次,采样率就是48000。
量化是指在纵轴(y轴)上对声音进行数字化,决定了y轴的范围。比如用16bit的数据表示声音的一个采样,16bit表示的范围是[-32768,32767],供65536个可能的取值。
编码就是按照一定的格式记录采样和量化之后的数据。音频的原始数据是PCM数据,Pulse Code Modulation,包含以下内容:
- 采样大小 一个采样用多少bit存放,常用的16bit,采样大小越大
- 采样率 1s采样多少次
- 声道数 左声道、右声道,双声道
音频的比特率
(1s种音频的大小)计算方式为
音频码率=采样大小*采样率*声道
以 CD 的音质为例:量化格式为 16 bit (2 byte),采样率 44100 ,声道数为 2,,存放1s钟音频数据需要的大小为
44100 * 16 * 2 = 1378.125 kbps
如果是1分钟,需要的大小为
1378.125 * 60 / 8 / 1024 = 10.09 MB
音频编码
CD音质的音频,存放一分钟数据需要的大小为10M,太大了,也需要压缩(编码)。编码的过程大概如下:
常见的编码方式有:WAV、MP3和AAC格式。
音频的编码方式不像视频那样那么多,而且音频在各个浏览器基本上都可以播放。
具体的每种编码格式包含的音频是怎么构成的,这里就不讲了。
封装格式
我们把视频数据、音频数据打包到一起,然后再添加一些基本信息,例如分辨率、时长、标题等,构成一个文件,这个文件称为封装格式。常见的封装格式有MP4,MOV,MPEG,WEBM等。
主要封装格式如下:
| 名称 | 推出机构 | 流媒体(边下边播) | 支持的视频编码 | 支持的音频编码 | 目前使用领域 |
|---|---|---|---|---|---|
| MP4 | MPEG | 支持 | MPEG-2,MPEG-44,H.264等 | AAC,MPEG-1等 | 互联网视频网站 |
| TS | MPEG | 支持 | MPEG-4,H.264等 | MPEG-1 Layers I, II, III, AAC, | IPTV,数字电视 |
| FLV | Adobe Inc. | 支持 | Sorenson, VP6, H.264 | MP3, ADPCM, Linear PCM, AAC等 | 互联网视频网站 |
| MKV | CoreCodec Inc. | 支持 | 几乎所有格式 | 几乎所有格式 | 互联网视频网站 |
| AVI | Microsoft Inc. | 不支持 | 几乎所有格式 | 几乎所有格式 | BT下载影视 |
从上表中可以看到,封装格式往往是与视频编码无关的,一个mp4文件,里面的视频流编码可以是h264,也可以是mpeg-4,所以就会出现,同样都是mp4文件,有的浏览器可以放,有的浏览器就放不了的问题,因为能不能放是由视频码流的编码格式决定的。
操作音视频必备工具-FFMPEG
这部分内容有点多,大家可以移步这篇文章原来FFmpeg这么有意思
参考文章
浏览器中的音视频知识总结(工作中需要和音视频打交道必看!)
wav音频与pcm音频的区别
小程序——MP3转pcm之殇
随手点赞,将爱传递 :)