logo

基于Vue3与百度语音识别API的录音转文字系统实现指南

作者:谁偷走了我的奶酪2025.09.23 13:10浏览量:1

简介:本文详细介绍如何基于Vue3开发长按或点击触发录音功能,结合百度语音识别API实现音频文件实时转文字并展示的完整流程。涵盖录音权限管理、音频流处理、API调用优化及前端界面交互等核心环节。

一、系统架构设计

本系统采用Vue3组合式API构建前端界面,通过WebRTC的MediaRecorder API实现浏览器端录音功能。录音数据经分块处理后,通过百度语音识别短语音接口或实时语音识别接口转换为文本。系统分为三大模块:录音控制模块、音频处理模块和文本展示模块。

录音控制模块需处理用户交互逻辑,包括长按触发、点击开始/停止等操作。建议采用防抖策略优化按钮响应,同时需处理移动端触摸事件与桌面端鼠标事件的兼容性问题。在Vue3中可通过@touchstart@touchend实现移动端长按检测,结合@mousedown@mouseup完善桌面端支持。

音频处理模块需解决浏览器兼容性问题。MediaRecorder在不同浏览器中的支持程度存在差异,建议通过特性检测实现渐进增强:

  1. const isSupported = () => {
  2. return navigator.mediaDevices &&
  3. typeof MediaRecorder !== 'undefined' &&
  4. /(chrome|firefox|edge)/i.test(navigator.userAgent);
  5. }

二、录音功能实现

  1. 权限获取与设备选择
    使用navigator.mediaDevices.getUserMedia()获取音频流,建议添加错误处理回调:

    1. const startRecording = async () => {
    2. try {
    3. const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    4. mediaRecorder = new MediaRecorder(stream, {
    5. mimeType: 'audio/wav',
    6. audioBitsPerSecond: 16000
    7. });
    8. // ...其他初始化逻辑
    9. } catch (err) {
    10. console.error('录音权限获取失败:', err);
    11. alert('需要麦克风权限才能使用录音功能');
    12. }
    13. };
  2. 分块录音与实时处理
    配置MediaRecorder的ondataavailable事件实现分块录音:

    1. let audioChunks = [];
    2. mediaRecorder.ondataavailable = (e) => {
    3. if (e.data.size > 0) {
    4. audioChunks.push(e.data);
    5. // 实时处理逻辑(可选)
    6. }
    7. };
  3. 停止录音与文件生成
    停止录音时需合并音频块并生成Blob对象:

    1. const stopRecording = () => {
    2. mediaRecorder.stop();
    3. mediaRecorder.onstop = () => {
    4. const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
    5. uploadAudio(audioBlob);
    6. audioChunks = [];
    7. };
    8. };

三、百度语音识别API集成

  1. API准备与鉴权
    在百度智能云控制台创建语音识别应用,获取API Key和Secret Key。建议使用后端服务生成Access Token,避免前端暴露敏感信息。若必须前端生成,需配置严格的CORS策略:

    1. const getAccessToken = async () => {
    2. const response = await fetch('YOUR_BACKEND_TOKEN_ENDPOINT', {
    3. method: 'POST',
    4. headers: { 'Content-Type': 'application/json' }
    5. });
    6. return response.json();
    7. };
  2. 短语音识别实现
    对于短音频文件(<60秒),推荐使用短语音识别接口:

    1. const recognizeShortAudio = async (audioBlob) => {
    2. const formData = new FormData();
    3. formData.append('audio', audioBlob, 'recording.wav');
    4. formData.append('format', 'wav');
    5. formData.append('rate', 16000);
    6. formData.append('dev_pid', 1537); // 中文普通话
    7. const { access_token } = await getAccessToken();
    8. const response = await fetch(`https://vop.baidu.com/server_api?access_token=${access_token}`, {
    9. method: 'POST',
    10. body: formData
    11. });
    12. return response.json();
    13. };
  3. 实时语音识别优化
    对于长音频或实时场景,需实现WebSocket连接:

    1. const recognizeRealTime = async (audioStream) => {
    2. const { access_token } = await getAccessToken();
    3. const socket = new WebSocket(`wss://vop.baidu.com/ws_api?access_token=${access_token}`);
    4. socket.onopen = () => {
    5. const params = {
    6. format: 'wav',
    7. rate: 16000,
    8. channel: 1,
    9. token: access_token
    10. };
    11. socket.send(JSON.stringify({
    12. "speech": "base64编码的音频数据",
    13. "format": "wav",
    14. "rate": 16000,
    15. "channel": 1,
    16. "cuid": "YOUR_DEVICE_ID"
    17. }));
    18. };
    19. socket.onmessage = (e) => {
    20. const result = JSON.parse(e.data);
    21. // 处理实时识别结果
    22. };
    23. };

