最近做了一个垃圾分类的小程序,可以通过拍照识别、语音录入垃圾名称,来判断垃圾所属分类的类别。
效果:
实现逻辑:
1. 通过小程序录音功能,录制音频文件
2. 利用百度的语音识别功能,将音频转为文字
准备阶段:
你需要注册一个百度云账号,并创建一个应用。参考: https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjgn3
创建好应用后可以获得API Key、Secret Key, 用于小程序开发中。
实现过程:
- 获取AccessToken
这是百度的鉴权认证过程,之后可以获得AccessToken。参考文档: https://ai.baidu.com/ai-doc/SPEECH/bk38lxitu
//app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
// env: 'my-env-id',
traceUser: true,
})
}
this.globalData = {
baiduyuyin:{
apiKey: '你的API Key',
secretKey: '你的Secret Key',
url: 'https://openapi.baidu.com/oauth/2.0/token'
}
}
},
onShow (options) {
that.initBaiduYuyinAccessToken();
},
//初始化语音识别 baiduBccessToken
initBaiduYuyinAccessToken: function () {
var that = this;
var baiduBccessToken = wx.getStorageSync("baidu_yuyin_access_token");
if (baiduBccessToken == undefined || baiduBccessToken == '') {
that.getBaiduYuyinAccessToken();
} else {
var baiduTime = wx.getStorageSync("baidu_yuyin_time");
var timeNum = new Date(parseInt(new Date().getTime() - baiduTime) * 1000).getDay();
if (timeNum > 28) {
that.getBaiduAccessToken();
}
}
},
getBaiduYuyinAccessToken: function () {
var that = this;
var baiduyuyin = that.globalData.baiduyuyin;
console.log(baiduyuyin);
wx.request({
url: baiduyuyin.url,
data: {
grant_type: 'client_credentials',
client_id: baiduyuyin.apiKey,
client_secret: baiduyuyin.secretKey
},
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success(res) {
wx.setStorageSync("baidu_yuyin_access_token", res.data.access_token);
wx.setStorageSync("baidu_yuyin_time", new Date().getTime());
}
})
},
})
我将鉴权过程放到了app.js, 在小程序启动时就能完成。这样就能保证在语音识别之前就能获取到AccessToken。避免在众多的异步操作中的复杂逻辑。
2. wxml点击按钮
<view class='item' catch:touchstart="handleTouchStart" catch:touchend="handleTouchEnd">
<image src="../../images/voice.png" mode="widthFix"></image>
<text>语音识别</text>
</view>
定义2个手势动作
1)触碰时开始录音catch:touchstart="handleTouchStart"
2)移开时结束录音catch:touchend="handleTouchEnd"
const recorderManager = wx.getRecorderManager()
//语音识别
handleTouchStart: function(e){
//录音参数
const options = {
sampleRate: 16000,
numberOfChannels: 1,
encodeBitRate: 48000,
format: 'PCM'
}
//开启录音
recorderManager.start(options);
wx.showLoading({
title: '正在识别中...',
})
},
handleTouchEnd: function(e){
recorderManager.stop();
},
录音api:https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.html
3.利用recorderManager.onStop监听录音结束,并生成音频文件
参考api: https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.onStop.html
bindRecorderStopEvent: function(){
recorderManager.onStop((res) => {
var baiduBccessToken = wx.getStorageSync("baidu_yuyin_access_token");
var tempFilePath = res.tempFilePath;//音频文件地址
// var fileSize = res.fileSize;
const fs = wx.getFileSystemManager();
fs.readFile({//读取文件并转为ArrayBuffer
filePath: tempFilePath,
success(res) {
const base64 = wx.arrayBufferToBase64(res.data);
var fileSize = res.data.byteLength;
wx.request({
url: 'https://vop.baidu.com/server_api',
data: {
format: 'pcm',
rate: 16000,
channel: 1,
cuid: 'sdfdfdfsfs',
token: baiduBccessToken,
speech: base64,
len: fileSize
},
method: 'POST',
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
wx.hideLoading();
console.log(res.data);
var result = res.data.result;
if (result.length == 0){
wx.showToast({
title: "未识别到语音信息!",
icon: 'none',
duration: 3000
})
return ;
}
var keyword = result[0];
keyword = keyword.replace("。", "");
wx.navigateTo({
url: '/pages/search/search?keyword=' + keyword
})
}
})
}
})
})
}
百度语音api要求音频文件要转为base64格式。利用fs.readFile读取文件并放到ArrayBuffer中,利用wx.arrayBufferToBase64(res.data)将其转为base64。
读取音频文件api: https://developers.weixin.qq.com/miniprogram/dev/api/file/FileSystemManager.readFile.html
最后调用https://vop.baidu.com/server_api识别接口就可以将语音转为文字了。