现在很多高端的浏览器已经支持SpeechSynthesisUtterance和speechSynthesis,这两个API是浏览器给我们提供的语音合成对象。
使用方法也很简单,具体详细方法可以在网上找到用法。
最简单的用法:
let speakRole = new SpeechSynthesisUtterance('微信到帐1000元');
window.speechSynthesis.speak(speakRole);
这样你的网页就可以发出声音了,这都是在你的浏览器支持的情况下才有效果,但目前情况下,还有很多浏览器是不支持该功能的。
在浏览器不支持的情况下,我这里使用百度提供的语音合成技术。
详细文档可以查看https://cloud.baidu.com/。
百度语音合成接口为:
https://tsn.baidu.com/text2audio?tex=***&lan=zh&cuid=***&ctp=1&tok=***
这是接口必填的5个参数,其中cuid和tok是隐私数据,如果像上面直接调用的话,隐私数据就会直接暴露出来,相当于你把帐号和密码直接告诉了别人。这不是百度推荐的方式,但这个是最方便的方式。
幸好我的服务器支持反现代理,可以将接口中的隐私数据隐藏起来:
location /_BaiDuSpeak/ {
valid_referers server_names *.0513.city;
if ($invalid_referer) {
return 403;
}
set $args "$args&tok=保密&cuid=保密&ctp=1&lan=zh&ie=UTF-8";
proxy_pass https://tsn.baidu.com/text2audio;
}
这里我使用_BaiDuSpeak代替了原本的隐私数据,valid_referers server_names *.0513.city; 表示_BaiDuSpeak只能在本服务器使用,其他地方调用都是返回403状态。
为了美观,单独可以为403设计一个错误提示页面,配置如下,地址是相对于网站根目录:
error_page 403 /error/403.html;
现在开始调用接口,具体思路,一边代码一代注释。
/**
* 调用语音合成
* 作者:顾永胜
* 简单实例,还有很多不足
*/
var speak = (function () {
var curDom = null; //当前正在播报的节点
var speakRole = null; //谙音对象Audio或SpeechSynthesisUtterance
function textToSpeak(text, o) {
if ("SpeechSynthesisUtterance" in window) {
windowSpeak(text); //浏览器播报
} else {
baiDuSpeak(text, o); //接口播报
}
}
function windowSpeak(text) {
window.speechSynthesis.cancel();
speakRole.text = text;
window.speechSynthesis.speak(speakRole);
//浏览器的播报现在只能点一次重头播放,没有暂停和继续播放
}
function baiDuSpeak(text, o) {
//多次点击,如果节点没有变,就开启暂停或继续播放,如果改变重新合成新语音
if (curDom != o) {
//调用接口
speakRole.src = "/_BaiDuSpeak/?tex=" + encodeURI(encodeURI(text)); //text是要播报的内容
speakRole.play();
curDom = o;
} else {
//暂停和继续播放
speakRole.paused ? speakRole.play() : speakRole.pause();
}
}
function _init(obj) {
//初始化,找到所用需要语音播报的节点
const dom = document.querySelectorAll(obj);
if (dom.length) {
if ("SpeechSynthesisUtterance" in window) {
speakRole = new SpeechSynthesisUtterance();
} else {
speakRole = new Audio();
// speakRole.addEventListener("ended", () => {
// //调用事件,播报结束后
// // curDom = null;
// });
}
//为每个节点后面加一个小耳机图标
dom.forEach((e) => {
let a = document.createElement("a");
let img = document.createElement("img");
let text = e.innerText;
a.href = "javascript:void(0)";
a.addEventListener("click", () => {
//点击小耳机开始播报
textToSpeak(text, e);
});
img.src = "/images/headset.svg";
a.appendChild(img);
e.appendChild(a);
});
}
}
return {
init: _init,
};
})();
调用的时候,先导入脚本,然后speak.init('节点类名');
实际运用,可以参考本网站生活日记里的文章,https://0513.city/blog/thought/146.html点小耳机试听。