“ 最近在做基于微信小程序【垃圾分类引导指南】的语音识别功能模块时,遇到了一个比较头疼得事情,由于腾讯AI开放平台的接口只支持PCM、WAV、AMR和SILK四种音频格式,而微信小程序录音的音频文件是mp3格式的(此处就是踩得第一大坑了,刚开始看到开发文档是的时候心里还暗喜了一波,因为微信小程序录音文件就可以设置为SILK格式,这样岂不是可以不费吹灰之力就搞定了想想有点头疼的语音识别啦~然而我们终究还是太年轻~折腾了半天,在真机测试的时候发现木有半点反应,调试发现没有生成录音文件,真的是丈二和尚摸不着头脑的赶脚,最后查了一番资料才知道微信小程序在真机上只能设置成acc和mp3格式的),那么这里就不得不进行音频格式转化了。”
此次分享废话不多说,直接上每一步的代码,首先上一波流程图
01—小程序部分
微信小程序端语音页面代码如下
<view class='serac_img' bindtap="startRecord" wx:if="{{hasRecord == false}}">
<image src='../../images/voice.png' mode="widthFix"></image>
<text>语音查询</text>
</view>
<view class='serac_img' bindtap="stopRecord" wx:if="{{hasRecord == true}}">
<image src='../../images/stop.png' mode="widthFix"></image>
<text>录音中</text>
</view>
Js部分的话,先引入wx.getRecorderManager()
const recorderManager = wx.getRecorderManager()
然后,在录音开始事件中进行录音参数设置及开启录音
startRecord() {
this.setData({
hasRecord: true
})
const options = {
duration: 10000,
sampleRate: 16000,
numberOfChannels: 1,
encodeBitRate: 48000,
format: 'mp3'
}
recorderManager.start(options);
}
最后,在停止录音事件里进行停止录音操作,并监控停止录音事件,获取到录音文件,使用wx.uploadFile()方法将录音文件传给后端,后端处理完成后返回最终处理信息并展示
stopRecord() {
this.setData({ hasRecord: false })
var that = this
recorderManager.stop()
recorderManager.onStop((res) => {
const { tempFilePath } = res;
wx.showLoading({
title: '语音检索中',
})
//上传录制的音频
wx.uploadFile({
url: requestUrl + 'Rubbish/VoiceSearch',
filePath: tempFilePath,
name: 'voices',
success: function (event) {
var datas = JSON.parse(event.data);
if (datas.status == 0) {
wx.hideLoading()
if (datas.result.list.length > 0) {
that.setData({
detail: datas.result
})
} else {
wx.showToast({
title: '如此聪明伶俐的我居然会词穷,我要喊我父亲大人送我去深造~',
icon: 'none',
duration: 2000
})
}
} else {
wx.showToast({
title: datas.msg,
icon: 'none',
duration: 2000
})
}
}
})
})
}
02—服务端部分
后端代码采用avconv进行音频转化,这里采用腾讯语音识别-echo版Api接口来进行语音识别,具体实现如下
接收录音文件并进行转码
public function VoiceSearch(){
$typeArr = array("mp3");
$path = "Public/uploads/voice_search/"; //上传路径
$name = $_FILES['voices']['name'];
$size = $_FILES['voices']['size'];
$name_tmp =$_FILES['voices']['tmp_name'];
if (empty($name)) {
jsonReturn(20000,'小主,请开口说话~');
}
$type = strtolower(substr(strrchr($name, '.'), 1)); //获取文件类型
if (!in_array($type, $typeArr)) {
jsonReturn(20002,'文件格式好像不对哟~');
}
if ($size > (5000 * 1024)) { //上传大小
jsonReturn(20003,'小主,口才可是真真的好呢~');
}
$pic_name = date('YmdHis') . rand(10000, 99999) . "." . $type; //名称
$pic_url = $path . $pic_name; //上传后路径+名称
if (move_uploaded_file($name_tmp, $pic_url)) { //临时文件转移到目标文件夹
$r_path = $_SERVER['DOCUMENT_ROOT'];
$wavname = date('YmdHis') . rand(10000, 99999).".wav";
$newpath = "Public/uploads/voice_search/".$wavname;
//执行文件格式转换
$exec1 = "avconv -i $r_path/$pic_url -vn -f wav $r_path/$newpath";
exec($exec1,$info,$status);
//转换成功后进入识别阶段
if ($status == 0){
//语音识别
$r = $this->voiceGeneral(SITE_URL.'/'.$newpath);
$resu = json_decode($r,true);
if ($resu['ret'] == 0 && $resu['msg'] == 'ok'){
jsonReturn(0,'获取成功',$resu['data']['text']);
}else{
jsonReturn(-1,'哎呀,人潮拥挤,请稍后重试~');
}
}else{
jsonReturn(-1,'哎呀,人潮拥挤,请稍后重试~');
}
} else {
jsonReturn(-1,'哎呀,人潮拥挤,请稍后重试~');
}
}
对接腾讯语音识别Api接口进行语音识别
public function voiceGeneral($path){
$url = 'https://api.ai.qq.com/fcgi-bin/aai/aai_asr';
$data = file_get_contents($path);
$base64 = base64_encode($data);
// 设置请求数据
$appkey = 'WjjphPD0oqrPJSYm';
$params = array(
'app_id' => '2018656256',
'format' => '2',
'rate' => '16000',
'speech' => $base64,
'time_stamp' => strval(time()),
'nonce_str' => strval(rand()),
'sign' => '',
);
$params['sign'] = $this->getReqSign($params, $appkey);
// 执行API调用
$response = httpRequest($url, 'POST',$params);
return $response;
}
public function getReqSign($params , $appkey )
{
// 1. 字典升序排序
ksort($params);
// 2. 拼按URL键值对
$str = '';
foreach ($params as $key => $value)
{
if ($value !== '')
{
$str .= $key . '=' . urlencode($value) . '&';
}
}
// 3. 拼接app_key
$str .= 'app_key=' . $appkey;
// 4. MD5运算+转换大写,得到请求签名
$sign = strtoupper(md5($str));
return $sign;
}
至此,微信小程序语音识别就结束了,又可以愉快的玩耍了~