从零到一:构建一个实时语音翻译应用(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 初始化语音识别
javascript
export function initSpeechRecognition() {
// 优先检测5+app环境
if (isPlusAppRecognitionAvailable()) {
isPlusApp = true;
console.log("检测到5+app环境,使用plus.speech API");
return null;
}
// 检查浏览器是否支持Web Speech API
if (
!("webkitSpeechRecognition" in window) &&
!("SpeechRecognition" in window)
) {
throw new Error("您的浏览器不支持语音识别功能");
}
const SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;
recognition = new SpeechRecognition();
// 配置识别参数
recognition.continuous = true; // 持续识别
recognition.interimResults = true; // 返回临时结果
recognition.lang = currentLanguage;
return recognition;
}
关键点解析:
continuous: true:启用持续识别模式,可以连续识别语音interimResults: true:返回临时识别结果,提供实时反馈- 支持环境检测,自动选择最佳 API
1.2 处理识别结果
javascript
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 错误处理
javascript
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 翻译服务封装
javascript
// src/services/translateService.js
const languageCodes = {
English: "en",
Spanish: "es",
Chinese: "zh",
French: "fr",
// ... 更多语言
};
export async function translate(text, fromLang, toLang) {
if (!text || !text.trim()) {
return "";
}
try {
// 优先使用MyMemory翻译
return await translateWithMyMemory(text, fromLang, toLang);
} catch (error) {
console.error("Memory翻译服务失败:", error);
throw new Error("翻译服务暂时不可用,请稍后重试");
}
}
2.2 MyMemory 翻译实现
javascript
export async function translateWithMyMemory(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 = await fetch(url);
const data = await response.json();
if (data.responseData && data.responseData.translatedText) {
return data.responseData.translatedText;
}
throw new Error("翻译失败");
}
API 选择理由:
- MyMemory:免费,有使用限制但适合个人项目
- Google Translate:免费但可能不稳定
- 百度翻译:需要 API 密钥,适合生产环境
3. 文字转语音(TTS)
TTS 功能支持多种实现方式,提供完整的降级策略。
3.1 TTS 服务封装
javascript
export function speakText(text, language = "English", options = {}) {
if (!text || !text.trim()) {
return;
}
// 检测环境并选择最佳API
if (isPlusAppEnvironment()) {
return speakTextWithPlusApp(text, language, options);
}
if ("speechSynthesis" in window) {
return speakTextWithWebAPI(text, language, options);
}
// 降级到百度TTS
const BAIDU_API_KEY = import.meta.env.VITE_BAIDU_TTS_API_KEY || "";
if (BAIDU_API_KEY) {
return speakTextWithBaiduTTS(text, language, options);
}
}
3.2 Web Speech API 实现
javascript
function speakTextWithWebAPI(text, language = "English", options = {}) {
stopSpeaking(); // 停止当前播放
const utterance = new SpeechSynthesisUtterance(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 语音识别和翻译流程
javascript
const startRecording = async (panel, event) => {
// 如果已经在录音,先停止
if (isRecording.value) {
stopRecording();
await new Promise(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()) {
await performTranslation(result.final.trim(),
sourceLanguage.value, targetLanguage.value);
}
} else {
translatedText.value = text;
// 反向翻译
if (result.final && result.final.trim()) {
await performTranslation(result.final.trim(),
targetLanguage.value, sourceLanguage.value);
}
}
},
// onError - 错误回调
(error) => {
// 错误处理...
},
// onEnd - 结束回调
async () => {
isRecording.value = false;
// 在识别结束时进行翻译
if (lastRecognizedText.value && lastRecognizedText.value.trim()) {
await performTranslation(lastRecognizedText.value.trim(), ...);
}
}
);
};
流程设计:
- 用户按下麦克风按钮
- 开始语音识别,实时显示临时结果
- 识别到最终结果后立即触发翻译
- 翻译完成后自动播放(如果启用)
4.2 翻译处理
javascript
const performTranslation = async (text, fromLang = null, toLang = null) => {
if (!text || !text.trim() || isTranslating.value) {
return;
}
isTranslating.value = true;
try {
const result = await translate(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 触摸事件处理
javascript
// 支持触摸和鼠标事件
<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 优化
css
.mic-button {
touch-action: manipulation; /* 禁用双击缩放 */
-webkit-tap-highlight-color: transparent; /* 移除点击高亮 */
-webkit-touch-callout: none; /* 禁用长按菜单 */
user-select: none; /* 禁用文本选择 */
}
技术难点与解决方案
1. 语音识别状态管理
问题:Web Speech API 的状态管理比较复杂,容易出现重复启动或状态不同步的问题。
解决方案:
- 使用
isListening标志位跟踪状态 - 在启动前强制停止之前的识别
- 添加重试机制处理启动失败
javascript
// 确保状态已重置
if (isListening) {
recognition.abort();
isListening = false;
}
// 延迟后重试
const startWithRetry = async (retryCount = 0) => {
if (retryCount > 2) {
errorMessage.value = '启动语音识别失败,请重试';
return;
}
const success = startRecognition(...);
if (!success) {
await new Promise(resolve => setTimeout(resolve, 300));
await startWithRetry(retryCount + 1);
}
};
2. 翻译 API 降级策略
问题:免费翻译 API 可能不稳定或有限制。
解决方案:
- 实现多 API 支持
- 提供降级策略
- 错误处理和重试机制
javascript
export async function translate(text, fromLang, toLang) {
try {
return await translateWithMyMemory(text, fromLang, toLang);
} catch (error) {
// 可以添加更多降级策略
console.error("翻译失败:", error);
throw new Error("翻译服务暂时不可用,请稍后重试");
}
}
3. 移动端触摸交互
问题:移动端的长按、双击等手势会干扰应用交互。
解决方案:
- 使用 CSS 禁用默认手势
- 正确处理触摸事件
- 优化按钮响应
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
使用说明
安装依赖
bash
npm install
开发运行
bash
npm run dev
构建生产版本
bash
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/\]
如果这篇文章对你有帮助,欢迎点赞、收藏和分享!有任何问题或建议,欢迎在评论区讨论。