掘金文章归档 · 第 11 篇 AI 概念系列 2/4 Vue3 / Web Speech

Web Speech API 实现语音的识别和播放

SpeechRecognition 识别 + speechSynthesis 播放,原生 API 零依赖搞定"语音对话"

原文作者:随意_(掘金) | juejin.cn/post/7491234023739441189 | 发布于 2025-04-10 | 阅读 681 · 约 1 分钟

0背景:大模型项目的语音识别与播放

在进行大模型的开发项目中,有很多会涉及到语音的识别及语音的播放。现按照 Web Speech API 原生支持的能力,实现此功能。

⚠️ 注意:此 demo 仅在科学上网的情况下可用——浏览器默认调用的语音识别服务有网络限制。

文章后会放源码:对接科大讯飞的版本。

1实现语音的识别(基础版)

<template>
  <div>
    <button @click="startRecognition" :disabled="isListening">开始录音</button>
    <button @click="stopRecognition" :disabled="!isListening">停止</button>
    <p>识别结果: {{ recognitionText }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const isListening = ref(false);
const recognitionText = ref('');
let recognition;

const startRecognition = () => {
  // 检查浏览器是否支持
  if (!('webkitSpeechRecognition' in window)) {
    alert('您的浏览器不支持语音识别');
    return;
  }

  recognition = new window.webkitSpeechRecognition();
  recognition.continuous = true;     // 连续识别
  recognition.interimResults = true; // 返回中间结果
  recognition.lang = 'zh-CN';        // 设置为中文

  recognition.onstart = () => {
    isListening.value = true;
  };

  recognition.onresult = (event) => {
    let interimTranscript = '';
    let finalTranscript = '';

    for (let i = event.resultIndex; i < event.results.length; i++) {
      const transcript = event.results[i][0].transcript;
      if (event.results[i].isFinal) {
        finalTranscript += transcript;      // 最终结果
      } else {
        interimTranscript += transcript;    // 临时结果
      }
    }

    recognitionText.value = finalTranscript || interimTranscript;
  };

  recognition.onerror = (event) => {
    console.error('语音识别错误:', event.error);
    isListening.value = false;
  };

  recognition.onend = () => {
    isListening.value = false;
  };

  recognition.start();
};

const stopRecognition = () => {
  if (recognition) {
    recognition.stop();
  }
};
</script>
📌 关键配置:webkitSpeechRecognition(Chrome 前缀 API)+ continuous: true 连续识别 + interimResults: true 中间结果 + lang: 'zh-CN' 中文。onresult 里区分 isFinal(最终结果)与临时结果。

2语音的识别及播放(合成版)

在识别的基础上,加入 speechSynthesis + SpeechSynthesisUtterance 实现"识别 → 文字 → 语音播放"闭环:

<template>
  <div>
    <button @click="startRecognition">开始语音识别</button>
    <button @click="stopRecognition">停止语音识别</button>
    <button @click="speakText">播放文字语音</button>
    <textarea v-model="recognizedText" rows="4" cols="50" placeholder="识别结果将显示在这里"></textarea>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const recognizedText = ref('');
const recognition = ref(null);
const synth = ref(window.speechSynthesis);

// 初始化语音识别
const initRecognition = () => {
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
  recognition.value = new SpeechRecognition();
  recognition.value.lang = 'zh-CN';

  recognition.value.onresult = (event) => {
    const transcript = event.results[0][0].transcript;
    recognizedText.value = transcript;
  };

  recognition.value.onerror = (event) => {
    console.error('语音识别出错:', event.error);
  };
};

// 开始语音识别
const startRecognition = () => {
  if (!recognition.value) {
    initRecognition();
  }
  recognition.value.start();
};

// 停止语音识别
const stopRecognition = () => {
  if (recognition.value) {
    recognition.value.stop();
  }
};

// 播放文字语音
const speakText = () => {
  if (recognizedText.value) {
    const utterance = new SpeechSynthesisUtterance(recognizedText.value);
    utterance.lang = 'zh-CN';
    synth.value.speak(utterance);
  }
};
</script>

<style scoped>
button {
  margin: 5px;
}
</style>
✅ 兼容性写法:window.SpeechRecognition || window.webkitSpeechRecognition 双兜底;播放用 new SpeechSynthesisUtterance(text) 构造朗读对象,utterance.lang = 'zh-CN' 指定中文,最后 synth.speak(utterance)
截图位置请对照原文:页面三个按钮(开始/停止语音识别、播放文字语音)+ 识别结果文本框。

3缺点 & 对接第三方

3.1 缺点

3.2 对接第三方

国内访问可以对接百度、星火、阿里云的语音服务。作者这边对接的是科大讯飞的,感兴趣的可以注册一下科大讯飞的语音服务(demo 地址见原文)。

方案识别(ASR)播放(TTS)网络要求
Web Speech API(原生)✅ 但需科学上网✅ 本地即可识别依赖 Google 服务
科大讯飞 / 百度 / 星火 / 阿里云✅ 国内可用✅ 国内可用国内直连,需注册 key

4术语表 & 附录:完整代码

术语表

术语定义
SpeechRecognitionWeb Speech 语音识别接口(Chrome 下为 webkitSpeechRecognition)
interimResults是否返回中间临时识别结果(边听边出字)
isFinal标记该段结果是否为最终结果
speechSynthesis语音合成(TTS)接口,本地朗读文字
SpeechSynthesisUtterance一次朗读任务的描述对象(文本 + lang + 语速等)
ASR / TTS自动语音识别 / 文本转语音

附录 A:最小可运行骨架

<script setup>
import { ref } from 'vue';

const recognizedText = ref('');
const recognition = ref(null);
const synth = ref(window.speechSynthesis);

const initRecognition = () => {
  const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
  recognition.value = new SpeechRecognition();
  recognition.value.lang = 'zh-CN';
  recognition.value.onresult = (event) => {
    recognizedText.value = event.results[0][0].transcript;
  };
  recognition.value.onerror = (event) => console.error(event.error);
};

const startRecognition = () => {
  if (!recognition.value) initRecognition();
  recognition.value.start();
};

const stopRecognition = () => recognition.value?.stop();

const speakText = () => {
  if (recognizedText.value) {
    const utterance = new SpeechSynthesisUtterance(recognizedText.value);
    utterance.lang = 'zh-CN';
    synth.value.speak(utterance);
  }
};
</script>

<template>
  <div>
    <button @click="startRecognition">开始语音识别</button>
    <button @click="stopRecognition">停止语音识别</button>
    <button @click="speakText">播放文字语音</button>
    <textarea v-model="recognizedText" rows="4" cols="50" placeholder="识别结果将显示在这里"></textarea>
  </div>
</template>
⚠️ 生产建议:国内项目直接对接讯飞 / 百度 / 阿里云语音服务,避免 Web Speech 识别在国内不可用的问题;原生 API 适合快速 demo 验证。