支付宝小程序录音翻译,从起飞到坠机

1,726 阅读10分钟

大家好,我是Angus,最近突然被组里的大佬拉去支持一个拍照翻译、语音翻译、文本翻译的项目,负责语音翻译部分的开发,一开始觉得没啥难度,觉得还是简单切切图,写写逻辑,但是后面遇到了一系列棘手的问题,解决了之后,觉得挺有意义,决定写篇文章和大家分享下。

需求

用户在支付宝小程序中的语音翻译界面,按住语音按钮,开启麦克风,完成语音输入,录音完成后,将用户输入的语音,同时转成语音和文本进行翻译
当时心想,除了注意一些边界条件,不就是在录音完成以后,把数据按照接口定义的类型传给后端,拿到返回的数据再在前端展示,这不是有手就行?起飞。于是马上开始开发起来。

f4d5ee4b23ff32c09bb1b00a7e61bcc0.jpeg

问题出现

当我迅速把页面切好后,决定先写个简单的逻辑,先把接口调通再说,于是乎打开有道的翻译接口文档(这个项目我们并没有后端,因为有道的AI自然语言翻译服务,能支持我们所有的需求),看到了下面的接口参数定义,嗯,参数有点多...

image.png 当写到format这个参数的时候,觉得事情开始不对劲了起来,这个语音文件的格式,只支持wav,咋和支付宝小程序录音API返回给我的语音文件格式有点不一样,然后迅速打开支付宝小程序开发文档,看一下开始录音时的demo和需要传的参数。

let recorderManager = my.getRecorderManager();
recorderManager.start({
 duration: 600000,
 format:aac
})

image.png

支付宝录音API返回的音频只支持AAC和MP3格式,愣是没有WAV,开始有一丝丝慌了起来。

src=http___tva1.sinaimg.cn_large_9150e4e5gy1fxngczdqlrj208c08a75a.jpg&refer=http___tva1.sinaimg.webp
逛了一下支付宝小程序的社区,想到了一些解决方案:
(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格式的音频。

非常好,看到了胜利的曙光,起飞。

207d342c1e3111f920ba7ed607df8d94.jpeg

安装完这个包后,马上开始coding。
写了一个简单的demo,可以将mp3格式的音频转换成pcm,nice。
于是马上在项目中开发起来,三下五除二写完,开始调试,果不其然失败了,绝望。

04bb39b761846e082734401ca50e123b.jpeg

分析js-mp3转码不成功的原因

MP3有几种格式

clipboard.png

下载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等。

主要封装格式如下:

名称推出机构流媒体(边下边播)支持的视频编码支持的音频编码目前使用领域
MP4MPEG支持MPEG-2,MPEG-44,H.264等AAC,MPEG-1等互联网视频网站
TSMPEG支持MPEG-4,H.264等MPEG-1 Layers I, II, III, AAC,IPTV,数字电视
FLVAdobe Inc.支持Sorenson, VP6, H.264MP3, ADPCM, Linear PCM, AAC等互联网视频网站
MKVCoreCodec Inc.支持几乎所有格式几乎所有格式互联网视频网站
AVIMicrosoft Inc.不支持几乎所有格式几乎所有格式BT下载影视

从上表中可以看到,封装格式往往是与视频编码无关的,一个mp4文件,里面的视频流编码可以是h264,也可以是mpeg-4,所以就会出现,同样都是mp4文件,有的浏览器可以放,有的浏览器就放不了的问题,因为能不能放是由视频码流的编码格式决定的。

操作音视频必备工具-FFMPEG

这部分内容有点多,大家可以移步这篇文章原来FFmpeg这么有意思

参考文章

浏览器中的音视频知识总结(工作中需要和音视频打交道必看!)
wav音频与pcm音频的区别
小程序——MP3转pcm之殇

随手点赞,将爱传递 :)