Appearance
使用方法
介绍
安卓百度语音识别UTS原生插件集成了短语音识别、离线自定义命令词识别、语音唤醒,SDK内部均为采用流式协议,即用户边说边处理,插件支持uniapp和uniapp x
插件使用注意事项
- 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您使用插件
- 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例
官方文档
https://ai.baidu.com/ai-doc/SPEECH/3ltwvtg6u
联系作者

关注微信公众号可联系作者
插件地址
https://ext.dcloud.net.cn/plugin?id=29753
用法
在需要使用插件的页面加载以下代码
js
import * as module from "@/uni_modules/leven-uts-bdSpeech"js
import * as module from "@/uni_modules/leven-uts-bdSpeech"页面内容
uniapp
vue
<template>
<view>
<uni-card title="功能示例">
<button type="primary" @click="toPage('onlineRecog')">在线识别</button>
<button type="primary" @click="toPage('offlineRecog')">离线命令词</button>
<button type="primary" @click="toPage('wakeup')">唤醒词</button>
<button type="primary" @click="toPage('wakeUpRecog')">唤醒后识别</button>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
export default {
data() {
return {
title: 'Hello'
}
},
mounted() {
this.$nextTick(() => {
//申请插件所需权限
this.requestPermissions();
})
},
methods: {
toPage(type) {
switch (type) {
case "onlineRecog":
uni.navigateTo({
url: "/pages/index/onlineRecog"
})
break
case "offlineRecog":
uni.navigateTo({
url: "/pages/index/offlineRecog"
})
break
case "wakeup":
uni.navigateTo({
url: "/pages/index/wakeup"
})
break
case "wakeUpRecog":
uni.navigateTo({
url: "/pages/index/wakeUpRecog"
})
break
}
},
showMessage(message) {
uni.showToast({
title: message,
icon: "none"
})
},
toAllFilesPermissionPage() {
module.toAllFilesPermissionPage({
complete: (res) => {
if (res.code == 0) {
let data = res.data;
if (!data.status) {
this.showMessage("所有文件访问权限未打开")
} else {
this.showMessage("权限申请完成")
}
} else {
this.showMessage(res.message)
}
}
})
},
checkAllFilesPermission() {
module.checkAllFilesPermission({
complete: (res) => {
if (res.code == 0) {
let data = res.data;
if (!data.status) {
this.toAllFilesPermissionPage();
} else {
this.showMessage("权限申请完成")
}
} else {
this.showMessage(res.message)
}
}
})
},
//申请插件所需权限
requestPermissions() {
module.requestPermissions({
params: {
permissions: [
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.RECORD_AUDIO"
]
},
complete: (res) => {
if (res.code == 0) {
//判断是否有所有文件访问权限
this.checkAllFilesPermission();
} else {
this.showMessage(res.message)
}
}
})
},
}
}
</script>
<style>
</style>vue
<template>
<view>
<uni-card title="在线普通识别功能(含长语音)">
<view>普通识别测试方法:</view>
<view>请保持设备联网,对着麦克风说出日常用语即可。</view>
<view>普通录音限制60s。使用长语音无此限制。</view>
</uni-card>
<uni-card title="设置">
<uni-section title="PID,语种">
<uni-data-checkbox v-model="settingParams.language" :localdata="languageItems"></uni-data-checkbox>
</uni-section>
<uni-section title="LMID,自训练平台ID,请选PID=8002生效">
<uni-data-checkbox v-model="settingParams.lm_id" :localdata="lmIdItems"></uni-data-checkbox>
</uni-section>
<uni-section title="长语音" sub-title="长语音参数,优先级高于vad_endpoint_timeout">
<radio-group @change="changeLongSpeech">
<radio :value="false" style="transform:scale(0.7)" :checked="longSpeechIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="longSpeechIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="VAD时长设置">
<uni-data-checkbox v-model="settingParams['vad.endpoint-timeout']"
:localdata="vadEndpointTimeoutItems"></uni-data-checkbox>
</uni-section>
<uni-section title="VAD是否开启">
<uni-data-checkbox v-model="settingParams.vad" :localdata="vadItems"></uni-data-checkbox>
</uni-section>
<uni-section title="外部音频">
<uni-data-checkbox v-model="settingParams.infile" :localdata="infileItems"></uni-data-checkbox>
</uni-section>
<uni-section title="保存录音">
<radio-group @change="changeSaveAudio">
<radio :value="false" style="transform:scale(0.7)" :checked="saveAudioIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="saveAudioIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="开启代码中音频回调事件" sub-title="不需要音频二进制数据的回调,请勿开启,否则影响性能">
<radio-group @change="changeAcceptAudioData">
<radio :value="false" style="transform:scale(0.7)" :checked="acceptAudioDataIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="acceptAudioDataIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="禁用标点" sub-title="在选择输入法模型的前提下生效">
<radio-group @change="changeDisablePunctuation">
<radio :value="false" style="transform:scale(0.7)" :checked="disablePunctuationIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="disablePunctuationIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="提示音">
<radio-group @change="changeTipsSound">
<radio :value="false" style="transform:scale(0.7)" :checked="tipsSoundIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="tipsSoundIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="开启代码中音量回调事件" sub-title="是否需要音频的音量回调。正常使用请勿开启">
<radio-group @change="changeAcceptAudioVolume">
<radio :value="false" style="transform:scale(0.7)" :checked="acceptAudioVolumeIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="acceptAudioVolumeIndex == 1"></radio>是
</radio-group>
</uni-section>
</uni-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<uni-card title="日志">
<view v-for="(item, index) in logs" :key="index">{{item}}</view>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/SpeechConstant.js"
import {
KeyUtils
} from "@/utils/KeyUtils.js"
export default {
data() {
return {
isStart: false,
//设置参数
settingParams: {
//语种
language: "",
//自训练平台ID
lm_id: "",
//长语音
"enable.long.speech": false,
//长语音时长设置
"vad.endpoint-timeout": "",
//vad是否开启
vad: "",
//外部音频
infile: "",
//开启代码中音频回调事件
"accept-audio-data": false,
//禁用标点
"disable-punctuation": false,
//开启代码中音量回调事件
"accept-audio-volume": false
},
//语种列表
languageItems: [{
"value": "",
"text": "默认"
}, {
"value": "cmn-Hans-CN",
"text": "普通话"
}, {
"value": "en-GB",
"text": "英语"
}, {
"value": "yue-Hans-CN",
"text": "粤语"
}, {
"value": "sichuan-Hans-CN",
"text": "四川话"
}],
//平台id列表
lmIdItems: [{
"value": "",
"text": "默认"
}, {
"value": 1068,
"text": "自训练平台上线的id,和账号维度绑定"
}],
//长语音默认选择
longSpeechIndex: 0,
//平台id列表
vadEndpointTimeoutItems: [{
"value": "",
"text": "默认"
}, {
"value": 0,
"text": "开启长语音(离线不支持)。建议pid选择15372"
}, {
"value": 800,
"text": "800毫秒,静音800ms后断句,适用于输入短语"
}, {
"value": 2000,
"text": "2000毫秒,静音2000ms后断句,适用于输入长句"
}, {
"value": 2230,
"text": "2230, 毫秒,请修改代码中的VAD_ENDPOINT_TIMEOUT,自定义时长(建议800ms-3000ms之间)"
}],
//vad是否开启配置
vadItems: [{
"value": "",
"text": "不设置"
}, {
"value": "dnn",
"text": "默认,推荐模型"
}, {
"value": "touch",
"text": "关闭静音断句功能。用戶手动停止录音"
}],
//外部音频列表
infileItems: [{
"value": "",
"text": "不设置"
}, {
"value": "assets:///com/baidu/android/voicedemo/16k_test.pcm",
"text": "16k采样的测试音频"
}, {
"value": "assets:///com/baidu/android/voicedemo/offline_input.pcm",
"text": "测试离线命令词"
}],
//是否保存录音文件
saveAudioIndex: 0,
//录音文件保存路径,为空则默认为项目私有目录
audioPath: "/storage/emulated/0/levenBdSpeech/1234.pcm",
//开启代码中音频回调事件索引
acceptAudioDataIndex: 0,
//禁用标点索引
disablePunctuationIndex: 0,
//提示音
tipsSoundIndex: 0,
//开启代码中音量回调事件
acceptAudioVolumeIndex: 0,
//日志
logs: []
}
},
mounted() {
this.$nextTick(() => {
//初始化后注册监听
this.initSdk();
})
},
onUnload() {
//页面卸载
this.release();
},
methods: {
toggle() {
if (this.isStart) {
this.stop()
} else {
this.start()
}
},
showMessage(message) {
uni.showToast({
title: message,
icon: "none"
})
},
initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res) => {
if (res.code == 0) {
this.addLog("初始化成功")
//注册监听
this.registerListener();
} else {
this.addLog(res.message)
}
}
})
},
start() {
let sendParams = this.settingParams;
if (this.saveAudioIndex == 1) {
// 目前必须开启此回掉才嫩保存音频
sendParams["accept-audio-data"] = true;
sendParams["outfile"] = this.audioPath;
}
if (this.tipsSoundIndex == 1) {
//请将声音文件放到到raw下面,传递时不需要带扩展名只传入文件名即可
sendParams['sound_start'] = "bdspeech_recognition_start";
sendParams['sound_end'] = "bdspeech_speech_end";
sendParams['sound_success'] = "bdspeech_recognition_success";
sendParams['sound_error'] = "bdspeech_recognition_error";
sendParams['sound_cancel'] = "bdspeech_recognition_cancel";
}
module.send({
params: {
//命令
cmd: SpeechConstant.ASR_START,
//执行参数
params: sendParams
},
complete: (res) => {
if (res.code == 0) {
this.showMessage("发送成功")
} else {
this.showMessage(res.message)
}
}
})
},
stop() {
module.send({
params: {
cmd: SpeechConstant.ASR_STOP,
},
complete: (res) => {
console.log(res)
}
})
},
registerListener() {
module.registerListener({
complete: (res) => {
let data = res.data;
if (data.type == "onRegisterSuccess") {
//注册监听成功
this.addLog("注册监听成功")
} else if (data.type == "onEvent") {
//识别回调事件
let name = data.name;
let params = data.params || "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
this.addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
this.addLog("检测到用户的已经开始说话")
this.isStart = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
this.addLog("检测到用户的已经停止说话")
this.isStart = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
this.addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
this.addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_LONG_SPEECH:
//长语音识别结束
this.addLog("长语音识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_VOLUME:
//音量的回调
this.addLog("音量的回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_AUDIO:
//语音的二进制数据,dataValue pcm格式,16bits 16000采样率
let dataValue = data.data || [];
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
this.addLog("引擎完成整个识别,空闲中")
break
case SpeechConstant.CALLBACK_EVENT_ASR_LOADED:
//离线命令词资源加载成功
this.addLog("离线命令词资源加载成功")
break
case SpeechConstant.CALLBACK_EVENT_ASR_UNLOADED:
//离线命令词资源释放成功
this.addLog("离线命令词资源释放成功")
break
}
}
}
})
},
addLog(message) {
this.logs.push(message)
},
release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res) => {
console.log(res)
}
})
//取消监听
module.unRegisterListener({
complete: (res) => {
console.log(res)
}
})
//释放资源
module.release({
complete: (res) => {
console.log(res)
}
})
},
changeSaveAudio(event) {
if (event.detail.value) {
this.saveAudioIndex = 1
} else {
this.saveAudioIndex = 0;
}
},
changeTipsSound(event) {
if (event.detail.value) {
this.tipsSoundIndex = 1
} else {
this.tipsSoundIndex = 0;
}
},
changeLongSpeech(event) {
this.settingParams['enable.long.speech'] = event.detail.value
},
changeAcceptAudioData(event) {
this.settingParams['accept-audio-data'] = event.detail.value
},
changeDisablePunctuation(event) {
this.settingParams['disable-punctuation'] = event.detail.value
},
changeAcceptAudioVolume(event) {
this.settingParams['accept-audio-volume'] = event.detail.value
}
}
}
</script>
<style>
</style>vue
<template>
<view>
<uni-card title="离线命令词识别(含长语音)">
<view>根据bsg文件里预定义的固定语法进行离线命令词识别:</view>
<view>SDK没有以下功能:</view>
<view>1.没有任意词离线识别。</view>
<view>2.没有纯离线,第一次使用必须联网。</view>
<view>3.离线效果远差于在线的。</view>
<view>离线命令词测试方法:</view>
<view>1. 首次使用,联网任意识别一句话。这一步可以测试之前的“在线识别”界面。</view>
<view>2. 断网, 大声说“打电话给妈妈”。遇见10012 Offline engine recognize fail ,表示您说的不够清晰或者语速过快。</view>
<view>集成注意事项:</view>
<view>1. demo中测试的“打电话给妈妈”, 其中 ”打电话给name”是bsg文件中定义的,"妈妈"是使用SLOT_DATA参数,覆盖bsg文件name词条的定义。</view>
<view>2. demo的bsg文件是放在core的模块里的assets目录下。需要自定义bsg文件,可以在http://yuyin.baidu.com/asr 下载</view>
<view>3. 首次联网SDK会自动下载授权文件。自动下载的前提是您填写的appId,appKey,secretKey及包名,同网页上填写的一致</view>
</uni-card>
<uni-card title="设置">
<uni-section title="VAD时长设置">
<uni-data-checkbox v-model="settingParams['vad.endpoint-timeout']"
:localdata="vadEndpointTimeoutItems"></uni-data-checkbox>
</uni-section>
<uni-section title="VAD是否开启">
<uni-data-checkbox v-model="settingParams.vad" :localdata="vadItems"></uni-data-checkbox>
</uni-section>
<uni-section title="外部音频">
<uni-data-checkbox v-model="settingParams.infile" :localdata="infileItems"></uni-data-checkbox>
</uni-section>
<uni-section title="保存录音">
<radio-group @change="changeSaveAudio">
<radio :value="false" style="transform:scale(0.7)" :checked="saveAudioIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="saveAudioIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="开启代码中音频回调事件" sub-title="不需要音频二进制数据的回调,请勿开启,否则影响性能">
<radio-group @change="changeAcceptAudioData">
<radio :value="false" style="transform:scale(0.7)" :checked="acceptAudioDataIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="acceptAudioDataIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="提示音">
<radio-group @change="changeTipsSound">
<radio :value="false" style="transform:scale(0.7)" :checked="tipsSoundIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="tipsSoundIndex == 1"></radio>是
</radio-group>
</uni-section>
<uni-section title="开启代码中音量回调事件" sub-title="是否需要音频的音量回调。正常使用请勿开启">
<radio-group @change="changeAcceptAudioVolume">
<radio :value="false" style="transform:scale(0.7)" :checked="acceptAudioVolumeIndex == 0"></radio>否
<radio :value="true" style="transform:scale(0.7)" :checked="acceptAudioVolumeIndex == 1"></radio>是
</radio-group>
</uni-section>
</uni-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<uni-card title="日志">
<view v-for="(item, index) in logs" :key="index">{{item}}</view>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/SpeechConstant.js"
import {
KeyUtils
} from "@/utils/KeyUtils.js"
export default {
data() {
return {
isStart: false,
//设置参数
settingParams: {
//离线解析
decoder: 2,
//长语音时长设置
"vad.endpoint-timeout": "",
//vad是否开启
vad: "",
//外部音频
infile: "",
//开启代码中音频回调事件
"accept-audio-data": false,
//开启代码中音量回调事件
"accept-audio-volume": false
},
//平台id列表
vadEndpointTimeoutItems: [{
"value": "",
"text": "默认"
}, {
"value": 0,
"text": "开启长语音(离线不支持)。建议pid选择15372"
}, {
"value": 800,
"text": "800毫秒,静音800ms后断句,适用于输入短语"
}, {
"value": 2000,
"text": "2000毫秒,静音2000ms后断句,适用于输入长句"
}, {
"value": 2230,
"text": "2230, 毫秒,请修改代码中的VAD_ENDPOINT_TIMEOUT,自定义时长(建议800ms-3000ms之间)"
}],
//vad是否开启配置
vadItems: [{
"value": "",
"text": "不设置"
}, {
"value": "dnn",
"text": "默认,推荐模型"
}, {
"value": "touch",
"text": "关闭静音断句功能。用戶手动停止录音"
}],
//外部音频列表
infileItems: [{
"value": "",
"text": "不设置"
}, {
"value": "assets:///com/baidu/android/voicedemo/16k_test.pcm",
"text": "16k采样的测试音频"
}, {
"value": "assets:///com/baidu/android/voicedemo/offline_input.pcm",
"text": "测试离线命令词"
}],
//是否保存录音文件
saveAudioIndex: 0,
//录音文件保存路径,为空则默认为项目私有目录
audioPath: "/storage/emulated/0/levenBdSpeech/1234.pcm",
//开启代码中音频回调事件索引
acceptAudioDataIndex: 0,
//提示音
tipsSoundIndex: 0,
//开启代码中音量回调事件
acceptAudioVolumeIndex: 0,
//日志
logs: []
}
},
mounted() {
this.$nextTick(() => {
//初始化
//初始化后注册监听
this.initSdk();
})
},
onUnload() {
//页面卸载
this.release();
},
methods: {
toggle() {
if (this.isStart) {
this.stop()
} else {
this.start()
}
},
showMessage(message) {
uni.showToast({
title: message,
icon: "none"
})
},
initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res) => {
if (res.code == 0) {
this.addLog("初始化成功")
//注册监听
this.registerListener();
//加载离线命令词,如果要在这里加载离线命令词需要使用代码同步,保证在registerListener之后加载,这样才会有registerListener的命令词加载状态的回调
// this.loadOfflineEngine()
} else {
this.addLog(res.message)
}
}
})
},
start() {
let sendParams = this.settingParams;
if (this.saveAudioIndex == 1) {
// 目前必须开启此回掉才嫩保存音频
sendParams["accept-audio-data"] = true;
sendParams["outfile"] = this.audioPath;
}
if (this.tipsSoundIndex == 1) {
//请将声音文件放到到raw下面,传递时不需要带扩展名只传入文件名即可
sendParams['sound_start'] = "bdspeech_recognition_start";
sendParams['sound_end'] = "bdspeech_speech_end";
sendParams['sound_success'] = "bdspeech_recognition_success";
sendParams['sound_error'] = "bdspeech_recognition_error";
sendParams['sound_cancel'] = "bdspeech_recognition_cancel";
}
module.send({
params: {
//命令
cmd: SpeechConstant.ASR_START,
//执行参数
params: sendParams
},
complete: (res) => {
if (res.code == 0) {
this.showMessage("发送成功")
} else {
this.showMessage(res.message)
}
}
})
},
stop() {
module.send({
params: {
cmd: SpeechConstant.ASR_STOP,
},
complete: (res) => {
console.log(res)
}
})
},
registerListener() {
module.registerListener({
complete: (res) => {
let data = res.data;
if (data.type == "onRegisterSuccess") {
//注册监听成功
this.addLog("注册监听成功")
//这里可以加载离线命令词
this.loadOfflineEngine();
} else if (data.type == "onEvent") {
//识别回调事件
let name = data.name;
let params = data.params || "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
this.addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
this.addLog("检测到用户的已经开始说话")
this.isStart = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
this.addLog("检测到用户的已经停止说话")
this.isStart = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
this.addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
this.addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_LONG_SPEECH:
//长语音识别结束
this.addLog("长语音识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_VOLUME:
//音量的回调
this.addLog("音量的回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_AUDIO:
//语音的二进制数据,dataValue pcm格式,16bits 16000采样率
let dataValue = data.data || [];
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
this.addLog("引擎完成整个识别,空闲中")
break
case SpeechConstant.CALLBACK_EVENT_ASR_LOADED:
//离线命令词资源加载成功
this.addLog("离线命令词资源加载成功")
break
case SpeechConstant.CALLBACK_EVENT_ASR_UNLOADED:
//离线命令词资源释放成功
this.addLog("离线命令词资源释放成功")
break
}
}
}
})
},
loadOfflineEngine() {
module.send({
params: {
//执行的命令
cmd: SpeechConstant.ASR_KWS_LOAD_ENGINE,
params: {
decoder: 2,
grammar: "assets:///baidu_speech_grammar.bsg",
"slot-data": {
name: ['妈妈', '李四'],
appname: ['手百', '度秘']
}
}
},
complete: (res) => {
console.log(res);
}
})
},
addLog(message) {
this.logs.push(message)
},
release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res) => {
console.log(res)
}
})
//卸载离线资源
module.send({
params: {
cmd: SpeechConstant.ASR_KWS_UNLOAD_ENGINE
},
complete: (res) => {
console.log(res)
}
})
//取消监听
module.unRegisterListener({
complete: (res) => {
console.log(res)
}
})
//释放资源
module.release({
complete: (res) => {
console.log(res)
}
})
},
changeSaveAudio(event) {
if (event.detail.value) {
this.saveAudioIndex = 1
} else {
this.saveAudioIndex = 0;
}
},
changeTipsSound(event) {
if (event.detail.value) {
this.tipsSoundIndex = 1
} else {
this.tipsSoundIndex = 0;
}
},
changeLongSpeech(event) {
this.settingParams['enable.long.speech'] = event.detail.value
},
changeAcceptAudioData(event) {
this.settingParams['accept-audio-data'] = event.detail.value
},
changeDisablePunctuation(event) {
this.settingParams['disable-punctuation'] = event.detail.value
},
changeAcceptAudioVolume(event) {
this.settingParams['accept-audio-volume'] = event.detail.value
}
}
}
</script>
<style>
</style>vue
<template>
<view>
<uni-card title="功能说明">
<view>唤醒词功能即SDK识别唤醒词,或者认为是SDK识别出用户一大段话中的“关键词”,与Android系统自身的锁屏唤醒无关</view>
<view>测试方法:</view>
<view>1.第一次使用需要联网使用</view>
<view>2. 请说“小度你好”或者 “百度一下”</view>
<view>唤醒词是本地功能,需要获取正式授权文件(与离线命令词的正式授权文件是同一个)。 第一次联网使用唤醒词功能自动获取正式授权文件。之后可以断网测试。</view>
<view>集成指南:</view>
<view>1.demo的wakeUp.bin文件是放在core的模块里的assets目录下。需要自定义bsg文件,可以在http://yuyin.baidu.com/asr 下载</view>
<view>2.首次联网SDK会自动下载授权文件。自动下载的前提是您填写的appId,appKey,secretKey及包名,同网页上填写的一致。</view>
</uni-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<uni-card title="日志">
<view v-for="(item, index) in logs" :key="index">{{item}}</view>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/SpeechConstant.js"
import {
KeyUtils
} from "@/utils/KeyUtils.js"
export default {
data() {
return {
isStart: false,
//日志
logs: []
}
},
mounted() {
this.$nextTick(() => {
//初始化后注册监听
this.initSdk();
})
},
onUnload() {
//页面卸载
this.release();
},
methods: {
toggle() {
if (this.isStart) {
this.stop()
} else {
this.start()
}
},
showMessage(message) {
uni.showToast({
title: message,
icon: "none"
})
},
initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY,
type: "wp"
},
complete: (res) => {
if (res.code == 0) {
this.addLog("初始化成功")
//注册监听
this.registerListener();
} else {
this.addLog(res.message)
}
}
})
},
start() {
module.send({
params: {
//命令
cmd: SpeechConstant.WAKEUP_START,
//执行参数
params: {
'kws-file': "assets:///WakeUp.bin",
// 'accept-audio-data':true,
// 'infile':"assets:///com/baidu/android/voicedemo/wakeup.pcm"
}
},
complete: (res) => {
if (res.code == 0) {
this.showMessage("发送成功")
this.isStart = true;
} else {
this.showMessage(res.message)
}
}
})
},
stop() {
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP,
},
complete: (res) => {
console.log(res)
this.isStart = false
}
})
},
registerListener() {
module.registerListener({
complete: (res) => {
let data = res.data;
if (data.type == "onRegisterSuccess") {
//注册监听成功
this.addLog("注册监听成功")
} else if (data.type == "onEvent") {
//识别回调事件
let name = data.name;
let params = data.params || "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_WAKEUP_SUCCESS:
//识别唤醒词成功
this.addLog("识别唤醒词成功:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_ERROR:
//识别唤醒词报错
this.addLog("识别唤醒词报错:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_STOPED:
//关闭唤醒词
this.addLog("关闭唤醒词")
this.isStart = false;
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_AUDIO:
//音频回调
this.addLog("音频回调:" + params)
break
}
}
}
})
},
addLog(message) {
this.logs.push(message)
},
release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP
},
complete: (res) => {
console.log(res)
}
})
//取消监听
module.unRegisterListener({
complete: (res) => {
console.log(res)
}
})
},
changeSaveAudio(event) {
if (event.detail.value) {
this.saveAudioIndex = 1
} else {
this.saveAudioIndex = 0;
}
},
changeTipsSound(event) {
if (event.detail.value) {
this.tipsSoundIndex = 1
} else {
this.tipsSoundIndex = 0;
}
},
changeLongSpeech(event) {
this.settingParams['enable.long.speech'] = event.detail.value
},
changeAcceptAudioData(event) {
this.settingParams['accept-audio-data'] = event.detail.value
},
changeDisablePunctuation(event) {
this.settingParams['disable-punctuation'] = event.detail.value
},
changeAcceptAudioVolume(event) {
this.settingParams['accept-audio-volume'] = event.detail.value
}
}
}
</script>
<style>
</style>vue
<template>
<view>
<uni-card title="功能说明">
<view>请先单独测试唤醒词功能和在线识别功能</view>
<view>唤醒后识别,即唤醒词识别成功后,立即在线识别。</view>
<view>根据用户说唤醒词之后有无停顿。共2种实现方式:</view>
<view>1. 您的场景需要唤醒词之后无停顿,用户一下子说出。那么可以使用录音回溯功能:连同唤醒词一起整句识别。</view>
<view>2. 您的场景为唤醒词之后UI引导有短暂停顿。那么不做回溯,识别出唤醒词停顿后的句子。</view>
<view>两个方案的优劣 :</view>
<view>方案1 中,整句回溯时间是经验值1.5s。 此外由于整句识别,可能唤醒词会识别成别的结果。</view>
<view>方案2中, 如果用户不停顿,将可能造成首字或者首词的识别错误。</view>
<view>测试方法:</view>
<view>测试请说:百度一下【此处可以停顿】,今天天气真好</view>
<view>集成指南:</view>
<view>代码中通过backTrackInMs成员变量可以选择测试方案1还是方案2。</view>
</uni-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<uni-card title="日志">
<view v-for="(item, index) in logs" :key="index">{{item}}</view>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/SpeechConstant.js"
import {
KeyUtils
} from "@/utils/KeyUtils.js"
import {
compile
} from "vue"
export default {
data() {
return {
isStart: false,
/**
* 0: 方案1, backTrackInMs > 0,唤醒词说完后,直接接句子,中间没有停顿。
* 开启回溯,连同唤醒词一起整句识别。推荐4个字 1500ms
* backTrackInMs 最大 15000,即15s
*
* >0 : 方案2:backTrackInMs = 0,唤醒词说完后,中间有停顿。
* 不开启回溯。唤醒词识别回调后,正常开启识别。
*
*/
backTrackInMs: 1500,
//日志
logs: []
}
},
mounted() {
this.$nextTick(() => {
//初始化后注册监听
this.initSdk();
})
},
onUnload() {
//页面卸载
this.release();
},
methods: {
toggle() {
if (this.isStart) {
this.stop()
} else {
this.start()
}
},
showMessage(message) {
uni.showToast({
title: message,
icon: "none"
})
},
initSdk() {
//先初始化命令词
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY,
type: "wp"
},
complete: (res) => {
if (res.code == 0) {
this.addLog("初始化命令词成功")
//初始化识别
this.initRecog()
} else {
this.addLog(res.message)
}
}
})
},
initRecog() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res) => {
if (res.code == 0) {
this.addLog("初始化识别成功")
//注册监听
this.registerListener();
} else {
this.addLog(res.message)
}
}
})
},
start() {
module.send({
params: {
//命令
cmd: SpeechConstant.WAKEUP_START,
//执行参数
params: {
'kws-file': "assets:///WakeUp.bin",
// 'accept-audio-data':true,
// 'infile':"assets:///com/baidu/android/voicedemo/wakeup.pcm"
}
},
complete: (res) => {
if (res.code == 0) {
this.showMessage("发送成功")
this.isStart = true;
} else {
this.showMessage(res.message)
}
}
})
},
stop() {
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP,
},
complete: (res) => {
console.log(res)
this.isStart = false
}
})
},
recog() {
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res) => {
let sendParams = {
'accept-audio-volume': false,
'vad': SpeechConstant.VAD_DNN
}
if (this.backTrackInMs > 0) {
let timeTamp = Date.parse(new Date());
// 方案1 唤醒词说完后,直接接句子,中间没有停顿。开启回溯,连同唤醒词一起整句识别。
// timeTamp - backTrackInMs , 表示识别从backTrackInMs毫秒前开始
sendParams['audio.mills'] = timeTamp - this.backTrackInMs;
}
module.send({
params: {
cmd: SpeechConstant.ASR_START,
params: sendParams
},
complete: (resStart) => {
console.log(resStart)
}
})
}
})
},
registerListener() {
module.registerListener({
complete: (res) => {
let data = res.data;
if (data.type == "onRegisterSuccess") {
//注册监听成功
this.addLog("注册监听成功")
} else if (data.type == "onEvent") {
//识别回调事件
let name = data.name;
let params = data.params || "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_WAKEUP_SUCCESS:
//识别唤醒词成功
this.addLog("识别唤醒词成功:" + params)
// 此处 开始正常识别流程
this.recog();
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_ERROR:
//识别唤醒词报错
this.addLog("识别唤醒词报错:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_STOPED:
//关闭唤醒词
this.addLog("关闭唤醒词")
this.isStart = false;
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_AUDIO:
//音频回调
this.addLog("音频回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
this.addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
this.addLog("检测到用户的已经开始说话")
this.isStart = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
this.addLog("检测到用户的已经停止说话")
this.isStart = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
this.addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
this.addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
this.addLog("引擎完成整个识别,空闲中")
break
}
}
}
})
},
addLog(message) {
this.logs.push(message)
},
release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP
},
complete: (res) => {
console.log(res)
}
})
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_STOP
},
complete: (res) => {
console.log(res)
}
})
//取消监听
module.unRegisterListener({
complete: (res) => {
console.log(res)
}
})
},
changeSaveAudio(event) {
if (event.detail.value) {
this.saveAudioIndex = 1
} else {
this.saveAudioIndex = 0;
}
},
changeTipsSound(event) {
if (event.detail.value) {
this.tipsSoundIndex = 1
} else {
this.tipsSoundIndex = 0;
}
},
changeLongSpeech(event) {
this.settingParams['enable.long.speech'] = event.detail.value
},
changeAcceptAudioData(event) {
this.settingParams['accept-audio-data'] = event.detail.value
},
changeDisablePunctuation(event) {
this.settingParams['disable-punctuation'] = event.detail.value
},
changeAcceptAudioVolume(event) {
this.settingParams['accept-audio-volume'] = event.detail.value
}
}
}
</script>
<style>
</style>uniapp x
vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<rice-cell-group border>
<rice-cell title="在线识别" arrow clickable @click="toPage('onlineRecog')"></rice-cell>
<rice-cell title="离线命令词" arrow clickable @click="toPage('offlineRecog')"></rice-cell>
<rice-cell title="唤醒词" arrow clickable @click="toPage('wakeup')"></rice-cell>
<rice-cell title="唤醒后识别" arrow clickable @click="toPage('wakeUpRecog')"></rice-cell>
</rice-cell-group>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import { LevenResult, LevenOptions } from "@/uni_modules/leven-uts-bdSpeech"
function toPage(type : string) {
switch (type) {
case "onlineRecog":
uni.navigateTo({
url: "/pages/bdSpeech/onlineRecog"
})
break
case "offlineRecog":
uni.navigateTo({
url: "/pages/bdSpeech/offlineRecog"
})
break
case "wakeup":
uni.navigateTo({
url: "/pages/bdSpeech/wakeup"
})
break
case "wakeUpRecog":
uni.navigateTo({
url: "/pages/bdSpeech/wakeUpRecog"
})
break
}
}
//显示消息
function showMessage(message : string) {
uni.showToast({
title: message,
icon: "none"
})
}
//跳转到所有文件访问权限页面
function toAllFilesPermissionPage() {
module.toAllFilesPermissionPage({
complete: (res : LevenResult) => {
if (res.code == 0) {
let data = res.data;
let status : boolean = data.getBoolean("status")!
if (!status) {
showMessage("所有文件访问权限未打开")
} else {
showMessage("权限授权完成,欢迎使用")
}
} else {
showMessage("跳转到所有文件访问权限页面失败")
}
}
} as LevenOptions)
}
//检测是否有所有文件访问权限
function checkAllFilesPermission() {
module.checkAllFilesPermission({
complete: (res : LevenResult) => {
if (res.code == 0) {
let data = res.data;
let status : boolean = data.getBoolean("status")!
if (!status) {
toAllFilesPermissionPage();
} else {
showMessage("权限授权完成,欢迎使用")
}
} else {
showMessage("查询文件权限失败")
}
}
} as LevenOptions)
}
//申请权限
function requestPermissions() {
module.requestPermissions({
params: {
permissions: [
'android.permission.READ_EXTERNAL_STORAGE',
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.RECORD_AUDIO'
]
},
complete: (res : LevenResult) => {
console.log(res)
if (res.code == 0) {
checkAllFilesPermission()
} else {
showMessage("权限申请未通过")
}
}
} as LevenOptions)
}
//页面加载
onMounted(() => {
//申请权限
requestPermissions();
})
</script>
<style>
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<lux-card title="在线普通识别功能(含长语音)">
<view><text>普通识别测试方法:</text></view>
<view><text>请保持设备联网,对着麦克风说出日常用语即可。</text></view>
<view><text>普通录音限制60s。使用长语音无此限制。</text></view>
</lux-card>
<lux-card title="设置">
<lux-section text="PID,语种">
<rice-radio-group v-model="language" direction="row">
<rice-radio value="" label="默认" :customStyle="radioStyle"></rice-radio>
<rice-radio value="cmn-Hans-CN" label="普通话" :customStyle="radioStyle"></rice-radio>
<rice-radio value="en-GB" label="英语" :customStyle="radioStyle"></rice-radio>
<rice-radio value="yue-Hans-CN" label="粤语" :customStyle="radioStyle"></rice-radio>
<rice-radio value="sichuan-Hans-CN" label="四川话" :customStyle="radioStyle"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="LMID,自训练平台ID,请选PID=8002生效">
<rice-radio-group v-model="lm_id">
<rice-radio value="" label="默认" :customStyle="radioStyle"></rice-radio>
<rice-radio value="1068" label="自训练平台上线的id,和账号维度绑定"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="长语音" subText="长语音参数,优先级高于vad_endpoint_timeout">
<rice-radio-group v-model="enableLongSpeech" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="VAD时长设置">
<rice-radio-group v-model="vadEndpointTimeout">
<rice-radio value="" label="默认"></rice-radio>
<rice-radio :value="0" label="开启长语音(离线不支持)。建议pid选择15372" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="800" label="800毫秒,静音800ms后断句,适用于输入短语" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="2000" label="2000毫秒,静音2000ms后断句,适用于输入长句" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="2230" label="2230, 毫秒,请修改代码中的VAD_ENDPOINT_TIMEOUT,自定义时长(建议800ms-3000ms之间)"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="VAD是否开启">
<rice-radio-group v-model="vad">
<rice-radio value="" label="不设置" :customStyle="radioStyle"></rice-radio>
<rice-radio value="dnn" label="默认,推荐模" :customStyle="radioStyle"></rice-radio>
<rice-radio value="touch" label="关闭静音断句功能。用戶手动停止录音"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="外部音频">
<rice-radio-group v-model="infile">
<rice-radio value="" label="不设置" :customStyle="radioStyle"></rice-radio>
<rice-radio value="assets:///com/baidu/android/voicedemo/16k_test.pcm" label="16k采样的测试音频"
:customStyle="radioStyle"></rice-radio>
<rice-radio value="assets:///com/baidu/android/voicedemo/offline_input.pcm" label="测试离线命令词"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="保存录音">
<rice-radio-group v-model="saveAudioData" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="开启代码中音频回调事件" subText="不需要音频二进制数据的回调,请勿开启,否则影响性能">
<rice-radio-group v-model="acceptAudioData" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="禁用标点" subText="在选择输入法模型的前提下生效">
<rice-radio-group v-model="disablePunctuation" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="提示音">
<rice-radio-group v-model="tipsSound" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="开启代码中音量回调事件" subText="是否需要音频的音量回调。正常使用请勿开启">
<rice-radio-group v-model="acceptAudioVolume" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
</lux-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<lux-card title="日志">
<view v-for="(item, index) in logs" :key="index"><text>{{item}}</text></view>
</lux-card>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import { LevenResult, LevenOptions } from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/bdSpeech/SpeechConstant.uts"
import {
KeyUtils
} from "@/utils/bdSpeech/KeyUtils.uts"
//radio样式
const radioStyle = {
marginBottom: '8px'
}
//设置参数
//语种
const language = ref("")
//自训练平台ID
const lm_id = ref("")
//长语音
const enableLongSpeech = ref(false)
//VAD时长
const vadEndpointTimeout = ref<number | string>("")
//vad是否开启
const vad = ref("")
//外部音频
const infile = ref("")
//保存录音
const saveAudioData = ref(false)
//开启代码中音频回调事件
const acceptAudioData = ref(false)
//禁用标点
const disablePunctuation = ref(false)
//提示音
const tipsSound = ref(false)
//开启代码中音量回调事件
const acceptAudioVolume = ref(false)
//是否开始识别
const isStart = ref(false)
//日志
const logs = ref<string[]>([])
function addLog(message : string) {
logs.value.push(message)
}
function showMessage(message : string) {
uni.showToast({
title: message,
icon: "none"
})
}
function start() {
let sendParams = {
//语种
language: language.value,
//自训练平台ID
lm_id: lm_id.value,
//长语音
"enable.long.speech": enableLongSpeech.value,
//长语音时长设置
"vad.endpoint-timeout": vadEndpointTimeout.value,
//vad是否开启
vad: vad.value,
//外部音频
infile: infile.value,
//开启代码中音频回调事件
"accept-audio-data": acceptAudioData.value,
//禁用标点
"disable-punctuation": disablePunctuation.value,
//开启代码中音量回调事件
"accept-audio-volume": acceptAudioVolume.value
};
if (saveAudioData.value) {
// 目前必须开启此回掉才嫩保存音频
sendParams["accept-audio-data"] = true;
sendParams["outfile"] = "/storage/emulated/0/levenBdSpeech/1234.pcm";
}
if (tipsSound.value) {
//请将声音文件放到到raw下面,传递时不需要带扩展名只传入文件名即可
sendParams['sound_start'] = "bdspeech_recognition_start";
sendParams['sound_end'] = "bdspeech_speech_end";
sendParams['sound_success'] = "bdspeech_recognition_success";
sendParams['sound_error'] = "bdspeech_recognition_error";
sendParams['sound_cancel'] = "bdspeech_recognition_cancel";
}
module.send({
params: {
//命令
cmd: SpeechConstant.ASR_START,
//执行参数
params: sendParams
},
complete: (res : LevenResult) => {
if (res.code == 0) {
showMessage("发送成功")
} else {
showMessage(res.message)
}
}
} as LevenOptions)
}
function stop() {
module.send({
params: {
cmd: SpeechConstant.ASR_STOP,
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//取消监听
module.unRegisterListener({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//释放资源
module.release({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function registerListener() {
module.registerListener({
complete: (res : LevenResult) => {
let data = res.data;
let type = data.getString("type")
if (type == "onRegisterSuccess") {
//注册监听成功
addLog("注册监听成功")
} else if (type == "onEvent") {
//识别回调事件
let name = data.getString("name");
let params = data.getString("params") ?? "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
addLog("检测到用户的已经开始说话")
isStart.value = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
addLog("检测到用户的已经停止说话")
isStart.value = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_LONG_SPEECH:
//长语音识别结束
addLog("长语音识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_VOLUME:
//音量的回调
addLog("音量的回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_AUDIO:
//语音的二进制数据,dataValue pcm格式,16bits 16000采样率
// let dataValue = data.getArray("data") || [];
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
addLog("引擎完成整个识别,空闲中")
break
case SpeechConstant.CALLBACK_EVENT_ASR_LOADED:
//离线命令词资源加载成功
addLog("离线命令词资源加载成功")
break
case SpeechConstant.CALLBACK_EVENT_ASR_UNLOADED:
//离线命令词资源释放成功
addLog("离线命令词资源释放成功")
break
}
}
}
} as LevenOptions)
}
function initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res : LevenResult) => {
if (res.code == 0) {
addLog("初始化成功")
//注册监听
registerListener();
} else {
addLog(res.message)
}
}
} as LevenOptions)
}
function toggle() {
if (isStart.value) {
stop()
} else {
start()
}
}
onMounted(() => {
nextTick(() => {
//初始化后注册监听
initSdk()
})
})
onUnload(() => {
//页面卸载
release();
})
</script>
<style>
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<lux-card title="离线命令词识别(含长语音)">
<view><text>根据bsg文件里预定义的固定语法进行离线命令词识别:</text></view>
<view><text>SDK没有以下功能:</text></view>
<view><text>1.没有任意词离线识别。</text></view>
<view><text>2.没有纯离线,第一次使用必须联网。</text></view>
<view><text>3.离线效果远差于在线的。</text></view>
<view><text>离线命令词测试方法:</text></view>
<view><text>1. 首次使用,联网任意识别一句话。这一步可以测试之前的“在线识别”界面。</text></view>
<view><text>2. 断网, 大声说“打电话给妈妈”。遇见10012 Offline engine recognize fail ,表示您说的不够清晰或者语速过快。</text></view>
<view><text>集成注意事项:</text></view>
<view><text>1. demo中测试的“打电话给妈妈”, 其中 ”打电话给name”是bsg文件中定义的,"妈妈"是使用SLOT_DATA参数,覆盖bsg文件name词条的定义。</text></view>
<view><text>2. demo的bsg文件是放在core的模块里的assets目录下。需要自定义bsg文件,可以在http://yuyin.baidu.com/asr 下载</text></view>
<view><text>3. 首次联网SDK会自动下载授权文件。自动下载的前提是您填写的appId,appKey,secretKey及包名,同网页上填写的一致</text></view>
</lux-card>
<lux-card title="设置">
<lux-section text="VAD时长设置">
<rice-radio-group v-model="vadEndpointTimeout">
<rice-radio value="" label="默认"></rice-radio>
<rice-radio :value="0" label="开启长语音(离线不支持)。建议pid选择15372" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="800" label="800毫秒,静音800ms后断句,适用于输入短语" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="2000" label="2000毫秒,静音2000ms后断句,适用于输入长句" :customStyle="radioStyle"></rice-radio>
<rice-radio :value="2230" label="2230, 毫秒,请修改代码中的VAD_ENDPOINT_TIMEOUT,自定义时长(建议800ms-3000ms之间)"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="VAD是否开启">
<rice-radio-group v-model="vad">
<rice-radio value="" label="不设置" :customStyle="radioStyle"></rice-radio>
<rice-radio value="dnn" label="默认,推荐模" :customStyle="radioStyle"></rice-radio>
<rice-radio value="touch" label="关闭静音断句功能。用戶手动停止录音"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="外部音频">
<rice-radio-group v-model="infile">
<rice-radio value="" label="不设置" :customStyle="radioStyle"></rice-radio>
<rice-radio value="assets:///com/baidu/android/voicedemo/16k_test.pcm" label="16k采样的测试音频"
:customStyle="radioStyle"></rice-radio>
<rice-radio value="assets:///com/baidu/android/voicedemo/offline_input.pcm" label="测试离线命令词"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="保存录音">
<rice-radio-group v-model="saveAudioData" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="开启代码中音频回调事件" subText="不需要音频二进制数据的回调,请勿开启,否则影响性能">
<rice-radio-group v-model="acceptAudioData" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="提示音">
<rice-radio-group v-model="tipsSound" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
<lux-section text="开启代码中音量回调事件" subText="是否需要音频的音量回调。正常使用请勿开启">
<rice-radio-group v-model="acceptAudioVolume" direction="row">
<rice-radio :value="false" label="否"></rice-radio>
<rice-radio :value="true" label="是"></rice-radio>
</rice-radio-group>
</lux-section>
</lux-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<lux-card title="日志">
<view v-for="(item, index) in logs" :key="index"><text>{{item}}</text></view>
</lux-card>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import { LevenResult, LevenOptions } from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/bdSpeech/SpeechConstant.uts"
import {
KeyUtils
} from "@/utils/bdSpeech/KeyUtils.uts"
//radio样式
const radioStyle = {
marginBottom: '8px'
}
//设置参数
//VAD时长
const vadEndpointTimeout = ref<number | string>("")
//vad是否开启
const vad = ref("")
//外部音频
const infile = ref("")
//保存录音
const saveAudioData = ref(false)
//开启代码中音频回调事件
const acceptAudioData = ref(false)
//提示音
const tipsSound = ref(false)
//开启代码中音量回调事件
const acceptAudioVolume = ref(false)
//是否开始识别
const isStart = ref(false)
//日志
const logs = ref<string[]>([])
function addLog(message : string) {
logs.value.push(message)
}
function showMessage(message : string) {
uni.showToast({
title: message,
icon: "none"
})
}
function start() {
let sendParams = {
//长语音时长设置
"vad.endpoint-timeout": vadEndpointTimeout.value,
//vad是否开启
vad: vad.value,
//外部音频
infile: infile.value,
//开启代码中音频回调事件
"accept-audio-data": acceptAudioData.value,
//开启代码中音量回调事件
"accept-audio-volume": acceptAudioVolume.value
};
if (saveAudioData.value) {
// 目前必须开启此回掉才嫩保存音频
sendParams["accept-audio-data"] = true;
sendParams["outfile"] = "/storage/emulated/0/levenBdSpeech/1234.pcm";
}
if (tipsSound.value) {
//请将声音文件放到到raw下面,传递时不需要带扩展名只传入文件名即可
sendParams['sound_start'] = "bdspeech_recognition_start";
sendParams['sound_end'] = "bdspeech_speech_end";
sendParams['sound_success'] = "bdspeech_recognition_success";
sendParams['sound_error'] = "bdspeech_recognition_error";
sendParams['sound_cancel'] = "bdspeech_recognition_cancel";
}
module.send({
params: {
//命令
cmd: SpeechConstant.ASR_START,
//执行参数
params: sendParams
},
complete: (res : LevenResult) => {
if (res.code == 0) {
showMessage("发送成功")
} else {
showMessage(res.message)
}
}
} as LevenOptions)
}
function stop() {
module.send({
params: {
cmd: SpeechConstant.ASR_STOP,
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//卸载离线资源
module.send({
params: {
cmd: SpeechConstant.ASR_KWS_UNLOAD_ENGINE
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//取消监听
module.unRegisterListener({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//释放资源
module.release({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function loadOfflineEngine() {
module.send({
params: {
//执行的命令
cmd: SpeechConstant.ASR_KWS_LOAD_ENGINE,
params: {
decoder: 2,
grammar: "assets:///baidu_speech_grammar.bsg",
"slot-data": {
name: ['妈妈', '李四'],
appname: ['手百', '度秘']
}
}
},
complete: (res : LevenResult) => {
console.log(res);
}
} as LevenOptions)
}
function registerListener() {
module.registerListener({
complete: (res : LevenResult) => {
let data = res.data;
let type = data.getString("type")
if (type == "onRegisterSuccess") {
//注册监听成功
addLog("注册监听成功")
//这里可以加载离线命令词
loadOfflineEngine();
} else if (type == "onEvent") {
//识别回调事件
let name = data.getString("name");
let params = data.getString("params") ?? "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
addLog("检测到用户的已经开始说话")
isStart.value = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
addLog("检测到用户的已经停止说话")
isStart.value = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_LONG_SPEECH:
//长语音识别结束
addLog("长语音识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_VOLUME:
//音量的回调
addLog("音量的回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_AUDIO:
//语音的二进制数据,dataValue pcm格式,16bits 16000采样率
// let dataValue = data.getArray("data") || [];
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
addLog("引擎完成整个识别,空闲中")
break
case SpeechConstant.CALLBACK_EVENT_ASR_LOADED:
//离线命令词资源加载成功
addLog("离线命令词资源加载成功")
break
case SpeechConstant.CALLBACK_EVENT_ASR_UNLOADED:
//离线命令词资源释放成功
addLog("离线命令词资源释放成功")
break
}
}
}
} as LevenOptions)
}
function initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res : LevenResult) => {
if (res.code == 0) {
addLog("初始化成功")
//加载离线命令词,如果要在这里加载离线命令词需要使用代码同步,保证在registerListener之后加载,这样才会有registerListener的命令词加载状态的回调
// loadOfflineEngine()
//注册监听
registerListener();
} else {
addLog(res.message)
}
}
} as LevenOptions)
}
function toggle() {
if (isStart.value) {
stop()
} else {
start()
}
}
onMounted(() => {
nextTick(() => {
//初始化后注册监听
initSdk()
})
})
onUnload(() => {
//页面卸载
release();
})
</script>
<style>
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<lux-card title="功能说明">
<view><text>唤醒词功能即SDK识别唤醒词,或者认为是SDK识别出用户一大段话中的“关键词”,与Android系统自身的锁屏唤醒无关</text></view>
<view><text>测试方法:</text></view>
<view><text>1.第一次使用需要联网使用</text></view>
<view><text>2. 请说“小度你好”或者 “百度一下”</text></view>
<view><text>唤醒词是本地功能,需要获取正式授权文件(与离线命令词的正式授权文件是同一个)。 第一次联网使用唤醒词功能自动获取正式授权文件。之后可以断网测试。</text></view>
<view><text>集成指南:</text></view>
<view><text>1.demo的wakeUp.bin文件是放在core的模块里的assets目录下。需要自定义bsg文件,可以在http://yuyin.baidu.com/asr 下载</text></view>
<view><text>2.首次联网SDK会自动下载授权文件。自动下载的前提是您填写的appId,appKey,secretKey及包名,同网页上填写的一致。</text></view>
</lux-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<lux-card title="日志">
<view v-for="(item, index) in logs" :key="index"><text>{{item}}</text></view>
</lux-card>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import { LevenResult, LevenOptions } from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/bdSpeech/SpeechConstant.uts"
import {
KeyUtils
} from "@/utils/bdSpeech/KeyUtils.uts"
//是否开始识别
const isStart = ref(false)
//日志
const logs = ref<string[]>([])
function addLog(message : string) {
logs.value.push(message)
}
function showMessage(message : string) {
uni.showToast({
title: message,
icon: "none"
})
}
function start() {
module.send({
params: {
//命令
//命令
cmd: SpeechConstant.WAKEUP_START,
//执行参数
params: {
'kws-file': "assets:///WakeUp.bin",
// 'accept-audio-data':true,
// 'infile':"assets:///com/baidu/android/voicedemo/wakeup.pcm"
}
},
complete: (res : LevenResult) => {
if (res.code == 0) {
showMessage("发送成功")
isStart.value = true
} else {
showMessage(res.message)
}
}
} as LevenOptions)
}
function stop() {
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP,
},
complete: (res : LevenResult) => {
console.log(res)
isStart.value = false
}
} as LevenOptions)
}
function release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//取消监听
module.unRegisterListener({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//释放资源
module.release({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function registerListener() {
module.registerListener({
complete: (res : LevenResult) => {
let data = res.data;
let type = data.getString("type")
if (type == "onRegisterSuccess") {
//注册监听成功
addLog("注册监听成功")
} else if (type == "onEvent") {
//识别回调事件
let name = data.getString("name");
let params = data.getString("params") ?? "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_WAKEUP_SUCCESS:
//识别唤醒词成功
addLog("识别唤醒词成功:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_ERROR:
//识别唤醒词报错
addLog("识别唤醒词报错:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_STOPED:
//关闭唤醒词
addLog("关闭唤醒词")
isStart.value = false;
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_AUDIO:
//音频回调
addLog("音频回调:" + params)
break
}
}
}
} as LevenOptions)
}
function initSdk() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY,
type: "wp"
},
complete: (res : LevenResult) => {
if (res.code == 0) {
addLog("初始化成功")
//注册监听
registerListener();
} else {
addLog(res.message)
}
}
} as LevenOptions)
}
function toggle() {
if (isStart.value) {
stop()
} else {
start()
}
}
onMounted(() => {
nextTick(() => {
//初始化后注册监听
initSdk()
})
})
onUnload(() => {
//页面卸载
release();
})
</script>
<style>
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<lux-card title="功能说明">
<view><text>请先单独测试唤醒词功能和在线识别功能</text></view>
<view><text>唤醒后识别,即唤醒词识别成功后,立即在线识别。</text></view>
<view><text>根据用户说唤醒词之后有无停顿。共2种实现方式:</text></view>
<view><text>1. 您的场景需要唤醒词之后无停顿,用户一下子说出。那么可以使用录音回溯功能:连同唤醒词一起整句识别。</text></view>
<view><text>2. 您的场景为唤醒词之后UI引导有短暂停顿。那么不做回溯,识别出唤醒词停顿后的句子。</text></view>
<view><text>两个方案的优劣 :</text></view>
<view><text>方案1 中,整句回溯时间是经验值1.5s。 此外由于整句识别,可能唤醒词会识别成别的结果。</text></view>
<view><text>方案2中, 如果用户不停顿,将可能造成首字或者首词的识别错误。</text></view>
<view><text>测试方法:</text></view>
<view><text>测试请说:百度一下【此处可以停顿】,今天天气真好</text></view>
<view><text>集成指南:</text></view>
<view><text>代码中通过backTrackInMs成员变量可以选择测试方案1还是方案2。</text></view>
</lux-card>
<button type="primary" @click="toggle">{{isStart ? "停止" : "开始"}}</button>
<lux-card title="日志">
<view v-for="(item, index) in logs" :key="index"><text>{{item}}</text></view>
</lux-card>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import * as module from "@/uni_modules/leven-uts-bdSpeech"
import { LevenResult, LevenOptions } from "@/uni_modules/leven-uts-bdSpeech"
import {
SpeechConstant
} from "@/utils/bdSpeech/SpeechConstant.uts"
import {
KeyUtils
} from "@/utils/bdSpeech/KeyUtils.uts"
import { dateuts } from '@/uni_modules/rice-ui';
//是否开始识别
const isStart = ref(false)
/**
* 0: 方案1, backTrackInMs > 0,唤醒词说完后,直接接句子,中间没有停顿。
* 开启回溯,连同唤醒词一起整句识别。推荐4个字 1500ms
* backTrackInMs 最大 15000,即15s
*
* >0 : 方案2:backTrackInMs = 0,唤醒词说完后,中间有停顿。
* 不开启回溯。唤醒词识别回调后,正常开启识别。
*
*/
const backTrackInMs = ref(1500)
//日志
const logs = ref<string[]>([])
function addLog(message : string) {
logs.value.push(message)
}
function showMessage(message : string) {
uni.showToast({
title: message,
icon: "none"
})
}
function start() {
module.send({
params: {
//命令
//命令
cmd: SpeechConstant.WAKEUP_START,
//执行参数
params: {
'kws-file': "assets:///WakeUp.bin",
// 'accept-audio-data':true,
// 'infile':"assets:///com/baidu/android/voicedemo/wakeup.pcm"
}
},
complete: (res : LevenResult) => {
if (res.code == 0) {
showMessage("发送成功")
isStart.value = true
} else {
showMessage(res.message)
}
}
} as LevenOptions)
}
function stop() {
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP,
},
complete: (res : LevenResult) => {
console.log(res)
isStart.value = false
}
} as LevenOptions)
}
function release() {
//取消识别
module.send({
params: {
cmd: SpeechConstant.WAKEUP_STOP
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//取消识别
module.send({
params: {
cmd: SpeechConstant.ASR_STOP
},
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//取消监听
module.unRegisterListener({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
//释放资源
module.release({
complete: (res : LevenResult) => {
console.log(res)
}
} as LevenOptions)
}
function recog() {
module.send({
params: {
cmd: SpeechConstant.ASR_CANCEL
},
complete: (res : LevenResult) => {
let sendParams = {
'accept-audio-volume': false,
'vad': SpeechConstant.VAD_DNN
}
if (backTrackInMs.value > 0) {
let timeTamp = dateuts().valueOf();
// 方案1 唤醒词说完后,直接接句子,中间没有停顿。开启回溯,连同唤醒词一起整句识别。
// timeTamp - backTrackInMs , 表示识别从backTrackInMs毫秒前开始
sendParams['audio.mills'] = timeTamp - backTrackInMs.value;
}
module.send({
params: {
cmd: SpeechConstant.ASR_START,
params: sendParams
},
complete: (resStart) => {
console.log(resStart)
}
})
}
} as LevenOptions)
}
function registerListener() {
module.registerListener({
complete: (res : LevenResult) => {
let data = res.data;
let type = data.getString("type")
if (type == "onRegisterSuccess") {
//注册监听成功
addLog("注册监听成功")
} else if (type == "onEvent") {
//识别回调事件
let name = data.getString("name");
let params = data.getString("params") ?? "{}"
switch (name) {
case SpeechConstant.CALLBACK_EVENT_WAKEUP_SUCCESS:
//识别唤醒词成功
addLog("识别唤醒词成功:" + params)
// 此处 开始正常识别流程
recog();
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_ERROR:
//识别唤醒词报错
addLog("识别唤醒词报错:" + params)
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_STOPED:
//关闭唤醒词
addLog("关闭唤醒词")
isStart.value = false;
break
case SpeechConstant.CALLBACK_EVENT_WAKEUP_AUDIO:
//音频回调
addLog("音频回调:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_READY:
//引擎准备就绪,可以开始说话
addLog("引擎准备完成,可以开始说话")
break
case SpeechConstant.CALLBACK_EVENT_ASR_BEGIN:
//检测到用户的已经开始说话
addLog("检测到用户的已经开始说话")
isStart.value = true;
break
case SpeechConstant.CALLBACK_EVENT_ASR_END:
//检测到用户的已经停止说话,或者ASR_STOP 输入事件调用后
addLog("检测到用户的已经停止说话")
isStart.value = false;
break
case SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL:
//识别结果,识别过程
addLog("识别过程:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_FINISH:
//识别结束
addLog("识别结束:" + params)
break
case SpeechConstant.CALLBACK_EVENT_ASR_EXIT:
//引擎完成整个识别,空闲中
addLog("引擎完成整个识别,空闲中")
break
}
}
}
} as LevenOptions)
}
function initRecog() {
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY
},
complete: (res : LevenResult) => {
if (res.code == 0) {
addLog("初始化识别成功")
//注册监听
registerListener();
} else {
addLog(res.message)
}
}
} as LevenOptions)
}
function initSdk() {
//先初始化命令词
module.init({
params: {
appId: KeyUtils.APPID,
apiKey: KeyUtils.APIKEY,
secretKey: KeyUtils.SECRETKEY,
type: "wp"
},
complete: (res : LevenResult) => {
if (res.code == 0) {
addLog("初始化命令词成功")
//初始化识别
initRecog()
} else {
addLog(res.message)
}
}
} as LevenOptions)
}
function toggle() {
if (isStart.value) {
stop()
} else {
start()
}
}
onMounted(() => {
nextTick(() => {
//初始化后注册监听
initSdk()
console.log(dateuts().valueOf())
})
})
onUnload(() => {
//页面卸载
release();
})
</script>
<style>
</style>
<script setup>
</script>
<style>
</style>示例项目用到的全局变量
uniapp
js
export const SpeechConstant = {
VERSION_NAME: "3.4.4.113",
ASR_START: "asr.start",
ASR_STOP: "asr.stop",
ASR_CANCEL: "asr.cancel",
ASR_CONFIG: "asr.config",
ASR_KWS_LOAD_ENGINE: "asr.kws.load",
ASR_KWS_UNLOAD_ENGINE: "asr.kws.unload",
ASR_UPLOAD_WORDS: "asr.upload.words",
ASR_UPLOAD_CANCEL: "asr.upload.cancel",
WAKEUP_START: "wp.start",
WAKEUP_STOP: "wp.stop",
WAKEUP_LOAD_ENGINE: "wp.load",
WAKEUP_UNLOAD_ENGINE: "wp.unload",
ASR_UPLOAD_CONTRACT: "asr.upload.contract",
UPLOADER_START: "uploader.start",
UPLOADER_CANCEL: "uploader.cancel",
CALLBACK_EVENT_ASR_READY: "asr.ready",
CALLBACK_EVENT_ASR_BEGIN: "asr.begin",
CALLBACK_EVENT_ASR_AUDIO: "asr.audio",
CALLBACK_EVENT_ASR_VOLUME: "asr.volume",
CALLBACK_EVENT_ASR_END: "asr.end",
CALLBACK_EVENT_ASR_PARTIAL: "asr.partial",
CALLBACK_EVENT_ASR_FINISH: "asr.finish",
CALLBACK_EVENT_ASR_EXIT: "asr.exit",
CALLBACK_EVENT_ASR_CANCEL: "asr.cancel",
CALLBACK_EVENT_ASR_ERROR: "asr.error",
CALLBACK_EVENT_ASR_LOADED: "asr.loaded",
CALLBACK_EVENT_ASR_UNLOADED: "asr.unloaded",
CALLBACK_EVENT_ASR_SERIALNUMBER: "asr.sn",
CALLBACK_EVENT_ASR_LOG: "asr.log",
CALLBACK_EVENT_UPLOAD_COMPLETE: "asr.upload.complete",
CALLBACK_EVENT_ASR_LONG_SPEECH: "asr.long-speech.finish",
ASR_CALLBACk_NAME: "ASR.callback",
WAKEUP_CALLBACK_NAME: "WAKEUP.callback",
UPLOAD_CALLBACK_NAME: "UPLOAD.callback",
CALLBACK_ASR_STATUS: "cb.asr.status.int",
strCALLBACK_ASR_LEVEL: "cb.asr.level.int",
CALLBACK_ASR_RESULT: "cb.asr.result.string",
CALLBACK_WAK_STATUS: "cb.wak.status.int",
CALLBACK_WAK_RESULT: "cb.wak.result.string",
CALLBACK_ERROR_DOMAIN: "cb.error.domain.int16_t",
CALLBACK_ERROR_CODE: "cb.error.code.int16_t",
CALLBACK_ERROR_DESC: "cb.error.desc.string",
CALLBACK_EVENT_UNIT_FINISH: "unit.finish",
SOUND_START: "sound_start",
SOUND_END: "sound_end",
SOUND_SUCCESS: "sound_success",
SOUND_ERROR: "sound_error",
SOUND_CANCEL: "sound_cancel",
CALLBACK_EVENT_WAKEUP_STARTED: "wp.enter",
CALLBACK_EVENT_WAKEUP_READY: "wp.ready",
CALLBACK_EVENT_WAKEUP_STOPED: "wp.exit",
CALLBACK_EVENT_WAKEUP_LOADED: "wp.loaded",
CALLBACK_EVENT_WAKEUP_UNLOADED: "wp.unloaded",
CALLBACK_EVENT_WAKEUP_ERROR: "wp.error",
CALLBACK_EVENT_WAKEUP_SUCCESS: "wp.data",
CALLBACK_EVENT_WAKEUP_AUDIO: "wp.audio",
CALLBACK_EVENT_UPLOAD_FINISH: "uploader.finish",
LOG_LEVEL: "log_level",
LANGUAGE: "language",
CONTACT: "contact",
VAD: "vad",
VAD_MFE: "mfe",
VAD_MODEL: "model-vad",
VAD_DNN: "dnn",
VAD_TOUCH: "touch",
SAMPLE_RATE: "sample",
PAM: "decoder-server.pam",
NLU: "nlu",
PROP: "prop",
PUBLIC_DECODER: false,
IN_FILE: "infile",
AUDIO_MILLS: "audio.mills",
AUDIO_SOURCE: "audio.source",
OUT_FILE: "outfile",
ACCEPT_AUDIO_DATA: "accept-audio-data",
ACCEPT_AUDIO_VOLUME: "accept-audio-volume",
APP_KEY: "key",
API_KEY: "apikey",
SECRET: "secret",
IAM_APIKEY: "iam_apikey",
ACCESS_TOKEN: "access_token",
URL: "decoder-server.url",
PID: "pid",
LMID: "lm_id",
APP_NAME: "decoder-server.app",
URL_NEW: "https://vse.baidu.com/v2",
URL_OLD: "https://vse.baidu.com/echo.fcgi",
DEC_TYPE: "dec-type",
DECODER: "decoder",
ASR_VAD_RES_FILE_PATH: "vad.res-file",
VAD_ENDPOINT_TIMEOUT: "vad.endpoint-timeout",
BDS_ASR_ENABLE_LONG_SPEECH: "enable.long.speech",
ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH: "grammar",
ASR_OFFLINE_ENGINE_DAT_FILE_PATH: "asr-base-file-path",
ASR_OFFLINE_ENGINE_LICENSE_FILE_PATH: "license-file-path",
SLOT_DATA: "slot-data",
DISABLE_PUNCTUATION: "disable-punctuation",
KWS_TYPE: "kws-type",
APP_ID: "appid",
APP_SN: "appsn",
DEV: "dev",
WP_DAT_FILEPATH: "wakeup_dat_filepath",
WP_WORDS_FILE: "kws-file",
WP_WORDS: "words",
ENABLE_HTTPDNS: "enable-httpdns",
WP_VAD_ENABLE: "wp.vad_enable",
WP_ENGINE_LICENSE_FILE_PATH: "license-file-path",
BOT_SESSION_LIST: "bot_session_list",
BOT_ID: "bot_id",
BOT_SESSION: "bot_session",
BOT_SESSION_ID: "bot_session_id",
ASR_ENABLE_NUMBERFORMAT: "enable.numberformat",
ASR_PUNCTUATION_MODE: "punctuation-mode"
}js
export const KeyUtils = {
APPID: "120626545",
SECRETKEY: "7azxFEumSZCUTR7dU0Bv0YnZwyuGIhKA",
APIKEY: "Jeva58gMRCWfCFu3iQX0Qkfu"
}uniapp x
js
export const SpeechConstant = {
VERSION_NAME: "3.4.4.113",
ASR_START: "asr.start",
ASR_STOP: "asr.stop",
ASR_CANCEL: "asr.cancel",
ASR_CONFIG: "asr.config",
ASR_KWS_LOAD_ENGINE: "asr.kws.load",
ASR_KWS_UNLOAD_ENGINE: "asr.kws.unload",
ASR_UPLOAD_WORDS: "asr.upload.words",
ASR_UPLOAD_CANCEL: "asr.upload.cancel",
WAKEUP_START: "wp.start",
WAKEUP_STOP: "wp.stop",
WAKEUP_LOAD_ENGINE: "wp.load",
WAKEUP_UNLOAD_ENGINE: "wp.unload",
ASR_UPLOAD_CONTRACT: "asr.upload.contract",
UPLOADER_START: "uploader.start",
UPLOADER_CANCEL: "uploader.cancel",
CALLBACK_EVENT_ASR_READY: "asr.ready",
CALLBACK_EVENT_ASR_BEGIN: "asr.begin",
CALLBACK_EVENT_ASR_AUDIO: "asr.audio",
CALLBACK_EVENT_ASR_VOLUME: "asr.volume",
CALLBACK_EVENT_ASR_END: "asr.end",
CALLBACK_EVENT_ASR_PARTIAL: "asr.partial",
CALLBACK_EVENT_ASR_FINISH: "asr.finish",
CALLBACK_EVENT_ASR_EXIT: "asr.exit",
CALLBACK_EVENT_ASR_CANCEL: "asr.cancel",
CALLBACK_EVENT_ASR_ERROR: "asr.error",
CALLBACK_EVENT_ASR_LOADED: "asr.loaded",
CALLBACK_EVENT_ASR_UNLOADED: "asr.unloaded",
CALLBACK_EVENT_ASR_SERIALNUMBER: "asr.sn",
CALLBACK_EVENT_ASR_LOG: "asr.log",
CALLBACK_EVENT_UPLOAD_COMPLETE: "asr.upload.complete",
CALLBACK_EVENT_ASR_LONG_SPEECH: "asr.long-speech.finish",
ASR_CALLBACk_NAME: "ASR.callback",
WAKEUP_CALLBACK_NAME: "WAKEUP.callback",
UPLOAD_CALLBACK_NAME: "UPLOAD.callback",
CALLBACK_ASR_STATUS: "cb.asr.status.int",
strCALLBACK_ASR_LEVEL: "cb.asr.level.int",
CALLBACK_ASR_RESULT: "cb.asr.result.string",
CALLBACK_WAK_STATUS: "cb.wak.status.int",
CALLBACK_WAK_RESULT: "cb.wak.result.string",
CALLBACK_ERROR_DOMAIN: "cb.error.domain.int16_t",
CALLBACK_ERROR_CODE: "cb.error.code.int16_t",
CALLBACK_ERROR_DESC: "cb.error.desc.string",
CALLBACK_EVENT_UNIT_FINISH: "unit.finish",
SOUND_START: "sound_start",
SOUND_END: "sound_end",
SOUND_SUCCESS: "sound_success",
SOUND_ERROR: "sound_error",
SOUND_CANCEL: "sound_cancel",
CALLBACK_EVENT_WAKEUP_STARTED: "wp.enter",
CALLBACK_EVENT_WAKEUP_READY: "wp.ready",
CALLBACK_EVENT_WAKEUP_STOPED: "wp.exit",
CALLBACK_EVENT_WAKEUP_LOADED: "wp.loaded",
CALLBACK_EVENT_WAKEUP_UNLOADED: "wp.unloaded",
CALLBACK_EVENT_WAKEUP_ERROR: "wp.error",
CALLBACK_EVENT_WAKEUP_SUCCESS: "wp.data",
CALLBACK_EVENT_WAKEUP_AUDIO: "wp.audio",
CALLBACK_EVENT_UPLOAD_FINISH: "uploader.finish",
LOG_LEVEL: "log_level",
LANGUAGE: "language",
CONTACT: "contact",
VAD: "vad",
VAD_MFE: "mfe",
VAD_MODEL: "model-vad",
VAD_DNN: "dnn",
VAD_TOUCH: "touch",
SAMPLE_RATE: "sample",
PAM: "decoder-server.pam",
NLU: "nlu",
PROP: "prop",
PUBLIC_DECODER: false,
IN_FILE: "infile",
AUDIO_MILLS: "audio.mills",
AUDIO_SOURCE: "audio.source",
OUT_FILE: "outfile",
ACCEPT_AUDIO_DATA: "accept-audio-data",
ACCEPT_AUDIO_VOLUME: "accept-audio-volume",
APP_KEY: "key",
API_KEY: "apikey",
SECRET: "secret",
IAM_APIKEY: "iam_apikey",
ACCESS_TOKEN: "access_token",
URL: "decoder-server.url",
PID: "pid",
LMID: "lm_id",
APP_NAME: "decoder-server.app",
URL_NEW: "https://vse.baidu.com/v2",
URL_OLD: "https://vse.baidu.com/echo.fcgi",
DEC_TYPE: "dec-type",
DECODER: "decoder",
ASR_VAD_RES_FILE_PATH: "vad.res-file",
VAD_ENDPOINT_TIMEOUT: "vad.endpoint-timeout",
BDS_ASR_ENABLE_LONG_SPEECH: "enable.long.speech",
ASR_OFFLINE_ENGINE_GRAMMER_FILE_PATH: "grammar",
ASR_OFFLINE_ENGINE_DAT_FILE_PATH: "asr-base-file-path",
ASR_OFFLINE_ENGINE_LICENSE_FILE_PATH: "license-file-path",
SLOT_DATA: "slot-data",
DISABLE_PUNCTUATION: "disable-punctuation",
KWS_TYPE: "kws-type",
APP_ID: "appid",
APP_SN: "appsn",
DEV: "dev",
WP_DAT_FILEPATH: "wakeup_dat_filepath",
WP_WORDS_FILE: "kws-file",
WP_WORDS: "words",
ENABLE_HTTPDNS: "enable-httpdns",
WP_VAD_ENABLE: "wp.vad_enable",
WP_ENGINE_LICENSE_FILE_PATH: "license-file-path",
BOT_SESSION_LIST: "bot_session_list",
BOT_ID: "bot_id",
BOT_SESSION: "bot_session",
BOT_SESSION_ID: "bot_session_id",
ASR_ENABLE_NUMBERFORMAT: "enable.numberformat",
ASR_PUNCTUATION_MODE: "punctuation-mode"
}js
export const KeyUtils = {
APPID: "120626545",
SECRETKEY: "7azxFEumSZCUTR7dU0Bv0YnZwyuGIhKA",
APIKEY: "Jeva58gMRCWfCFu3iQX0Qkfu"
}