前言
平时在做项目的过程中,有遇到场景是客户要求播放语音的场景,比如:无障碍朗读,整篇文章实现朗读,文字转语音,文字转语音播放等等。
在不使用第三方API
接口的情况下,这里需要js
来实现文字转语音播放的功能。能想到的也就是利用html5
的个API
:SpeechSynthesis
。
SpeechSynthesis
用于将指定文字合成为对应的语音.也包含一些配置项,指定如何去阅读(语言,音量,音调)等等
SpeechSynthesis实例对象属性
-
lang
获取并设置话语的语言 -
pitch
获取并设置话语的音调(值越大越尖锐,越低越低沉) -
rate
获取并设置说话的速度(值越大语速越快,越小语速越慢) -
text
获取并设置说话时的文本 -
voice
获取并设置说话的声音 -
volume
获取并设置说话的音量
SpeechSynthesis方法
-
speak()
将对应的实例添加到语音队列中 -
cancel()
删除队列中所有的语音.如果正在播放,则直接停止 -
pause()
暂停语音 -
resume()
恢复暂停的语音 -
getVoices
获取支持的语言数组. 注意:必须添加在voiceschanged
事件中才能生效
实例对象中的方法
onstart
-- 语音合成开始时候的回调。onpause
-- 语音合成暂停时候的回调。onresume
-- 语音合成重新开始时候的回调。onend
-- 语音合成结束时候的回调
简单实现
如果想让浏览器读出"书以启智,技于谋生,活出斜杠"的声音,可以下面的js代码:
js
let utterThis = new SpeechSynthesisUtterance('书以启智,技于谋生,活出斜杠');
speechSynthesis.speak(utterThis);
实现这个语音朗读,需要用构造器函数SpeechSynthesisUtterance
方法,实例对象下,调用speak
方法,即可实现语音的播报
除了使用speak
方法,我们还可以实例对象属性text
,因此上面的代码也可以写成
js
let utterThis = new SpeechSynthesisUtterance();
utterThis.text = '书以启智,技于谋生,活出斜杠';
utterThis.lang = 'en-US';//汉语
utterThis.rate = 0.7;//语速
speechSynthesis.speak(utterThis);
具体实例代码
html
<template>
<div class="speech-wrap">
<div>
<span class="demonstration">音量</span>
<el-slider @input="handleVoinceInput" v-model="voinceValue" vertical height="200px"></el-slider>
</div>
<div>
<el-input class="inseret-input" clearable placeholder="请输入内容" v-model="input"></el-input>
<el-select @change="handleSelectChange" v-model="selectVal" slot="prepend" placeholder="请选择语言">
<el-option label="zh-CN" value="zh-CN"></el-option>
<el-option label="en-US" value="en-US"></el-option>
</el-select>
<el-button slot="append" @click="handleTransYuYin">转语音</el-button>
<el-button @click="handleStopYuYin">暂停</el-button>
<el-button @click="handleHuiFuYuYin">恢复</el-button>
</div>
</div>
</template>
<script>
export default {
name: 'speechSynthesisUtterance',
data() {
return {
input: '书以启智,技于谋生,活出斜杠',
voinceValue: 30,
selectVal: 'zh-CN',
}
},
methods: {
handleTransYuYin() {
if(this.input) {
let msg = new SpeechSynthesisUtterance(this.input);
msg.volume = this.voinceValue;
msg.rate = this.voinceValue;
msg.pitch = this.voinceValue;
this.throttle(window.speechSynthesis.speak(msg),2000);
}else {
this.$message.error('输入框内容不能为空');
}
},
handleVoinceInput(val) {
this.voinceValue = val;
},
handleSelectChange(val) {
this.selectVal = val;
},
handleStopYuYin() {
window.speechSynthesis.pause();
},
handleHuiFuYuYin() {
window.speechSynthesis.resume();
},
throttle(fn,delay) {
let last = 0
return function() {
const now = new Date()
if(now - last > delay) {
fn.apply(this,arguments)
last = now
}
}
}
}
}
</script>
<style scoped>
.speech-wrap {
display:flex;
justify-content:start;
align-items: center;
}
.speech-wrap .inseret-input {
width: 400px;
}
</style>
window.speechSynthesis
来创建语音,xxx.volume
获取并设置说话的音量,xxx.rate
获取并设置说话的速度(值越大语速越快,越小语速越慢),xxx.pitch
获取并设置话语的音调(值越大越尖锐,越低越低沉)
window.speechSynthesis.speak(msg)
播放语音,msg
是一个SpeechSynthesisUtterance
对象,msg.text
设置要播放的话, msg.lang
设置语言,msg.volume
设置音量,msg.rate
设置语速,msg.pitch
设置音调
上面使用了throttle
函数来限制播放的频率,防止播放过快,导致浏览器卡顿
如果不使用接口的方式,在项目中加入文本转语音,可以用这种方式实现,但是要注意兼容性问题,这个API是不兼容IE浏览器的