四、前端界面与交互设计

  1. 录音按钮状态管理
    使用Vue3的refcomputed实现按钮状态切换:

    1. <template>
    2. <button
    3. @touchstart="handleTouchStart"
    4. @touchend="handleTouchEnd"
    5. :class="{ 'recording': isRecording }"
    6. >
    7. {{ isRecording ? '停止录音' : '长按录音' }}
    8. </button>
    9. <div v-if="transcript" class="transcript">{{ transcript }}</div>
    10. </template>
    11. <script setup>
    12. import { ref, computed } from 'vue';
    13. const isRecording = ref(false);
    14. const transcript = ref('');
    15. const handleTouchStart = () => {
    16. isRecording.value = true;
    17. startRecording();
    18. };
    19. const handleTouchEnd = () => {
    20. isRecording.value = false;
    21. stopRecording();
    22. };
    23. </script>
  2. 识别结果动态展示
    采用逐字显示效果增强用户体验:

    1. const displayResult = (result) => {
    2. const words = result.split('');
    3. let index = 0;
    4. const interval = setInterval(() => {
    5. if (index < words.length) {
    6. transcript.value += words[index];
    7. index++;
    8. } else {
    9. clearInterval(interval);
    10. }
    11. }, 50);
    12. };

五、性能优化与错误处理

  1. 音频压缩策略
    使用audio-context进行实时降采样:

    1. const compressAudio = (audioBlob) => {
    2. return new Promise((resolve) => {
    3. const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    4. const reader = new FileReader();
    5. reader.onload = (e) => {
    6. const arrayBuffer = e.target.result;
    7. audioContext.decodeAudioData(arrayBuffer).then(audioBuffer => {
    8. const offlineCtx = new OfflineAudioContext(
    9. audioBuffer.numberOfChannels,
    10. audioBuffer.length,
    11. audioBuffer.sampleRate
    12. );
    13. // 处理逻辑...
    14. });
    15. };
    16. reader.readAsArrayBuffer(audioBlob);
    17. });
    18. };
  2. API调用容错机制
    实现重试策略和备用方案:

    1. const callWithRetry = async (fn, retries = 3) => {
    2. for (let i = 0; i < retries; i++) {
    3. try {
    4. return await fn();
    5. } catch (err) {
    6. if (i === retries - 1) throw err;
    7. await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    8. }
    9. }
    10. };

六、安全与隐私考虑

  1. 数据传输加密
    确保所有API调用使用HTTPS,音频文件上传前进行加密处理:

    1. const encryptAudio = (audioBlob) => {
    2. // 使用Web Crypto API实现加密
    3. return crypto.subtle.encrypt(
    4. { name: "AES-GCM", iv: new Uint8Array(12) },
    5. cryptoKey,
    6. await audioBlob.arrayBuffer()
    7. ).then(encrypted => {
    8. return new Blob([encrypted], { type: 'audio/wav' });
    9. });
    10. };
  2. 用户隐私保护
    在界面显著位置展示隐私政策链接,录音前获取明确授权。建议实现本地缓存控制,允许用户清除历史记录。

七、部署与监控

  1. 前端构建优化
    使用Vite或Webpack进行代码分割,减少首屏加载时间:

    1. // vite.config.js
    2. export default {
    3. build: {
    4. rollupOptions: {
    5. output: {
    6. manualChunks: {
    7. recorder: ['media-recorder-polyfill'],
    8. api: ['axios']
    9. }
    10. }
    11. }
    12. }
    13. };
  2. 错误监控集成
    接入Sentry等错误监控服务:

    1. import * as Sentry from '@sentry/vue';
    2. const app = createApp(App);
    3. Sentry.init({
    4. dsn: 'YOUR_DSN',
    5. integrations: [
    6. new Sentry.BrowserTracing({
    7. routingInstrumentation: Sentry.vueRouterInstrumentation(router),
    8. }),
    9. ],
    10. });
    11. app.use(Sentry.VueIntegration);

该实现方案通过模块化设计实现了录音转文字的核心功能,兼顾了性能优化与用户体验。实际开发中需根据具体业务场景调整参数配置,建议先在测试环境验证API调用限额和错误处理机制。对于高并发场景,可考虑引入消息队列缓冲音频处理请求。

相关文章推荐

发表评论