从零到一:构建一个实时语音翻译应用(Vue3 + Web Speech API)
从零到一:构建一个实时语音翻译应用(Vue3 + Web Speech API)
前言
在全球化日益深入的今天,跨语言交流变得越来越重要。传统的翻译工具需要手动输入文本,效率较低。本文将带你从零开始,使用 Vue 3 和 Web Speech API 构建一个实时语音翻译应用,实现语音识别、实时翻译和语音播报的完整流程。
预览效果
项目地址:[https://github.com/lewuzhijing/translating]
在线演示:[https://transnow.asia/]
实时翻译app版本:https://pan.baidu.com/s/1nj_LPtiutEIsO_7-S1KWAw 提取码:rvuh

-----演示图-------
项目概述
本项目是一个基于 Vue 3 的实时语音翻译应用,主要功能包括:
- 🎤 实时语音识别:支持 Web Speech API 和 5+app 环境
- 🌐 多语言翻译:集成 Google 翻译、MyMemory 等翻译服务
- 🔊 文字转语音:支持自动播放翻译结果
- 🔄 双向翻译:支持上下两个面板的语音输入和翻译
- 📱 移动端优化:针对移动设备的触摸交互优化
技术栈
- 前端框架:Vue 3 (Composition API)
- 构建工具:Vite
- 语音识别:Web Speech API / 5+app plus.speech
- 翻译服务:MyMemory Translation API / Google Translate API
- 语音合成:Web Speech Synthesis API / 百度 TTS
核心功能实现
1. 语音识别服务
语音识别是整个应用的核心功能之一。我们创建了 speechService.js 来封装语音识别逻辑,支持 Web Speech API 和 5+app 环境。
1.1 初始化语音识别
exportfunctioninitSpeechRecognition(){// 优先检测5+app环境if(isPlusAppRecognitionAvailable()){ isPlusApp =true; console.log("检测到5+app环境,使用plus.speech API");returnnull;}// 检查浏览器是否支持Web Speech APIif(!("webkitSpeechRecognition"in window)&&!("SpeechRecognition"in window)){thrownewError("您的浏览器不支持语音识别功能");}const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognition =newSpeechRecognition();// 配置识别参数 recognition.continuous =true;// 持续识别 recognition.interimResults =true;// 返回临时结果 recognition.lang = currentLanguage;return recognition;}关键点解析:
continuous: true:启用持续识别模式,可以连续识别语音interimResults: true:返回临时识别结果,提供实时反馈- 支持环境检测,自动选择最佳 API
1.2 处理识别结果
recognition.onresult=(event)=>{let interimTranscript ="";let finalTranscript ="";const resultIndex = event.resultIndex ||0;const results = event.results ||[];for(let i = resultIndex; i < results.length; i++){const transcript = results[i][0].transcript;if(results[i].isFinal){ finalTranscript += transcript +" ";}else{ interimTranscript += transcript;}}// 更新识别结果if(onResult){onResult({ interim: interimTranscript, final: finalTranscript.trim(),});}};技术要点:
- 区分临时结果(interim)和最终结果(final)
- 临时结果提供实时反馈,最终结果用于翻译
- 使用
resultIndex避免重复处理
1.3 错误处理
recognition.onerror=(event)=>{const error = event?.error || event?.message ||"未知错误";// 忽略一些常见的非致命错误const ignorableErrors =["no-speech","aborted","audio-capture","network"];if(ignorableErrors.includes(error)){return;// 不显示给用户}// 只报告真正的错误 console.error("语音识别错误:", error);if(onError){onError(error);}};优化策略:
- 过滤非致命错误,提升用户体验
- 网络错误可能是暂时的,不中断用户操作
2. 翻译服务
翻译服务支持多种 API,提供降级策略确保服务可用性。
2.1 翻译服务封装
// src/services/translateService.jsconst languageCodes ={ English:"en", Spanish:"es", Chinese:"zh", French:"fr",// ... 更多语言};exportasyncfunctiontranslate(text, fromLang, toLang){if(!text ||!text.trim()){return"";}try{// 优先使用MyMemory翻译returnawaittranslateWithMyMemory(text, fromLang, toLang);}catch(error){ console.error("Memory翻译服务失败:", error);thrownewError("翻译服务暂时不可用,请稍后重试");}}2.2 MyMemory 翻译实现
exportasyncfunctiontranslateWithMyMemory(text, fromLang, toLang){const fromCode = languageCodes[fromLang]||"auto";const toCode = languageCodes[toLang]||"en";const url =`https://api.mymemory.translated.net/get?q=${encodeURIComponent( text )}&langpair=${fromCode}|${toCode}`;const response =awaitfetch(url);const data =await response.json();if(data.responseData && data.responseData.translatedText){return data.responseData.translatedText;}thrownewError("翻译失败");}API 选择理由:
- MyMemory:免费,有使用限制但适合个人项目
- Google Translate:免费但可能不稳定
- 百度翻译:需要 API 密钥,适合生产环境
3. 文字转语音(TTS)
TTS 功能支持多种实现方式,提供完整的降级策略。
3.1 TTS 服务封装
exportfunctionspeakText(text, language ="English", options ={}){if(!text ||!text.trim()){return;}// 检测环境并选择最佳APIif(isPlusAppEnvironment()){returnspeakTextWithPlusApp(text, language, options);}if("speechSynthesis"in window){returnspeakTextWithWebAPI(text, language, options);}// 降级到百度TTSconstBAIDU_API_KEY=import.meta.env.VITE_BAIDU_TTS_API_KEY||"";if(BAIDU_API_KEY){returnspeakTextWithBaiduTTS(text, language, options);}}3.2 Web Speech API 实现
functionspeakTextWithWebAPI(text, language ="English", options ={}){stopSpeaking();// 停止当前播放const utterance =newSpeechSynthesisUtterance(text.trim()); utterance.lang =getTTSLanguageCode(language); utterance.rate = options.rate ||1.0;// 语速 utterance.pitch = options.pitch ||1.0;// 音调 utterance.volume = options.volume !==undefined? options.volume :1.0; utterance.onstart=()=>{ isSpeaking =true;}; utterance.onend=()=>{ isSpeaking =false;}; window.speechSynthesis.speak(utterance);}4. 主应用组件
主应用组件 App.vue 整合了所有功能,实现了完整的交互流程。
4.1 语音识别和翻译流程
conststartRecording=async(panel, event)=>{// 如果已经在录音,先停止if(isRecording.value){stopRecording();awaitnewPromise(resolve=>setTimeout(resolve,300));}// 停止当前正在播放的语音if(isCurrentlySpeaking()){stopSpeaking();} currentPanel.value = panel; isRecording.value =true;// 根据面板设置识别语言const lang = panel ==='top'? sourceLanguage.value : targetLanguage.value;setRecognitionLanguage(lang);// 开始语音识别startRecognition(// onResult - 识别结果回调async(result)=>{const text = result.final || result.interim;if(panel ==='top'){ sourceText.value = text;// 如果有最终结果,立即进行翻译if(result.final && result.final.trim()){awaitperformTranslation(result.final.trim(), sourceLanguage.value, targetLanguage.value);}}else{ translatedText.value = text;// 反向翻译if(result.final && result.final.trim()){awaitperformTranslation(result.final.trim(), targetLanguage.value, sourceLanguage.value);}}},// onError - 错误回调(error)=>{// 错误处理...},// onEnd - 结束回调async()=>{ isRecording.value =false;// 在识别结束时进行翻译if(lastRecognizedText.value && lastRecognizedText.value.trim()){awaitperformTranslation(lastRecognizedText.value.trim(),...);}});};流程设计:
- 用户按下麦克风按钮
- 开始语音识别,实时显示临时结果
- 识别到最终结果后立即触发翻译
- 翻译完成后自动播放(如果启用)
4.2 翻译处理
constperformTranslation=async(text, fromLang =null, toLang =null)=>{if(!text ||!text.trim()|| isTranslating.value){return;} isTranslating.value =true;try{const result =awaittranslate(text, fromLang, toLang);// 根据翻译方向更新对应的文本if(from=== sourceLanguage.value && to === targetLanguage.value){ translatedText.value = result;// 自动播放翻译结果if(autoPlayEnabled.value && ttsSupported.value){speakText(result, targetLanguage.value);}}else{// 反向翻译 sourceText.value = result;if(autoPlayEnabled.value && ttsSupported.value){speakText(result, sourceLanguage.value);}}}catch(error){ errorMessage.value = error.message ||'翻译失败,请稍后重试';}finally{ isTranslating.value =false;}};5. 移动端优化
5.1 触摸事件处理
// 支持触摸和鼠标事件<button @mousedown.prevent="!isTouchDevice && startRecording('top', $event)" @mouseup.prevent="!isTouchDevice && stopRecording($event)" @touchstart.passive="startRecording('top', $event)" @touchend.passive="stopRecording($event)" @touchcancel.passive="handleTouchCancel($event)">关键点:
- 使用
.passive修饰符提升滚动性能 - 检测触摸设备,避免事件冲突
- 处理
touchcancel事件,确保状态正确
5.2 CSS 优化
.mic-button{touch-action: manipulation;/* 禁用双击缩放 */-webkit-tap-highlight-color: transparent;/* 移除点击高亮 */-webkit-touch-callout: none;/* 禁用长按菜单 */user-select: none;/* 禁用文本选择 */}技术难点与解决方案
1. 语音识别状态管理
问题:Web Speech API 的状态管理比较复杂,容易出现重复启动或状态不同步的问题。
解决方案:
- 使用
isListening标志位跟踪状态 - 在启动前强制停止之前的识别
- 添加重试机制处理启动失败
// 确保状态已重置if(isListening){ recognition.abort(); isListening =false;}// 延迟后重试conststartWithRetry=async(retryCount =0)=>{if(retryCount >2){ errorMessage.value ='启动语音识别失败,请重试';return;}const success =startRecognition(...);if(!success){awaitnewPromise(resolve=>setTimeout(resolve,300));awaitstartWithRetry(retryCount +1);}};2. 翻译 API 降级策略
问题:免费翻译 API 可能不稳定或有限制。
解决方案:
- 实现多 API 支持
- 提供降级策略
- 错误处理和重试机制
exportasyncfunctiontranslate(text, fromLang, toLang){try{returnawaittranslateWithMyMemory(text, fromLang, toLang);}catch(error){// 可以添加更多降级策略 console.error("翻译失败:", error);thrownewError("翻译服务暂时不可用,请稍后重试");}}3. 移动端触摸交互
问题:移动端的长按、双击等手势会干扰应用交互。
解决方案:
- 使用 CSS 禁用默认手势
- 正确处理触摸事件
- 优化按钮响应
.translate-app{-webkit-user-select: none;-webkit-touch-callout: none;-webkit-tap-highlight-color: transparent;}项目结构
translating/ ├── src/ │ ├── App.vue # 主应用组件 │ ├── main.js # 入口文件 │ ├── services/ │ │ ├── speechService.js # 语音识别和TTS服务 │ │ └── translateService.js # 翻译服务 │ └── assets/ # 静态资源 ├── package.json ├── vite.config.js └── README.md 使用说明
安装依赖
npminstall开发运行
npm run dev 构建生产版本
npm run build 浏览器要求
- 推荐:Chrome、Edge(Chromium 内核)
- 不支持:Safari、Firefox(Web Speech API 支持有限)
功能使用
- 选择语言:在中间的语言栏选择源语言和目标语言
- 开始录音:点击麦克风按钮,开始说话
- 查看翻译:识别完成后会自动翻译并显示结果
- 自动播放:翻译结果会自动播放(可在设置中关闭)
- 反向翻译:点击下方面板的麦克风,可以反向翻译
扩展功能建议
- 历史记录:保存翻译历史,方便查看
- 离线支持:使用 Service Worker 实现离线翻译
- 更多语言:扩展支持的语言列表
- 语音质量优化:添加降噪、回声消除等功能
- 翻译质量评估:显示翻译置信度
- 自定义快捷键:支持键盘快捷键操作
总结
本文详细介绍了一个实时语音翻译应用的完整实现过程,包括:
- ✅ 语音识别的实现和优化
- ✅ 多翻译 API 的集成和降级策略
- ✅ 文字转语音的实现
- ✅ 移动端交互优化
- ✅ 错误处理和状态管理
这个项目展示了如何将现代 Web API 与 Vue 3 结合,构建一个功能完整、用户体验良好的应用。通过合理的架构设计和错误处理,我们实现了一个稳定可靠的实时翻译工具。
参考资源
作者:[lewuzhijing]
项目地址:[https://github.com/lewuzhijing/translating]
在线演示:[https://transnow.asia/]
如果这篇文章对你有帮助,欢迎点赞、收藏和分享!有任何问题或建议,欢迎在评论区讨论。