从零到一:构建一个实时语音翻译应用(Vue3 + Web Speech API)

从零到一:构建一个实时语音翻译应用(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(),...);}});};

流程设计

  1. 用户按下麦克风按钮
  2. 开始语音识别,实时显示临时结果
  3. 识别到最终结果后立即触发翻译
  4. 翻译完成后自动播放(如果启用)
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 支持有限)

功能使用

  1. 选择语言:在中间的语言栏选择源语言和目标语言
  2. 开始录音:点击麦克风按钮,开始说话
  3. 查看翻译:识别完成后会自动翻译并显示结果
  4. 自动播放:翻译结果会自动播放(可在设置中关闭)
  5. 反向翻译:点击下方面板的麦克风,可以反向翻译

扩展功能建议

  1. 历史记录:保存翻译历史,方便查看
  2. 离线支持:使用 Service Worker 实现离线翻译
  3. 更多语言:扩展支持的语言列表
  4. 语音质量优化:添加降噪、回声消除等功能
  5. 翻译质量评估:显示翻译置信度
  6. 自定义快捷键:支持键盘快捷键操作

总结

本文详细介绍了一个实时语音翻译应用的完整实现过程,包括:

  • ✅ 语音识别的实现和优化
  • ✅ 多翻译 API 的集成和降级策略
  • ✅ 文字转语音的实现
  • ✅ 移动端交互优化
  • ✅ 错误处理和状态管理

这个项目展示了如何将现代 Web API 与 Vue 3 结合,构建一个功能完整、用户体验良好的应用。通过合理的架构设计和错误处理,我们实现了一个稳定可靠的实时翻译工具。

参考资源


作者:[lewuzhijing]
项目地址:[https://github.com/lewuzhijing/translating]
在线演示:[https://transnow.asia/]

如果这篇文章对你有帮助,欢迎点赞、收藏和分享!有任何问题或建议,欢迎在评论区讨论。

Read more

nginx 部署前端vue项目

nginx 部署前端vue项目

👨‍⚕主页: gis分享者 👨‍⚕感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕收录于专栏:前端工程师 文章目录 * 一、🍓什么是nginx? * 二、🍓nginx 部署前端vue项目步骤 * 2.1 🍉安装nginx * 2.1.1 🍌windows环境安装 * 2.1.2 🍌linux环境安装 * 2.2 🍉打包vue项目 * 2.3 🍉配置nginx 一、🍓什么是nginx? Nginx是一款轻量级的HTTP服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的IO性能,时常用于服务端的反向代理和负载均衡。 优点: * 支持海量高并发:采用IO多路复用epoll。官方测试Nginx能够支持5万并发链接,实际生产环境中可以支撑2-4万并发连接数。 * 内存消耗少 * 可商业化 * 配置文件简单 除了这些优点还有很多,比如反向代理功能,灰度发布,负载均衡功能等

前端网页开发学习(HTML+CSS+JS)有这一篇就够!

前端网页开发学习(HTML+CSS+JS)有这一篇就够!

目录 HTML教程 ▐ 概述 ▐ 基础语法 ▐ 文本标签 ▐ 列表标签  ▐ 表格标签 ▐ 表单标签 CSS教程 ▐ 概述 ▐ 基础语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 透明度 ▐ 伪类 ▐ 盒子模型 ▐ 浮动 ▐ 定位 JavaScript教程 ▐ 概述 ▐ 基础语法 ▐ 函数 ▐ 事件 ▐ 计时   ▐ HTML DOM html css js三者之间的关系 HTML教程 ▐ 概述 HTML是HyperText  Markup  Language的缩写,即超文本标记语言。它为我们提供了许多功能不同的标签,最终运行时由浏览器对标签进行解析,呈现出不同标签的样子。 ▐ 基础语法 注释:  <!--   -->        ( Ctrl + / ) <body> <

医疗咨询机器人怕出事?Qwen3Guard-Gen-WEB帮你拦截风险

医疗咨询机器人怕出事?Qwen3Guard-Gen-WEB帮你拦截风险 在AI医疗应用加速落地的今天,一个现实困境正困扰着每家尝试部署智能问诊系统的机构:既要让患者获得即时、专业的健康建议,又必须确保每一句回复都经得起医学伦理、法律法规和临床安全的三重检验。一句看似无害的“试试偏方”可能延误治疗,一段模糊的“可能有风险”可能引发恐慌,而一次对禁忌症的疏漏判断,甚至可能危及生命。 更棘手的是,通用大模型并非为医疗场景而生——它不了解药品相互作用,不掌握最新诊疗指南,也无法识别患者描述中隐含的急症信号(如“头痛伴喷射性呕吐”实为颅内压增高征兆)。当医疗咨询机器人直接暴露在用户自由输入的语境中,它就像一位未经资质认证的“云医生”,能力越强,潜在风险越高。 正是在这种高敏感、零容错的现实压力下,Qwen3Guard-Gen-WEB 的出现不是锦上添花,而是雪中送炭。它并非用来生成诊断结论,而是作为一道嵌入式“安全闸门”,专为拦截那些游走在合规边缘、潜藏临床风险、违背医学常识的输出内容。它不替代医生,但能确保机器人永远不说出不该说的话。 1. 它不是医生,却是医疗AI的“执业资格审查员