JS实现将文字转换为语音并自动播放

在开发业务系统时,有时候可能需要使用语音播报一段文字,比如下面的场景:

当顾客付款成功后,需要系统自动播报收款的金额,其中付款金额是不固定的,比如1元、2元、3.2元等等
如果是相对固定的场景,并且语音有限的情况下,可以采用录制的方式,即先录制好所有的音频资源,然后根据业务场景播放相应的音频即可;但是如果场景不固定,需要的语音也不一样时,采用录制的方式的话,音频资源将会非常多,而且还可能会出现不全的问题,那么这个时候利用语音合成技术是一个较好的办法,即实时将文字转换成语音。
【JS实现将文字转换为语音并自动播放】目前文字转语音即语音合成技术现在已经很成熟了,像百度、讯飞等都提供了相关的服务,支持将文字转换成各种形式的语音,通常这些服务都需要付费使用,如果对语音要求不高,并且又想节约成本,那么可以直接使用浏览器的语音合成功能。
有些浏览器已经支持将文字转换为语音的功能,下面来看看官方的介绍:
语音合成是通过 SpeechSynthesis 接口进行访问,它提供了文字到语音(TTS)的能力,这使得程序能够读出它们的文字内容(通常使用设备默认的语音合成器)。不同的声音类类型通过 SpeechSynthesisVoice 对象进行表示,不同部分的文字则由 SpeechSynthesisUtterance 对象来表示,最后可以通过 SpeechSynthesis.speak() 方法来产生语音。
语音合成主要涉及到上面的三个对象:SpeechSynthesis 、SpeechSynthesisVoice 和 SpeechSynthesisUtterance 。
1、SpeechSynthesis
SpeechSynthesis 是语音合成服务的控制器接口,可用于获取设备上可用的合成语音,开始、暂停以及其它相关命令的信息,可以使用 window.speechSynthesis 属性来访问 SpeechSynthesis 控制器,从而获取语音合成功能的入口。
JS实现将文字转换为语音并自动播放
文章图片

或者省略 window,直接使用 speechSynthesis 也是可以的
JS实现将文字转换为语音并自动播放
文章图片

它有 paused、pending、speaking 三个属性,都是只读属性,不可修改。
它拥有的方法如下:
  • SpeechSynthesis.cancel():取消语音播放
  • SpeechSynthesis.getVoices():获取当前设备所有可用声音的 SpeechSynthesisVoice 列表。
  • SpeechSynthesis.pause() :暂停语音播放
  • SpeechSynthesis.resume() :恢复播放
  • SpeechSynthesis.speak() :添加语音到播放列队,将会在其他语音播放完后自动播放
2、SpeechSynthesisVoice
SpeechSynthesisVoice表示当前系统支持的语音资源,每一个 SpeechSynthesisVoice 都对应相关的语音服务,可以通过 SpeechSynthesis.getVoices() 获取语音列表,如下:
JS实现将文字转换为语音并自动播放
文章图片

它有5个只读的属性,分别为 default、lang、name、localService、voiceURI.
3、SpeechSynthesisUtterance
SpeechSynthesisUtterance 表示一次发音请求,其中包含了将由语音服务朗读的内容,以及如何朗读它(例如:语种、音高、音量)。
它有6个属性,分别如下:
  • lang:读取时的语言
  • pitch:声音的音高,取值0~2 ,正常音高为1
  • rate:读取的语速,取值0.1~10 ,正常语速值为1
  • text:要合成语音的文字内容
  • voice:读取文字的语音服务,默认为 SpeechSynthesisVoice的属性值为 default 的那个
  • volume:读取时声音的音量,取值0~1,正常音量为1
除了上面的属性外,还有7个事件方法,分别如下:
  • onboundary:当播放至一个词或句子结尾时触发
  • onend:语音播放结束时触发
  • onerror:语音播放错误时触发
  • onmark:当语音播放至 mark 标记时触发
  • onpause:暂停语音播放时触发
  • onresume:恢复语音播放时触发
  • onstart:开始语音播放时触发
关于SpeechSynthesisVoice的属性和方法,可以直接在 console 中查看,如下:
JS实现将文字转换为语音并自动播放
文章图片

4、语音合成代码
在了解了语音合成的相关对象后,下面来简单测试一下
let synth = window.speechSynthesis; let utterThis = new SpeechSynthesisUtterance('支付宝到账7.5元'); synth.speak(utterThis);

运行后,就可以听到语音了,这里使用 Chrome 浏览器测试的,语音听起来还可以。
下面给出一个比较通用的方法,具体实现的代码:
/** * @description 文字转语音方法 * @public * @param { text, rate, lang, volume, pitch } object * @paramtext 要合成的文字内容,字符串 * @paramrate 读取文字的语速 0.1~10正常1 * @paramlang 读取文字时的语言 * @paramvolume读取时声音的音量 0~1正常1 * @parampitch读取时声音的音高 0~2正常1 * @returns SpeechSynthesisUtterance */ function speak({ text, speechRate, lang, volume, pitch }, endEvent, startEvent) { if (!window.SpeechSynthesisUtterance) { console.warn('当前浏览器不支持文字转语音服务') return; }if (!text) { return; }const speechUtterance = new SpeechSynthesisUtterance(); speechUtterance.text = text; speechUtterance.rate = speechRate || 1; speechUtterance.lang = lang || 'zh-CN'; speechUtterance.volume = volume || 1; speechUtterance.pitch = pitch || 1; speechUtterance.onend = function() { endEvent && endEvent(); }; speechUtterance.onstart = function() { startEvent && startEvent(); }; speechSynthesis.speak(speechUtterance); return speechUtterance; }

测试一下
speak({ text: '微信到账100元' }, function() { console.log('语音播放结束'); }, function() { console.log('语音开始播放'); });

运行后,可以看到此时的 speechUtterance 实例如下:
JS实现将文字转换为语音并自动播放
文章图片

同时控制台会依次输出下面的信息
语音开始播放 语音播放结束

参考资料
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Speech_API
  • https://developer.mozilla.org/zh-CN/docs/Web/API/SpeechSynthesis
  • https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisVoice
  • https://developer.mozilla.org/zh-CN/docs/Web/API/SpeechSynthesisUtterance

    推荐阅读