一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
分析
-
腾讯语音识别涉及到secretId及secretKey等敏感信息,所以采用云开发的方式,通过调用云函数来实现相关接口的请求。
-
云服务空间阿里云与腾讯云使用区别不大,这里选择阿里云。
实现
创建项目
创建一个uniCloud项目,并关联云服务空间,这里选择的是阿里云。项目结构如下图:
编写云函数
- 云函数名为:speech-recognition。直接使用HBuilder提供的可视化方式创建。
- 在该云函数的根目录下执行:
npm init -y
- 安装腾讯云提供的Node.js的SDK包:
npm install tencentcloud-sdk-nodejs --save
- 将腾讯云生成的示例代码复制到云函数中,并改造下返回结果:
- 最终的云函数如下:(注意,secretId和secretKey要改成自己的)
//cloudfunctions\speech-recognition\index.js
'use strict';
/**
* 腾讯一句话语音识别
*/
exports.main = async (event, context) => {
console.log('参数:');
console.log(event);
let result;
const tencentcloud = require("tencentcloud-sdk-nodejs");
const AsrClient = tencentcloud.asr.v20190614.Client;
const clientConfig = {
credential: {
secretId: "填写腾讯云上的secretId",
secretKey: "填写腾讯云上的secretKey",
},
region: "",
profile: {
httpProfile: {
endpoint: "asr.tencentcloudapi.com",
},
},
};
const client = new AsrClient(clientConfig);
const params = {
"ProjectId": 0,
"SubServiceType": 2,
"EngSerViceType": event.EngSerViceType,
"SourceType": 0,
"Url": event.url,
"VoiceFormat": event.VoiceFormat,
"UsrAudioKey": event.id
};
await client.SentenceRecognition(params).then(
(data) => {
result = data;
},
(err) => {
result = err;
}
);
console.log('识别结果:')
console.log(result);
return result;
};
实现录音功能
- 先定义一个全局录音管理器
//全局录音管理器
const recorderManager = uni.getRecorderManager();
- 在onLoad方法中实现录音停止时的回调监听
onLoad() {
let self = this;
//停止录音时的回调
recorderManager.onStop(function(res) {
console.log('recorder stop' + JSON.stringify(res));
self.voicePath = res.tempFilePath;
});
},
- 实现录音开始方法
methods: {
//开始录音
startRecord() {
console.log('开始录音');
recorderManager.start({
duration: 60000,
format: 'mp3'
});
},
}
- 腾讯一句话语音识别最大支持一分钟的时长,所以录音时长不应超过一分钟,使用参数duration
- 腾讯一句话语音识别只运行mp3和wav两种格式,这里采用mpe格式。
录音文件上传至云存储
腾讯一句话语音识别支持两种数据传输方式:
建议采用url方式,不仅简单,而且不易出错~
onLoad() {
let self = this;
//停止录音时的回调
recorderManager.onStop(function(res) {
let tempFilePath = res.tempFilePath;
//将录音文件上传到云存储
uniCloud.uploadFile({
filePath: tempFilePath,
cloudPath: new Date().getTime() + tempFilePath.substr(tempFilePath.lastIndexOf('.'), tempFilePath.length),
onUploadProgress: function(progressEvent) {
if ((progressEvent.loaded * 100) >= progressEvent.total) {
//uni.hideLoading();
}
},
success(result) {
const src = result.fileID;
console.log('文件地址:' + src);
},
fail(fail) {
console.log(fail);
},
complete() {}
});
});
},
- 阿里云服务空间上传后直接返回文件的URL地址。而腾讯云返回的为
cloud://形式,如需展示需要调用getTempFileURL获取链接- 使用阿里云时,
cloudPath为云端文件名,请勿使用非法字符
调用云函数识别语音结果
参数说明如下:
- url:文件地址,需要公网可访问
- id:用户端对此任务的唯一标识,用户自助生成,用于用户查找识别结果
- EngSerViceType:引擎模型类型。 电话场景: • 8k_en:电话 8k 英语; • 8k_zh:电话 8k 中文普通话通用; 非电话场景: • 16k_zh:16k 中文普通话通用; • 16k_en:16k 英语; • 16k_ca:16k 粤语; • 16k_ja:16k 日语; • 16k_zh_medical:16k 医疗; • 16k_zh_dialect:多方言。
- VoiceFormat :识别音频的音频格式。mp3、wav。
uniCloud.callFunction({
name: 'speech-recognition',
data: {
url: src,
id: (new Date().getTime()).toString(),
EngSerViceType: '16k_zh',
VoiceFormat: src.substr(src.lastIndexOf('.') + 1, src.length)
}
})
.then(speechRes => {
console.log('识别用户声音结果:');
console.log(speechRes);
})
.catch(error => {
console.log(error);
})
踩坑记录
开发者工具不可用
微信开发者工具录音结果与真机录音结果格式不一致,无法被腾讯识别,所以在调试时最好采用真机调试方式。
npm使用
如果在项目根目录下安装了依赖,在云函数中无法使用。要把依赖安装到当前云函数的根目录下并上传到云函数空间。
nodejs版本
uni-app的云函数默认运行环境为nodejs8,而腾讯提供的SDK最低需要nodejs10。uni-app支持nodejs8和nodejs12两个版本,可以在云函数package.json中修改。
{
"cloudfunction-config": {
"runtime": "Nodejs12"
}
}
发行模式
uniCloud若打包成体验版或正式版,需要使用发行模式。
白名单配置
由于云函数调用了阿里或腾讯的服务器,所以需要配置白名单。
完整代码地址
https://gitee.com/hqzmss/uni-app-test01.git