微信同声传译插件完全指南:语音识别与语音合成实战
功能说明应用场景语音识别将语音转为文字语音搜索、语音输入语音合成将文字转为语音步骤播报、语音提示实时翻译中英互译(暂不常用)国际化场景功能API说明获取识别管理器录音+识别一体化开始识别duration 最长60秒停止识别触发 onStop 回调文字转语音返回音频临时路径播放音频配合 TTS 使用。
·
本文基于「灶台导航」小程序实际开发经验,全面总结微信同声传译插件(WechatSI)的使用方法,涵盖插件配置、语音识别、语音合成、权限处理及最佳实践。
一、插件简介
1.1 什么是微信同声传译插件?
微信同声传译插件是微信官方提供的语音处理插件,主要提供以下能力:
| 功能 | 说明 | 应用场景 |
|---|---|---|
| 语音识别 | 将语音转为文字 | 语音搜索、语音输入 |
| 语音合成 | 将文字转为语音 | 步骤播报、语音提示 |
| 实时翻译 | 中英互译(暂不常用) | 国际化场景 |
1.2 为什么选择官方插件?
| 对比项 | 官方插件 | 第三方服务 |
|---|---|---|
| 集成难度 | ⭐ 简单,声明即可 | ⭐⭐⭐ 需对接API |
| 费用 | 基础配额免费 | 按量计费 |
| 稳定性 | 官方维护 | 依赖第三方 |
| 审核速度 | 无需额外审核 | 可能需要ICP备案 |
二、插件配置
2.1 在 app.json 中声明插件
{
"plugins": {
"WechatSI": {
"version": "0.3.6",
"provider": "wx069ba97219f66d99"
}
}
}
参数说明:
version:插件版本号,建议使用稳定版本provider:插件 AppID,固定为wx069ba97219f66d99
注意:需要在插件市场将该插件导入。
2.2 录音权限声明
在 app.json 中添加录音权限描述:
{
"permission": {
"scope.record": {
"desc": "用于语音输入,让您通过说话快速输入食材和场景"
}
}
}
2.3 引入插件
在需要使用的页面 JS 文件顶部引入:
const plugin = requirePlugin('WechatSI')
三、语音识别实战
3.1 获取识别管理器
微信同声传译插件提供了专门的语音识别管理器,集成了录音+识别功能:
const plugin = requirePlugin('WechatSI')
// 获取语音识别管理器(录音+识别一体化)
const manager = plugin.getRecordRecognitionManager()
注意:这是插件特有的管理器,不同于
wx.getRecorderManager()。插件管理器将录音和识别合并为一个流程,使用更便捷。
3.2 初始化识别事件
Page({
data: {
isRecording: false,
recognizedText: ''
},
onLoad() {
this.initRecorderManager()
},
initRecorderManager() {
const manager = plugin.getRecordRecognitionManager()
this.recorderManager = manager
// 录音开始
manager.onStart = (res) => {
console.log('[录音] 开始录音识别')
this.setData({ isRecording: true })
}
// 识别完成
manager.onStop = (res) => {
console.log('[识别] 结果:', res.result, '时长:', res.duration)
this.setData({ isRecording: false })
const text = res.result || ''
if (text.trim()) {
this.setData({ recognizedText: text.trim() })
// 自动发送或处理识别结果
this.handleRecognizedText(text.trim())
} else {
wx.showToast({ title: '未识别到语音内容', icon: 'none' })
}
}
// 错误处理
manager.onError = (res) => {
console.error('[录音] 错误:', res.msg, 'retcode:', res.retcode)
this.setData({ isRecording: false })
wx.showToast({ title: '录音失败: ' + (res.msg || '未知错误'), icon: 'none' })
}
}
})
3.3 开始/停止识别
// 开始录音识别
startRecognition() {
this.recorderManager.start({
duration: 60000, // 最长60秒
lang: 'zh_CN' // 中文
})
}
// 停止录音识别
stopRecognition() {
this.recorderManager.stop()
}
3.4 两种交互模式
在实际项目中,我们实现了两种语音输入模式:
模式一:长按说话(按住录音,松开发送)
// 按下开始
holdStart() {
this._checkRecordPermission(() => {
this._recordSource = 'hold' // 标记来源
this.recorderManager.start({ duration: 60000, lang: 'zh_CN' })
})
}
// 松开结束
holdEnd() {
if (this.data.isRecording) {
this.recorderManager.stop()
}
}
// 在 onStop 回调中判断
manager.onStop = (res) => {
const source = this._recordSource
if (res.result && source === 'hold') {
// 自动发送
setTimeout(() => this.onSend(), 300)
}
}
模式二:点击切换(点击开始,再点击结束)
toggleRecording() {
if (this.data.isRecording) {
// 正在录音,点击结束
this.recorderManager.stop()
} else {
// 未在录音,点击开始
this._checkRecordPermission(() => {
this._recordSource = 'toggle'
this.recorderManager.start({ duration: 60000, lang: 'zh_CN' })
})
}
}
四、语音合成(TTS)实战
4.1 基础用法
const plugin = requirePlugin('WechatSI')
// 文字转语音
speakText(text) {
plugin.textToSpeech({
lang: 'zh_CN',
tts: true,
content: text,
success: (res) => {
// res.filename 是生成的音频文件临时路径
const innerAudio = wx.createInnerAudioContext()
innerAudio.src = res.filename
innerAudio.play()
innerAudio.onEnded(() => {
innerAudio.destroy()
})
innerAudio.onError((err) => {
console.error('[TTS] 播放失败:', err)
innerAudio.destroy()
})
},
fail: (err) => {
console.error('[TTS] 语音合成失败:', err)
}
})
}
4.2 播报当前步骤(实际应用)
在烹饪导航页中,我们使用 TTS 播报当前步骤:
// pages/cook/cook.js
const plugin = requirePlugin('WechatSI')
Page({
data: {
currentStep: 1,
currentStepData: {},
isVoiceOn: false,
currentAudio: null
},
// 播报当前步骤
speakCurrentStep() {
const step = this.data.currentStepData
if (!step || !step.description) return
// 构建播报文本
let text = `第${this.data.currentStep}步,${step.description}`
// 添加时长提示
if (step.duration) {
const m = Math.floor(step.duration / 60)
const s = step.duration % 60
if (m > 0) {
text += `。预计需要${m}分${s > 0 ? s + '秒' : '钟'}`
} else {
text += `。预计需要${s}秒`
}
}
// 添加小贴士
if (step.tips) {
text += `。小贴士:${step.tips}`
}
this.speakText(text)
},
// 通用播报方法
speakText(text) {
if (!this.data.isVoiceOn || !text) return
// 先停止之前的播放
if (this.currentAudio) {
this.currentAudio.stop()
this.currentAudio.destroy()
this.currentAudio = null
}
plugin.textToSpeech({
lang: 'zh_CN',
tts: true,
content: text,
success: (res) => {
if (!this.data.isVoiceOn) return // 用户已关闭
const innerAudio = wx.createInnerAudioContext()
innerAudio.src = res.filename
this.currentAudio = innerAudio
innerAudio.play()
innerAudio.onEnded(() => {
innerAudio.destroy()
if (this.currentAudio === innerAudio) {
this.currentAudio = null
}
})
innerAudio.onError((err) => {
console.error('[TTS] 播放失败:', err)
innerAudio.destroy()
if (this.currentAudio === innerAudio) {
this.currentAudio = null
}
})
},
fail: (err) => {
console.error('[TTS] 语音合成失败:', err)
}
})
},
// 开启语音
startVoice() {
this.setData({ isVoiceOn: true })
this.speakCurrentStep()
},
// 关闭语音
stopVoice() {
this.setData({ isVoiceOn: false })
if (this.currentAudio) {
this.currentAudio.stop()
this.currentAudio.destroy()
this.currentAudio = null
}
}
})
五、权限处理
5.1 检查并申请录音权限
_checkRecordPermission(callback) {
wx.getSetting({
success: (res) => {
const recordAuth = res.authSetting['scope.record']
if (recordAuth === true) {
// 已授权
callback()
} else if (recordAuth === false) {
// 用户之前拒绝过,引导去设置
wx.showModal({
title: '提示',
content: '需要麦克风权限才能使用语音输入,是否前往设置?',
success: (modalRes) => {
if (modalRes.confirm) {
wx.openSetting()
}
}
})
} else {
// 从未授权,申请授权
wx.authorize({
scope: 'scope.record',
success: () => callback(),
fail: () => {
wx.showModal({
title: '提示',
content: '需要麦克风权限才能使用语音输入,是否前往设置?',
success: (modalRes) => {
if (modalRes.confirm) {
wx.openSetting()
}
}
})
}
})
}
}
})
}
5.2 权限状态说明
| authSetting 值 | 含义 | 处理方式 |
|---|---|---|
true |
已授权 | 直接使用 |
false |
已拒绝 | 引导去设置 |
undefined |
未询问 | 调用 wx.authorize |
六、完整交互流程
6.1 语音搜索完整实现
// pages/index/index.js
const plugin = requirePlugin('WechatSI')
Page({
data: {
inputMode: 'text', // 'text' | 'voice'
isRecording: false,
inputText: ''
},
onLoad() {
this.initRecorderManager()
},
initRecorderManager() {
const manager = plugin.getRecordRecognitionManager()
this.recorderManager = manager
manager.onStart = () => {
this.setData({ isRecording: true })
}
manager.onStop = (res) => {
this.setData({ isRecording: false })
const text = res.result || ''
if (text.trim()) {
this.setData({ inputText: text.trim() })
// 自动发送搜索
this.handleSearch(text.trim())
}
}
manager.onError = (err) => {
this.setData({ isRecording: false })
wx.showToast({ title: '识别失败', icon: 'none' })
}
},
// 切换输入模式
switchInputMode() {
const newMode = this.data.inputMode === 'text' ? 'voice' : 'text'
this.setData({ inputMode: newMode })
},
// 开始语音输入
startVoiceRecord() {
this._checkRecordPermission(() => {
this.recorderManager.start({ duration: 60000, lang: 'zh_CN' })
})
},
// 结束语音输入
stopVoiceRecord() {
this.recorderManager.stop()
},
// 处理搜索
async handleSearch(text) {
wx.showLoading({ title: '搜索中...' })
try {
const res = await wx.cloud.callFunction({
name: 'chat',
data: { message: text }
})
this.setData({ searchResult: res.result })
// 可选:TTS播报结果
if (res.result.speakText) {
this.speakText(res.result.speakText)
}
} catch (err) {
wx.showToast({ title: '搜索失败', icon: 'none' })
} finally {
wx.hideLoading()
}
}
})
七、最佳实践
7.1 音频实例管理
问题:多次调用 wx.createInnerAudioContext() 会创建多个实例,导致资源浪费和播放混乱。
解决方案:单例管理
// utils/audio-manager.js
class AudioManager {
constructor() {
this.innerAudioContext = null
this.isPlaying = false
}
getInstance() {
if (!this.innerAudioContext) {
this.innerAudioContext = wx.createInnerAudioContext()
this.setupEvents()
}
return this.innerAudioContext
}
play(src) {
const audio = this.getInstance()
// 如果正在播放,先停止
if (this.isPlaying) {
audio.stop()
}
audio.src = src
this.isPlaying = true
audio.play()
}
stop() {
if (this.innerAudioContext && this.isPlaying) {
this.innerAudioContext.stop()
this.isPlaying = false
}
}
destroy() {
if (this.innerAudioContext) {
this.innerAudioContext.destroy()
this.innerAudioContext = null
}
}
}
module.exports = new AudioManager()
7.2 语音开关持久化
// 存储用户设置
function saveVoiceSettings(enabled) {
wx.setStorageSync('voiceEnabled', enabled)
}
// 读取用户设置
function getVoiceSettings() {
return wx.getStorageSync('voiceEnabled') !== false // 默认开启
}
// 页面中使用
Page({
onLoad() {
const voiceEnabled = getVoiceSettings()
this.setData({ isVoiceOn: voiceEnabled })
},
onVoiceToggle() {
const newStatus = !this.data.isVoiceOn
this.setData({ isVoiceOn: newStatus })
saveVoiceSettings(newStatus)
}
})
7.3 页面卸载时释放资源
Page({
onUnload() {
// 停止定时器
if (this._timerInterval) {
clearInterval(this._timerInterval)
}
// 停止语音
if (this.currentAudio) {
this.currentAudio.stop()
this.currentAudio.destroy()
this.currentAudio = null
}
}
})
八、常见问题
8.1 识别不到语音
插件版本过老,api过时了
或者没有打开录音权限。
8.2 点击去授权跳转页面没有授权按钮
需要先进行微信登录再通过微信授权
九、总结
9.1 核心API速查表
| 功能 | API | 说明 |
|---|---|---|
| 获取识别管理器 | plugin.getRecordRecognitionManager() |
录音+识别一体化 |
| 开始识别 | manager.start({ duration, lang }) |
duration 最长60秒 |
| 停止识别 | manager.stop() |
触发 onStop 回调 |
| 文字转语音 | plugin.textToSpeech({ lang, tts, content }) |
返回音频临时路径 |
| 播放音频 | wx.createInnerAudioContext() |
配合 TTS 使用 |
9.2 使用流程图
语音识别流程:
开始录音 → onStart → 用户说话 → stop() → onStop(result) → 处理识别结果
语音合成流程:
构建文本 → textToSpeech → success(filename) → InnerAudioContext.play() → onEnded → destroy()
作者:「倒灶了队」
项目:灶台导航 - 微信小程序
更新时间:2026-04-08
更多推荐



所有评论(0)