功能概述
微信小程序同声传译插件提供了强大的语音识别能力,可以将用户的实时语音转换为文字内容。这个功能特别适合用于聊天输入、语音搜索、语音笔记等场景。
核心实现步骤
1. 插件配置
首先需要在 manifest.json
中配置插件信息:
json
{
"mp-weixin": {
"plugins": {
"WechatSI": {
"version": "插件的版本号",
"provider": "插件的appId"
}
}
}
}
2. 权限管理
语音功能需要用户授权,我们封装了权限检查方法:
javascript
export function authorize(scope) {
return new Promise((resolve, reject) => {
uni.getSetting({
success(res) {
if (!res.authSetting[scope]) {
uni.authorize({
scope: scope,
success(res) {
resolve(res)
},
fail(err) {
resolve(err)
console.log(err.errMsg)
}
})
} else {
resolve(res)
}
}
})
})
}
3. 录音状态管理
使用 ref 管理录音的各个状态:
javascript
const recordState = ref(-1) // -1 未授权 0 未录音 1 正在录音 2 解析录音
const startTime = ref(0)
const endTime = ref(0)
核心功能实现
初始化语音识别管理器
javascript
const plugin = requirePlugin('WechatSI')
const manager = plugin.getRecordRecognitionManager()
// 开始识别回调
manager.onRecognize = function(res) {
console.log("成功开始识别", res)
}
// 开始录音回调
manager.onStart = function(res) {
console.log("成功开始录音", res)
}
错误处理机制
完善的错误处理是良好用户体验的关键:
javascript
manager.onError = function(res) {
console.error("error msg", res)
let error = '微信异常或超时,请重试或手动输入~'
if(recordState.value) {
if(res.retcode == -30004) {
error = '声音太小,请重试~'
}
if(res.retcode != -30012) {
wx.showModal({
title: '提示',
content: error,
showCancel: false
})
}
onMikeEnd()
}
recordState.value = 0
}
录音结束处理
当用户停止录音时,获取识别结果:
javascript
manager.onStop = function(res) {
let text = res.result
console.log('结束录音,语音内容: ' + text)
if (!text || text.length == 0) {
wx.showModal({
title: '提示',
content: '听不清楚,请重新说一遍!',
showCancel: false
})
return
}
content.value += text
recordState.value = 0
// 自动发送逻辑
if(roomStore.$audioAutoSend) {
uni.$emit("SEND_MESSAGE", {
speechInput: true
})
}
}
用户体验优化
防误触处理
通过时间判断避免用户误触:
javascript
function onMikeStart(e) {
startTime.value = new Date().getTime()
recordState.value = 1
setTimeout(function() {
if (!recordState.value) {
console.log("时间小于0.5秒,认为误点,不进行录音")
return
}
manager.start({
duration: 30000, // 最长30秒
lang: 'zh_CN' // 支持中文识别
})
}, 100)
}
录音时长控制
javascript
function onMikeEnd() {
endTime.value = new Date().getTime()
let time = endTime.value - startTime.value
// 时间太短不处理
if (time < 500) {
console.log("时间太短,不调用manager.stop()")
return
}
recordState.value = 2
manager.stop()
}
技术要点总结
- 权限管理:必须先获取用户授权才能使用录音功能
- 状态管理:清晰的状态机确保流程正确
- 错误处理:针对不同错误码提供友好提示
- 性能优化:防误触、超时控制等细节处理
完整代码
javascript
export function useSpeech() {
const plugin = requirePlugin('WechatSI')
const manager = plugin.getRecordRecognitionManager()
// 事件监听
manager.onRecognize = function(res) {
console.log("成功开始识别", res)
}
manager.onStart = function(res) {
console.log("成功开始录音", res)
}
manager.onError = function(res) {
console.error("error msg", res)
let error = '微信异常或超时,请重试或手动输入~'
if(recordState.value) {
if(res.retcode == -30004) {
error = '声音太小,请重试~'
}
if(res.retcode != -30012) {
wx.showModal({
title: '提示',
content: error,
showCancel: false
})
}
onMikeEnd()
}
recordState.value = 0
}
manager.onStop = function(res) {
let text = res.result
console.log('结束录音,语音内容: ' + text)
if (!text || text.length == 0) {
wx.showModal({
title: '提示',
content: '听不清楚,请重新说一遍!',
showCancel: false
})
return
}
content.value += text
recordState.value = 0
if(roomStore.$audioAutoSend) {
uni.$emit("SEND_MESSAGE", {
speechInput: true
})
}
}
const recordState = ref(-1)
const startTime = ref(0)
const endTime = ref(0)
const startOver = ref(true)
const endEnable = ref(true)
function onMikeStart(e) {
if (!startOver.value) {
endEnable.value = false
return
} else {
startOver.value = false
endEnable.value = true
}
startTime.value = new Date().getTime()
recordState.value = 1
setTimeout(function() {
if (!recordState.value) {
console.log("时间小于0.5秒,认为误点,不进行录音")
startOver.value = true
return
}
manager.start({
duration: 30000,
lang: 'zh_CN'
})
startOver.value = true
}, 100)
}
function onMikeEnd() {
if (!endEnable.value || recordState.value == 2) {
return
}
recordState.value = 2
endTime.value = new Date().getTime()
let time = endTime.value - startTime.value
if (time < 500) {
return
}
manager.stop()
}
return {
getRecordAuth,
recordState,
onMikeStart,
onMikeEnd
}
}