前言
平时在做项目的过程中,有遇到场景是客户要求播放语音的场景,比如:无障碍朗读,整篇文章朗读,文字转语音,文字转语音播放等等。
在不使用第三方`API`接口的情况下,这里需要`js`来实现文字转语音播放的功能。能想到的也就是利用html5
的个API
:SpeechSynthesis
。
SpeechSynthesis
用于将指定文字合成为对应的语音.也包含一些配置项,指定如何去阅读(语言,音量,音调)等等
实例对象属性
1. lang
获取并设置话语的语言
2. pitch
获取并设置话语的音调(值越大越尖锐,越低越低沉)
3. rate
获取并设置说话的速度(值越大语速越快,越小语速越慢)
4. text
获取并设置说话时的文本
5. voice
获取并设置说话的声音
6. volume
获取并设置说话的音量
SpeechSynthesis方法
1. speak()
将对应的实例添加到语音队列中
2. cancel()
删除队列中所有的语音.如果正在播放,则直接停止
3. pause()
暂停语音
4. resume()
恢复暂停的语音
5. getVoices
获取支持的语言数组. 注意:必须添加在voiceschanged
事件中才能生效
实例对象中的方法
1. onstart–
语音合成开始时候的回调。
2. onpause
– 语音合成暂停时候的回调。
3. onresume
– 语音合成重新开始时候的回调。
4. onend
– 语音合成结束时候的回调
简单实现
如果想让浏览器读出“书以启智,技于谋生,活出斜杠”的声音,可以下面的js代码:
let utterThis = new SpeechSynthesisUtterance('书以启智,技于谋生,活出斜杠');
speechSynthesis.speak(utterThis);
实现这个语音朗读,需要用构造器函数SpeechSynthesisUtterance
方法,实例对象下,调用speak
方法,即可实现语音的播报
除了使用speak
方法,我们还可以实例对象属性text
,因此上面的代码也可以写成
let utterThis = new SpeechSynthesisUtterance();
utterThis.text = '书以启智,技于谋生,活出斜杠';
utterThis.lang = 'en-US';//汉语
utterThis.rate = 0.7;//语速
speechSynthesis.speak(utterThis);
实例代码
<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
函数来限制播放的频率,防止播放过快,导致浏览器卡顿