前两天接到一个需求,要求web端能到接收到后台实时推送的告警信息,并进行语音播报,what?这是什么黑科技,我第一反应是做不到...问了一下同事才知道,这个功能可以有,语音合成api了结一下.
官方文档:developer.mozilla.org/en-US/docs/…
语音合成,顾名思义,就是可以将文字转换为语音,恕我孤陋寡闻,第一次知道这种黑科技.看了一下文档,其实很简单.示例demo如下:
let windowSpeech = new window.SpeechSynthesisUtterance('hello world!');
window.speechSynthesis.speak(windowSpeech);
将上面的代码复制到控制台就可以听到电脑的播放音了.(如果你发现没有播放出声音,那有可能window版本有问题,不是完全版的,tts引擎没有安装,可以百度一下补丁包自行安装一下)这段功能的核心主要有两个对象SpeechSynthesisUtterance
和speechSynthesis
.
1.SpeechSynthesisUtterance对象
主要用来构建语音合成实例,例如上面代码中的实例对象windowSpeech。我们可以直接在构建的时候就把要读的文字内容写进去,也可以通过text属性设置要读的内容.SpeechSynthesisUtterance对象属性如下:
属性
text: 要合成的文字内容,字符串。
lang: 使用的语言,字符串, 例如:"zh-cn"
voiceURI: 指定希望使用的声音和服务,字符串。
volume: 声音的音量,区间范围是0到1,默认是1。
rate: 语速,数值,默认值是1,范围是0.1到10,表示语速的倍数,例如2表示正常语速的两倍。
pitch: 表示说话的音高,数值,范围从0(最小)到2(最大)。默认值为1。
事件:
onstart: 语音合成开始时候的回调。
onpause: 语音合成暂停时候的回调。
onresume: 语音合成重新开始时候的回调。
onend: 语音合成结束时候的回调。
2.speechSynthesis对象
主要作用是触发行为,例如读,停,还原等,可以控制语音合成的播放过程.
speak(): 只能接收SpeechSynthesisUtterance作为唯一的参数,作用是读合成的话语。
stop(): 立即终止合成过程。
pause(): 暂停合成过程。
resume(): 重新开始合成过程。
getVoices: 此方法不接受任何参数,用来返回浏览器支持的语音包列表,是个数组.
3.在vue项目中使用:
为了测试上文两个核心对象的功能,写了一个demo.主要实现了列表循环播放,逐条播放,以及播放的暂停,重新开始等功能.
效果图:
代码如下:
<template>
<div class="window-speech">
<div class="button-box">
<span class="button" @click="allPlay">循环播放</span>
<span class="button" @click="go_erasure">消音</span>
</div>
<div class="list-box">
<div v-for="(item) in speechList" :key="item.index" :class="activeIndex == item.index?'red':''">
<span>{{item.text}}</span>
<span class="button" @click="onePlay(item)" v-if="item.status === 0">播放</span>
<span class="button" @click="onePause(item)" v-if="item.status === 1">暂停</span>
<span class="button" @click="oneContinue(item)" v-if="item.status === 2">继续 </span>
</div>
</div>
</div>
</template>
<script>
export default {
name:'windowSpeech',
data(){
return {
speechList:[ // 0 停止 1 播放中 2 暂停中
{text:'测试报警声音001', index:0, status:0},
{text:'测试报警声音002', index:1, status:0},
{text:'测试报警声音003', index:2, status:0},
{text:'测试报警声音004', index:3, status:0},
{text:'测试报警声音005', index:4, status:0},
{text:'测试报警声音006', index:5, status:0},
{text:'测试报警声音007', index:6, status:0},
{text:'测试报警声音008', index:7, status:0},
{text:'测试报警声音009', index:8, status:0},
],
activeIndex: -1,
windowMsg:null,
windowSpeech:null,
playFlag: true,
}
},
mounted(){
this.windowMsg = new window.SpeechSynthesisUtterance()
this.windowSpeech = window.speechSynthesis
},
methods:{
onePause(data){
console.log('暂停')
this.windowSpeech.pause()
},
oneContinue(data){
console.log('继续')
this.windowSpeech.resume()
},
onePlay(data){
console.log('bofang')
this.playFlag = true;
this.circleFlag = false;
this.play(data);
},
play(data){
if(!this.playFlag){
console.log('消音了')
this.windowSpeech.cancel();
return
}
if(!this.windowMsg || !this.windowSpeech ){
this.windowMsg = new window.SpeechSynthesisUtterance();
this.windowSpeech = window.speechSynthesis
}
this.windowMsg.text = data.text;
this.windowMsg.volume = 1;
this.windowMsg.voiceURI = 'Google 普通话(中国大陆)';
console.log(this.windowMsg,'this.windowMsg')
console.log(this.windowSpeech,'this.windowMsg')
this.windowMsg.onstart = ()=>{
console.log('开始合成')
this.activeIndex = data.index;
this.speechList[data.index].status = 1;
}
this.windowMsg.onerror = (e)=>{
console.log('出问题了',e)
this.speechList[data.index].status = 0;
}
this.windowMsg.onend = ()=>{
if(this.circleFlag){
console.log('播放完成一条',this.activeIndex)
this.activeIndex++
if(this.activeIndex == this.speechList.length){
this.activeIndex = 0;
}
this.play(this.speechList[this.activeIndex])
}else{
this.activeIndex = -1;
}
this.speechList[data.index].status = 0;
}
this.windowMsg.onresume = () => {
this.speechList[data.index].status = 1;
}
this.windowMsg.onpause = (e) => {
console.log('暂停',e)
this.speechList[data.index].status = 2;
}
this.windowSpeech.speak(this.windowMsg);
},
allPlay(){
this.circleFlag = true;
this.activeIndex = 0;
this.play(this.speechList[this.activeIndex])
},
go_erasure(){
this.playFlag = false;
this.$message.success('消音成功')
}
}
}
</script>
<style lang="less" scoped>
.window-speech{
width: 60%;
margin: auto;
.button{
display: inline-block;
line-height: 40px;
cursor: pointer;
margin: 0 10px;
}
.button-box{
}
.list-box{
.red{
color: red;
}
}
}
</style>
git地址:github.com/aicai0/test…
如有问题,欢迎探讨,如果满意,请手动点赞,谢谢!🙏
及时获取更多姿势,请您关注!!