最近业余时间浏览技术文章的时候,看到了一篇关于语音朗读的文章:Use JavaScript to Make Your Browser Speak(用Javascript让你的浏览器说话),文章中提到可以通过speechSynthesis实现让现代浏览器语音朗读指定的内容,这激发了我的好奇心去探索了一番,于是便有了下文。

本文提及的代码片段执行需要音频输出设备(如音响、耳机)和音频输入设备(如麦克风)等硬件设备的支持。

语音朗读 speechSynthesis
严格意义来上,实现语音朗读的功能需要speechSynthesis和SpeechSynthesisUtterance两个方法共同协作完成。SpeechSynthesisUtterance告诉浏览器需要语音朗读的内容,而speechSynthesis将需要朗读的内容合成为音频内容,由音响等一类的音频输出设备进行播放。

支持朗读的语言
speechSynthesis的实现是通过浏览器底层调用了操作系统的相关接口实现的语音朗读。因此语言的支持度可能因为浏览器和操作系统的不同而不同,可以通过speechSynthesis.getVoices()获取当前设备支持的朗读语言。

不过,多数支持speechSynthesis方法的浏览器一般都支持中文内容的朗读。而且这样也带来了一个好处:可以离线使用,也可以通过SpeechSynthesisVoice.localService方法替换成自己的音源。

代码示例

语音朗读 说话 兼容性 speechSynthesis的兼容性

排除已不再维护的IE浏览器,PC几个主流的浏览器和IOS均已支持,安卓支持性有好有坏,需要做好兼容处理。

M71提案
不过值得注意的一点是,当Chrome上线相关功能之后,发现语音朗读的功能被一些网站滥用,于是Chrome在M71提案(提案链接)之后,将触发机制变更成:需要用户自行触发事件才能进行语音朗读。

我个人测试了Chrome、Edge两款浏览器,Chrome无法通过直接调用和通过创建DOM节点触发click事件间接调用,而Edge在写文时(2021-03-13)两种方法都可以调用;因此如果有相关业务需求时,建议做好相应的兼容准备。

语音朗读 测试完这些代码的时候,脑海中忽然闪过一个想法:既然都有语音朗读了,那有没有语音识别的方法呢?于是我查了MDN及一些相关的资料,发现还真有语音识别的方法:SpeechRecognition(文档链接)。

语音识别 SpeechRecognition
跟语音朗读speechSynthesis本地朗读不同,SpeechRecognition在MDN文档(点击此处)中明确提出了是基于服务器的语音识别,也就是说必须联网才能识别。

On some browsers, like Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won’t work offline.

在某些浏览器(例如Chrome)上,网页上使用的语音识别基于服务器的识别引擎。您的音频将发送到网络服务以进行识别处理,因此它将无法离线工作。

如果你使用的浏览器是Chrome,语音识别的服务端则是由谷歌提供的。不过好在提供了SpeechRecognition.serviceURI用来自定义语音识别的提供商,算是一种权宜之计吧。

代码示例

语音朗读 点击识别语音 结束语音识别

识别准确度 我个人拿Chrome浏览器尝试了一下午,当识别率低于90%的时候,基本就会出现丢字的情况,比如我用较快的语气说了一句“今天天气怎么样”,最后识别的结果是“怎么样”。当环境比较嘈杂的时候,基本识别率就没有高于70%的时候,说一句“你好”,得到的结果要么直接报错要么不搭边,对长难句的识别率也不怎么高。

低识别率会丢字

如果希望达到一个比较高的识别率,则需要安静的环境,简单的语句,说话清晰响亮缓慢(类似于播音腔)。

高识别率

兼容性
这算是一个相当新的api,新到什么程度呢?

新到MDN文档创建SpeechRecognition相关词条的时间在2020年9月15日,截止我写文的2021年03月13日刚好半年的时间。

虽然新意味着兼容性差,但这也从某种层次上说明,未来Web前端的发展方向也许真的可能替代原生应用。

SpeechRecognition的兼容性

从兼容性来看,PC只有Chrome和Edge(仅限Chromium核心)这两款浏览器支持,移动端几乎全军覆没,只有少数几个比较新的版本支持,但不确定对整体的兼容性如何。

经过实际的测试,Chrome支持英文和中文的语音识别,而Edge会提示language-not-supported的错误,更改html上的语言仍然报错,怀疑需要更改电脑的系统语言才能解决(未确定)。

Edge提示language-not-supported的错误

语音识别 + 语音朗读 = 语音助手
市面上比较常见的各类语音助手(比如Siri),在前端的逻辑都比较简单,一般情况下如果只处理本地化的配置,如设置闹钟、询问日期等功能,核心功能主要分为语音识别和语音朗读两部分,当浏览器提供了这两项能力的时候,便已满足了语音助手的条件。

于是我尝试写了一个很简单的DEMO,将两者合二为一实现了一个语音助手。

代码示例

语音助手 点击识别语音