日拱一卒:浏览器端语音识别实现

1,087 阅读2分钟

前言

要实现 AI 虚拟助手的对话功能,涉及到两个关键技术,一个是 speech2text 一个是 text2speech,也就是语音识别和文字转语音。关于语音识别的实现,实现方法包括:

  1. 调用浏览器 API SpeechRecognition - Web APIs | MDN
  2. 调用第三方提供的语音识别接口,比如科大迅飞,可以限制时间免费使用一年,超时需收费。
  3. 在本地运行机器学习模型,比如 OpenAI 的 whisper
  4. ...

这里我们使用浏览器提供的 SpeechRecognition 实现语音识别功能,经测试英文识别效果较好,中文一般,不过作为免费方案也至少是可用了。

什么是 SpeechRecognition?

SpeechRecognition 是一项由浏览器提供的语音识别服务,在 Chrome 等浏览器中语音识别涉及到后端服务,所以需要联网使用: image.png 兼容性方面基本上除了 Firefox 浏览器,其他主流的浏览器都提供了支持: image.png

构造对象

因为是一项比较新的技术所以需要判断浏览器是否支持相应 API,然后构造 SpeechRecognition对象,设置属性:

// 判断是否支持 SpeechRecognition
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SpeechRecognition) return;

// 构造对象
const recognition = new SpeechRecognition();
// 设置所识别的语言
recognition.lang = 'zh-CN';
// 是否返回未确定的结果
recognition.interimResults = true;
// 是否返回连续结果
recognition.continuous = false;

更多属性详见: SpeechRecognition - Web APIs | MDN

处理事件

result 识别结果

SpeechRecognitionEventresults返回 SpeechRecognitionResultList 的对象,类似二维数组,我们可以通过 event.results[0][0].transcript获取最新的识别结果,event.results[0].isFinal可以获得是否完成识别。


recognition.addEventListener('result', handleRecognitionResult);

// 处理识别结果
const handleRecognitionResult = useCallback((event: SpeechRecognitionEvent) => {
  const text = event.results[0][0].transcript;
  // 识别结果显示
  setMessage(text);
  // 识别完成做相应动作,比如发送消息
  if (event.results[0].isFinal) {
    setMessage(text);
    // onChatProcessStart(text);
  }
}, []);

当然除了 addEventListener 的方式还可以通过 recognition.onresult 实现:

recognition.onresult = (event) => {
  const color = event.results[0][0].transcript;
  diagnostic.textContent = `Result received: ${color}.`;
  bg.style.backgroundColor = color;
};

end 识别结束

可以从事件中控制识别过程的状态转换:

  recognition.addEventListener('end', handleRecognitionEnd);

  const handleRecognitionEnd = useCallback(() => {
    setIsRecording(false);
  }, []);

同理可以通过 onend 方法实现:

recognition.onend = () => {
  console.log("Speech recognition service disconnected");
};

更多事件

更多事件详见: SpeechRecognition - Web APIs | MDN

实例方法

可通过 recognition实例控制识别过程:

const handleRecord = () => {
  if (isRecording) {
    speechRecognition?.abort();
    setIsRecording(false);
    return;
  }

  speechRecognition?.start();
  setIsRecording(true);
};

Demo 示例

你可以访问下面的网址打开 Demo 体验示例:demo.vidol.chat/ ,该 API 调用需要调用浏览器的服务,所以请自备好梯子。 image.png image.png

参考

GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak Supervision