1、 需求背景html
目前咱们科大讯飞平台目前已经支持语音识别相关业务,咱们只要将小程序语音上传(对接)到科大讯飞语音处理后台,就能完成上述需求。node
2、 分析和调研问题git
2.科大讯飞语音接口接收的参数github
将语音转换为对应的文本和语义npm
3.明确需求:小程序
a) Mp3 => pcm
b) Mp3 => speex
c) Mp3 => amr
d) Mp3 => opus后端
a) 有一个工具ffmpeg(安装) 命令行转(不知足需求)
b) 【小程序社区】社区中有两种声音
(1)官方能不能增长pcm录音格式(官方给出暂时不考虑)
(2)MP3 => pcm放在服务器端作(咱们的后端推不动)
(3)【很高兴】得知github js-mp3
开源库能够将MP3的arraybuffer => pcm格式的arraybuffer
https://developers.weixin.qq....微信小程序
a) 网上下载 MP3
b) 在node.js中写对应的demo
c) 能够将MP3转为 pcm(很高兴,也没注意该MP3的采样率是多少)
d) 微信小程序demo, 将录音的mp3,将录音的MP3文件由临时文件保存到本地文件(此时不知道保存到哪里了,手机的根目录/tencent/MicroMsg/wxafiles/tem_XXXXXX, 文件名变了,文件管理功能不强大)
e) 将录音MP3(16k)试着用 js-mp3转码(很惋惜失败了,绝望)浏览器
a) MP3有几种格式服务器
b) 下载ultraEdit对MP3文件头分析
音频数据帧
每一个帧都有4 字节帧头 + 2 字节CRC校验(存在是否由帧头决定)+ 尸体数据(MAIN_DATA) Ø 帧头 AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
c) js-mp3支持的MP3帧数据的前几位是
(1)49 68
1001001 011 01 00 0
保留 保留
(2)49 51
1001001 010 10 00 1
Mpeg2 保留
(3)FF FA
11111111 111 11 01 0
Mpeg1 layer3
(4)FF FB
11111111 111 11 01 1
Mpeg1 layer3
总结:这个包只支持采样率为32k以上的音频转码
http://www.mp3-tech.org/progr...
d) 微信MP3(16k,8k)所属格式(几个转码不成功的)
微信 wx.mp3
Ff f3 68 04
1111 1111 1111 0011 0110 1000 0000 0100
Mpeg2 Layer3 比特率 48 采样率 8000
Wx1.mp3
【开头16进制】49 44 33 03
【二级制】0100 1001 0100 0100 0011 0011 0000 0011
Mpeg2.5 layer2 比特率 24 采样率 12000
FF F3
1111 1111 111 10 01 1
Mpeg2 layer3
下载的MP3
Ff f3 40 c0
1111 1111 111 10 01 1 0100 0000 1100 0000
MPEG 2 layer3 比特率 32 采样率 22050
【绝望】js-mp3 好像不行了,重新调研其余包
3、 解决问题
Pcm播放器播不了,wav能播
a) 【曙光】Mp3文件 buffer => arraybuffer
=> audioBuffer =>
wav的ArrayBuffer => buffer(写入文件)
b) Audiobuffer 这个对象是浏览器端的对象(绝望)
c) audio-decode 这个包在node端也支持https://github.com/audiojs/au...
d) 开始测试普通的MP3文件转码ok, 小程序录音的MP3文件又报错
断点调试:这个包引入 ‘is-mp3’
通过分析得知:
wx MP3开头 Ff f3
支持的开头 (1)FF FA/FB (2)49 44/33
怀疑: 这难道不是真正的MP3
手动添加
校验过去了,可是仍是不支持这种采样率为(16k或者8k的),转换时候报错了
获得pcm格式(32k采样率)
let Mp3 = require('js-mp3'); var mp3ArrayBuffer = ...; // prepare your mp3 decoded array buffer here var decoder = Mp3.newDecoder(mp3ArrayBuffer); var pcmArrayBuffer = decoder.decode(); // now you got decoded PCM data
pcm.convert(buffer, fromFormat, toFormat)
Convert array buffer from one format to another.
注意:
采样率 32k 变为 16k
SamplesPerFrame和采样率是对应的
BitDepth不设置的时候,默认是16
保存pcm(pcm文件大小约为MP3文件大小的10倍)文件到本地,此时用ffmpeg将pcm转为wav
(1) 用采样率为16k转换时,时长为原MP3的两倍(严重失真)
(2) 用采样率32k转换时,时长和原mp3一致(不失真)
结论: 上述pcm 32k=> pcm16k时没有成功(toFormat有问题)。
经过排查将bitDepth设为 原来的一半 8,结果 pcm 16k文件约为原mp3大小的5倍,ffmpeg 16k 转为wav播放正常(无失真)
4、对接科大讯飞语音识别Ai
录音时长(s) 转码时间(s)
10.920 7.118
5.8 3.972
1.48 0.918
提交转码后的16k pcm,能够实现语音识别
5、分析和优化
分析
优化
1.变两步为一步 mp3 (16k) => pcm (16k)
2.解决audio-decode 引入错误,若是能将 ,mp3的arraybuffer 分片转为audioBuffer(不依赖整个mp3头),完成 pcm(16k) 直接转换
6、收获 完成了小程序社区没人敢去尝试的一条路 办法总比问题多 沉着冷静逐一击破 后面再优化