基于Vue3与百度语音识别API的录音转文字系统实现指南
2025.09.23 13:10浏览量:1简介:本文详细介绍如何基于Vue3开发长按或点击触发录音功能,结合百度语音识别API实现音频文件实时转文字并展示的完整流程。涵盖录音权限管理、音频流处理、API调用优化及前端界面交互等核心环节。
一、系统架构设计
本系统采用Vue3组合式API构建前端界面,通过WebRTC的MediaRecorder API实现浏览器端录音功能。录音数据经分块处理后,通过百度语音识别短语音接口或实时语音识别接口转换为文本。系统分为三大模块:录音控制模块、音频处理模块和文本展示模块。
录音控制模块需处理用户交互逻辑,包括长按触发、点击开始/停止等操作。建议采用防抖策略优化按钮响应,同时需处理移动端触摸事件与桌面端鼠标事件的兼容性问题。在Vue3中可通过@touchstart和@touchend实现移动端长按检测,结合@mousedown和@mouseup完善桌面端支持。
音频处理模块需解决浏览器兼容性问题。MediaRecorder在不同浏览器中的支持程度存在差异,建议通过特性检测实现渐进增强:
const isSupported = () => {return navigator.mediaDevices &&typeof MediaRecorder !== 'undefined' &&/(chrome|firefox|edge)/i.test(navigator.userAgent);}
二、录音功能实现
权限获取与设备选择
使用navigator.mediaDevices.getUserMedia()获取音频流,建议添加错误处理回调:const startRecording = async () => {try {const stream = await navigator.mediaDevices.getUserMedia({ audio: true });mediaRecorder = new MediaRecorder(stream, {mimeType: 'audio/wav',audioBitsPerSecond: 16000});// ...其他初始化逻辑} catch (err) {console.error('录音权限获取失败:', err);alert('需要麦克风权限才能使用录音功能');}};
分块录音与实时处理
配置MediaRecorder的ondataavailable事件实现分块录音:let audioChunks = [];mediaRecorder.ondataavailable = (e) => {if (e.data.size > 0) {audioChunks.push(e.data);// 实时处理逻辑(可选)}};
停止录音与文件生成
停止录音时需合并音频块并生成Blob对象:const stopRecording = () => {mediaRecorder.stop();mediaRecorder.onstop = () => {const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });uploadAudio(audioBlob);audioChunks = [];};};
三、百度语音识别API集成
API准备与鉴权
在百度智能云控制台创建语音识别应用,获取API Key和Secret Key。建议使用后端服务生成Access Token,避免前端暴露敏感信息。若必须前端生成,需配置严格的CORS策略:const getAccessToken = async () => {const response = await fetch('YOUR_BACKEND_TOKEN_ENDPOINT', {method: 'POST',headers: { 'Content-Type': 'application/json' }});return response.json();};
短语音识别实现
对于短音频文件(<60秒),推荐使用短语音识别接口:const recognizeShortAudio = async (audioBlob) => {const formData = new FormData();formData.append('audio', audioBlob, 'recording.wav');formData.append('format', 'wav');formData.append('rate', 16000);formData.append('dev_pid', 1537); // 中文普通话const { access_token } = await getAccessToken();const response = await fetch(`https://vop.baidu.com/server_api?access_token=${access_token}`, {method: 'POST',body: formData});return response.json();};
实时语音识别优化
对于长音频或实时场景,需实现WebSocket连接:const recognizeRealTime = async (audioStream) => {const { access_token } = await getAccessToken();const socket = new WebSocket(`wss://vop.baidu.com/ws_api?access_token=${access_token}`);socket.onopen = () => {const params = {format: 'wav',rate: 16000,channel: 1,token: access_token};socket.send(JSON.stringify({"speech": "base64编码的音频数据","format": "wav","rate": 16000,"channel": 1,"cuid": "YOUR_DEVICE_ID"}));};socket.onmessage = (e) => {const result = JSON.parse(e.data);// 处理实时识别结果};};
四、前端界面与交互设计
录音按钮状态管理
使用Vue3的ref和computed实现按钮状态切换:<template><button@touchstart="handleTouchStart"@touchend="handleTouchEnd":class="{ 'recording': isRecording }">{{ isRecording ? '停止录音' : '长按录音' }}</button><div v-if="transcript" class="transcript">{{ transcript }}</div></template><script setup>import { ref, computed } from 'vue';const isRecording = ref(false);const transcript = ref('');const handleTouchStart = () => {isRecording.value = true;startRecording();};const handleTouchEnd = () => {isRecording.value = false;stopRecording();};</script>
识别结果动态展示
采用逐字显示效果增强用户体验:const displayResult = (result) => {const words = result.split('');let index = 0;const interval = setInterval(() => {if (index < words.length) {transcript.value += words[index];index++;} else {clearInterval(interval);}}, 50);};
五、性能优化与错误处理
音频压缩策略
使用audio-context进行实时降采样:const compressAudio = (audioBlob) => {return new Promise((resolve) => {const audioContext = new (window.AudioContext || window.webkitAudioContext)();const reader = new FileReader();reader.onload = (e) => {const arrayBuffer = e.target.result;audioContext.decodeAudioData(arrayBuffer).then(audioBuffer => {const offlineCtx = new OfflineAudioContext(audioBuffer.numberOfChannels,audioBuffer.length,audioBuffer.sampleRate);// 处理逻辑...});};reader.readAsArrayBuffer(audioBlob);});};
API调用容错机制
实现重试策略和备用方案:const callWithRetry = async (fn, retries = 3) => {for (let i = 0; i < retries; i++) {try {return await fn();} catch (err) {if (i === retries - 1) throw err;await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));}}};
六、安全与隐私考虑
数据传输加密
确保所有API调用使用HTTPS,音频文件上传前进行加密处理:const encryptAudio = (audioBlob) => {// 使用Web Crypto API实现加密return crypto.subtle.encrypt({ name: "AES-GCM", iv: new Uint8Array(12) },cryptoKey,await audioBlob.arrayBuffer()).then(encrypted => {return new Blob([encrypted], { type: 'audio/wav' });});};
用户隐私保护
在界面显著位置展示隐私政策链接,录音前获取明确授权。建议实现本地缓存控制,允许用户清除历史记录。
七、部署与监控
前端构建优化
使用Vite或Webpack进行代码分割,减少首屏加载时间:// vite.config.jsexport default {build: {rollupOptions: {output: {manualChunks: {recorder: ['media-recorder-polyfill'],api: ['axios']}}}}};
错误监控集成
接入Sentry等错误监控服务:import * as Sentry from '@sentry/vue';const app = createApp(App);Sentry.init({dsn: 'YOUR_DSN',integrations: [new Sentry.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),}),],});app.use(Sentry.VueIntegration);
该实现方案通过模块化设计实现了录音转文字的核心功能,兼顾了性能优化与用户体验。实际开发中需根据具体业务场景调整参数配置,建议先在测试环境验证API调用限额和错误处理机制。对于高并发场景,可考虑引入消息队列缓冲音频处理请求。

发表评论
登录后可评论,请前往 登录 或 注册