前言
要实现 AI 虚拟助手的对话功能,涉及到两个关键技术,一个是 speech2text 一个是 text2speech,也就是语音识别和文字转语音。关于语音识别的实现,实现方法包括:
- 调用浏览器 API SpeechRecognition - Web APIs | MDN
- 调用第三方提供的语音识别接口,比如科大迅飞,可以限制时间免费使用一年,超时需收费。
- 在本地运行机器学习模型,比如 OpenAI 的 whisper。
- ...
这里我们使用浏览器提供的 SpeechRecognition 实现语音识别功能,经测试英文识别效果较好,中文一般,不过作为免费方案也至少是可用了。
什么是 SpeechRecognition?
SpeechRecognition 是一项由浏览器提供的语音识别服务,在 Chrome 等浏览器中语音识别涉及到后端服务,所以需要联网使用:
兼容性方面基本上除了 Firefox 浏览器,其他主流的浏览器都提供了支持:
构造对象
因为是一项比较新的技术所以需要判断浏览器是否支持相应 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 识别结果
SpeechRecognitionEvent的 results返回 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实例控制识别过程:
- 取消识别:SpeechRecognition.abort(),不返回结果。
- 开始识别:SpeechRecognition.start()
- 停止识别:SpeechRecognition.stop(),返回识别结果。
const handleRecord = () => {
if (isRecording) {
speechRecognition?.abort();
setIsRecording(false);
return;
}
speechRecognition?.start();
setIsRecording(true);
};
Demo 示例
你可以访问下面的网址打开 Demo 体验示例:demo.vidol.chat/ ,该 API 调用需要调用浏览器的服务,所以请自备好梯子。
参考
GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak Supervision