浏览器实现语音合成

应用场景

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

当需要系统自动播报收款的金额,其中付款金额是不固定时或者车辆平台需要播报预警等等

如果是相对固定的场景,并且语音有限的情况下,可以采用录制的方式,即先录制好所有的音频资源,然后根据业务场景播放相应的音频即可;但是如果场景不固定,需要的语音也不一样时,采用录制的方式的话,音频资源将会非常多,而且还可能会出现不全的问题,那么这个时候利用语音合成技术是一个较好的办法,即实时将文字转换成语音。

目前文字转语音即语音合成技术现在已经很成熟了,像百度、讯飞等都提供了相关的服务,支持将文字转换成各种形式的语音,通常这些服务都需要付费使用,如果对语音要求不高,并且又想节约成本,那么可以直接使用浏览器的语音合成功能。

语音合成主要涉及到两个对象:SpeechSynthesisSpeechSynthesisUtterance

SpeechSynthesis语言合成

SpeechSynthesis 接口是语音服务的控制接口;它可以用于获取设备上关于可用的合成声音的信息,开始、暂停语音,或除此之外的其他命令

实例属性
属性解释
paused当处于暂停状态时值返回true
pending当语音播放队列到目前为止保持没有说完的语音时为true
speaking当语音谈话正在进行的时候为true

注:这个三个属性都是只读,不可进行修改 改变状态需要用到以下几个方法

实例方法
方法解释
cancel移除所有语音谈话队列中的谈话。
pause把对象置为暂停状态
resume把对象置为一个非暂停状态:如果已经暂停了则继续
getVoices返回当前设备所有可用声音的
speak添加一个语音谈话队列中

example
let synthesis=window.speechSynthesis
​
// 暂停
pause() {
   synthesis.pause();
}
// 继续播放
resume() {
    synthesis.resume();
}
// 移除所有语音
//添加新的语音时,如果需要立即播放刚添加的语音需要先清空语音队列否则还是会把队列存在的语音播放完在播放刚添加的
cancel() {
    synthesis.cancel();
}
// 取消播放
cancel() {
    synthesis.cancel();
}
// 获取系统可用的语音列表
getVoices() {
   synthesis.getVoices();
}
// 添加一个语音到队列中
const utterance = new SpeechSynthesisUtterance(
  "浏览器实现语音合成",
);
speak() {
   synthesis.speak(utterance);
}

SpeechSynthesisUtterance语音合成话语

SpeechSynthesisUtterance是HTML5中新增的API,用于将指定文字合成为对应的语音.也包含一些配置项,指定如何去阅读(语言,音量,音调)等

实例属性
属性解释
pitch获取并设置话语的音调(值越大越尖锐,越低越低沉)
rate获取并设置说话的速度(值越大语速越快,越小语速越慢)
volume获取并设置说话的音量
lang获取并设置播放语言类型
text获取并设置语音播放内容
voice获取并设置说话的声音

example
let speech = new SpeechSynthesisUtterance();
​
speech.pitch = 1; // 获取并设置话语的音调(值越大越尖锐,越低越低沉)
​
speech.rate = 1.5; // 获取并设置说话的速度(值越大语速越快,越小语速越慢)
​
speech.volume = 10; // 获取并设置说话的音量
​
speech.lang = "zh-CN"; // 设置播放语言(如果设置了voice会有先使用voice对象中的lang)
​
speech.voice = "ZhangJing"; // 获取并设置说话的声音
​
speech.text = text   //文字或者SSML语音标签
​

实例事件
事件解释
onboundary在语音语句达到单词或句子边界时触发
onend在语音结束时触发
onerror当发生阻止成功朗读语句的错误时触发
onmark语音标记事件 结合ssml标签语言中mark使用
onpause在话语中途暂停时触发
onresume在语音恢复播放时触发
onstart在开始说出话语时触发

example
let speech = new SpeechSynthesisUtterance();
// 语音播报边界
speech.onboundary = () => {
    //中英文监听不一致
    //eg: how are you  触发四次
    //    这是一段语音播放  触发六次
    // console.log("语音播报边界")
}
// 错误语音播报事件
speech.onerror = () => {
    // console.log("错误语音播报事件")
}
// 标记语音播报事件
speech.onmark = () => {
    // 结合ssml语音标签测试发现没有效果   可能是azure废弃了bookmark
    // console.log("标记语音播报事件")
}
// 语音开始播报
speech.onstart = () => {
    // console.log("语音开始播报")
}
// 语音暂停播报
speech.onpause = () => {
    // console.log("语音暂停播报")
}
// 语音恢复播报
speech.onresume = () => {
    // console.log("语音恢复播报")
}
// 语音结束播报
speech.onend = () => {
    // console.log("语音播报结束")
}
​

