一、需求
需求是需要将 在微信小程序端点击录制按钮 录制的音频文件转为文字,显示在搜索框,然后根据 正则 进行 垃圾种类的查询
将查询结果渲染在下面的列表
二、问题描述
具体的细节功能逻辑这里不再说,主要针对百度的语音识别接口出现的一些问题及解决进行说明
可以参考:
- 参考baidu新手指南的步骤:https://ai.baidu.com/ai-doc/SPEECH/qknh9i8ed
- 参考baidu语音识别导览:https://ai.baidu.com/ai-doc/SPEECH/Ek39uxgre
- 参考baidu短语音识别标准版api使用:https://ai.baidu.com/ai-doc/SPEECH/Vk38lxily(对于小程序不是很详细,可以参考我下面的部分代码)
- 参考微信小程序官方文档全局录音管理器使用:https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.html
功能实现大致步骤:
- 使用RecorderManager录制音频文件,获得指定格式(mp3、pcm、aac、wav),上传文件,获取临时地址,使用的音频文件临时地址转码base64
- 创建百度接口的应用(默认创建应用会包含语音识别功能模块,但是好像需要自己领取免费额度),然后记录需要获取access_token的参数到小程序,接着获取token
- 携带 token 、音频参数 及 各种控制参数 等 访问api
- 拿到数据渲染
有一些坑
- 音频文件格式(
mp3、pcm、aac、wav
选择哪种?百度接口推荐pcm,好在微信小程序RecorderManager.start(Object object)
可以在直接选择,否者转码较麻烦),RecorderManager.start(Object object)官方文档并转码base64
格式 - 音频文件的大小(字节为单位):因为后面访问接口的参数需要len,即音频文件的字节大小,不是
转为base64
的长度,否则会报invalid audio length
(重要) - 关于访问api怎么携带参数的问题,是选择json格式的还是row格式的请求方式,这里不设置好的话会出现
json param error
(重要)
问题1录制音频参数及格式选择
在微信端需要设置录音参数,需要跟api上面要求的保持一致,其中format 可选 mp3、pcm、aac、wav
api 上面说最好pcm格式
//录音参数
const options = {
duration: 10000,
sampleRate: 16000,
numberOfChannels: 1,
encodeBitRate: 48000,
format: 'pcm'
}
//开启录音
recorderManager.start(options);
wx.showToast({
title: '正在录音,往下滑动取消发送',
icon: 'none',
duration: 10000
})
接着就是recorderManager.onStop((res)
监控录音结束,从res中拿到临时地址tempFilePath
const {
tempFilePath
} = res;
wx.showLoading({
title: '语音检索中',
})
问题2音频文件的字节大小填充api请求参数len
及编码填充speech
需要在获得base64编码之前获取,方便后续的json格式访问api必须的参数 len
获得的方式使用 wx.getFileSystemManager().getFileInfo
,得到的res对象包含size
属性,即以字节为单位的文件大小 ,具体使用参考官方文档
// 2. 拿到file_pcm_len
wx.getFileSystemManager().getFileInfo({
filePath: tempFilePath,
success: res => {
console.log(res)
var file_pcm_len = res.size
// 3. 解析音频,拿到file_pcm_base
// base64格式
wx.getFileSystemManager().readFile({
filePath: tempFilePath,
encoding: "base64",
success: function (res) {
console.log(res.data)
// 3. 然后访问接口
var file_pcm_base = res.data
....
....
....
然后获取base64编码,跟图片获取的的方式类似,参考上述代码
问题3关于请求api格式的方式
大致流程可以参考api说明,但是上面并没有微信小程序demo,访问的方式有
- json方式:请求参数不放在链接中,对于vue和小程序的写法就是放在data中
- row方式:请求参数放在链接中,类似RequestParam,类似
url?xxx=xxx & xxx=xxx ...
这个json格式的弄好花了我些时间,直接贴代码
//6.访问语音api
const askImageToWordsApi = function (file_pcm_base, file_pcm_len) {
return new Promise((resolve, reject) => {
// 2. 访问api
var API_URL = 'http://vop.baidu.com/server_api'
console.log(file_pcm_len)
wx.request({
url: API_URL,
data: JSON.stringify( {
token: wx.getStorageSync('access_token'),
'cuid': "3c-f0-11-ea-74-87",
'format': 'pcm',
'rate': 16000,
'channel': 1,
'speech': file_pcm_base,
'len':file_pcm_len
}),
headers: {
'Content-Type': 'application/json' // 默认值
},
dataType: "json",
method: "POST",
success: function (res) {
console.log(res)
resolve(res);
},
fail: function (res) {
wx.showToast({
title: '网络错误,请重试!',
icon: 'none',
duration: 2000
})
reject(res);
},
complete: function (res) {
resolve(res);
}
})
})
}
最最需要注意的就,确保是正确的json格式
data: JSON.stringify( {
token: wx.getStorageSync('access_token'),
'cuid': "3c-f0-11-ea-74-87",
'format': 'pcm',
'rate': 16000,
'channel': 1,
'speech': file_pcm_base,
'len':file_pcm_len
}),
之前key没加' '
和 JSON.stringify
一直报 json param error
,然后加上就可以了