最近在做基于微信小程序【垃圾分类引导指南】的语音识别功能模块时,遇到了一个比较头疼得事情,由于腾讯AI开放平台的接口只支持PCM、WAV、AMR和SILK四种音频格式,而微信小程序录音的音频文件是mp3格式的(此处就是踩得第一大坑了,刚开始看到开发文档是的时候心里还暗喜了一波,因为微信小程序录音文件就可以设置为SILK格式,这样岂不是可以不费吹灰之力就搞定了想想有点头疼的语音识别啦然而我们终究还是太年轻折腾了半天,在真机测试的时候发现木有半点反应,调试发现没有生成录音文件,真的是丈二和尚摸不着头脑的赶脚,最后查了一番资料才知道微信小程序在真机上只能设置成acc和mp3格式的),那么这里就不得不进行音频格式转化了。
此次分享废话不多说,直接上每一步的代码,首先上一波流程图
微信小程序端语音页面代码如下
<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
})
}
}
})
})
}
后端代码采用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;
}
至此,微信小程序语音识别就结束了,又可以愉快的玩耍了~
最后再上一个小程序码,欢迎大家扫码体验,有什么意见可以给我留言哟~