遇到的一些问题

1.为什么SpeechSynthesis不能在直接Chrome上播放语音

Chrome浏览器在18年4月起,全面禁止了音视频的自动播放功能。从Chrome 66开始,限制了video和audio元素的自动播放,从Chrome 71开始,还限制了Web Audio API的自动播放。

<html>
    <head>
    </head>
    <body>
            if ( 'speechSynthesis' in window ) {
                var to_speak = new SpeechSynthesisUtterance('Hello world!');
                window.speechSynthesis.speak(to_speak);
            } else {
                alert('not support ');
            }
        </script>
    </body>
</html>

a.问题原因是Chrome自动播放策略始不允许自动播放需要用户交互才能够允许播放

<form>
  <input type='text' id="input"></input>
  <select id='voiceSelect'></select>
  <button type="button" id="button">Speak</button>
</form>
​
​
​
button.addEventListener('click', () => {
  if ( 'speechSynthesis' in window ) {
    const to_speak = new SpeechSynthesisUtterance(input.value || 'Hello world!');
    speechSynthesis.cancel();
    speechSynthesis.speak(to_speak);
  } else {
    alert('not supported');
  }
});

b.进行chrome浏览器设置,右击chrome快捷图标-->属性-->快捷方式-->目标加入"--autoplay-policy=no-user-gesture-required"

2.为什么直接获取语音列表为空,这是因为允许使用远程服务器进行语音合成,而SpeechSynthesis向服务器请求语音列表。 要解决此问题,需要等待语音将被加载,然后再次请求它们

a.官网的做法speechSynthesis.onvoiceschanged ,当由SpeechSynthesis.getVoices()方法返回的SpeechSynthesisVoice列表改变时触发

    if (speechSynthesis.onvoiceschanged !== undefined) {
      speechSynthesis.onvoiceschanged = getVoices()   //获取语音列表的方法
    }

b.延时获取语音列表

    setTimeout(()=>{
    seepchSynthesis.getVoices()
    },10)

3.speechSynthesis.getVoice()获取的语音列表为什么有些语音不能够正常播放

a.因为获取的语音列表大部分是远程异步服务,不能播放的因素有网络宽带或需要支付费用才能使用,本地可使用的音频localService==true

参考文献

1.语音合成 - 网络接口 |多核 (mozilla.orghttps://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis)

2.SpeechSynthesisUtterance - Web APIs | MDN (mozilla.org)https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance

3.不起作用_SpeechSynthesis.speak 在 chrome 中不起作用_IT常识

JavaScript中文语音合成是指使用JavaScript语言编写代码来实现将文字转换成中文语音的功能。这种技术可以让网页或应用程序能够通过声音的方式传递信息,提供更好的用户体验。 在JavaScript中实现中文语音合成可以通过调用浏览器的Web Speech API来实现。Web Speech API提供了SpeechSynthesis接口,该接口提供了一些方法和事件,用于控制和监控语音合成的过程。 首先,可以使用SpeechSynthesis接口的getVoices()方法获取可用的语音合成引擎。接着,可以通过调用SpeechSynthesisUtterance()构造函数创建一个新的语音合成实例。然后,可以设置要转换的文字内容,以及其他参数,如音量、语速等。最后,调用SpeechSynthesis接口的speak()方法,即可将文字转换成中文语音,并播放出来。 通过JavaScript中文语音合成,我们可以轻松地实现网页上的文字转语音功能,为用户提供更加丰富的交互体验。例如,可以在网页中添加一个按钮,让用户点击后将网页内容转换成语音,方便用户无需阅读时获取信息。此外,还可以将语音与其他功能结合起来,如语音导航、语音播报等,提升应用程序的便利性。 需要注意的是,由于Web Speech API是浏览器提供的功能,不同浏览器对API的支持程度可能会有所不同。因此,在使用JavaScript中文语音合成时,最好进行浏览器兼容性的考虑,以确保功能在不同浏览器中正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值