H5的API:
功能: 支持间隔特定时间播放(这里的坑是,无法预判播放语音要多久,所以间隔特定时间播放功能,不能定时调用speak,需要根据utterance的状态,在结束时调用speak)
useTextToVoice:
js
import { message } from 'ant-design-vue';
const useTextToVoice = (gap = 1000, voiceType = 0) => {
const synth = window.speechSynthesis;
const voices = synth.getVoices();
const utteranceQueue = []; // 待播报文本队列
const checkVoiceSupport = () => {
const isSupport = 'speechSynthesis' in window;
if (!isSupport) {
message.warn('您的浏览器不支持文本转语音功能。请更换浏览器或者升级浏览器版本。');
}
return isSupport;
};
const speak = (text) => {
if (!checkVoiceSupport()) return;
const utterance = new SpeechSynthesisUtterance(text);
utterance.voice = voices[voiceType];
// 如果有待播报的文本或者正在播报中,将文本添加到队列中
if (synth.pending || synth.speaking) {
utteranceQueue.push(text);
} else {
synth.speak(utterance);
}
utterance.onend = () => {
console.log('speak end');
// 检查队列中是否还有待播报的文本
if (utteranceQueue.length > 0) {
const nextText = utteranceQueue.shift();
setTimeout(() => speak(nextText), gap);
}
};
};
return { speak };
};
export default useTextToVoice;
使用
scss
const { speak } = useTextToVoice(2000);
直接调用speak()传入文本就好啦~
接口
还有另一种方式,使用接口,觉得要构建audio标签有点麻烦,没采用
隐藏问题
这里有个坑,就是浏览器出于避免打扰用户,做了安全机制限制了需要用户与界面有一定交互才可以自动播放,目前可以实现自动播放的方案:
- 播放次数多了,浏览器安全值提高则会自动播放。
- 打开浏览器的安全设置,解除当前网站的播放限制(需要能拿到用户设备,手动设置,最后我们采用了这个)。
- 模仿爱奇艺等视频网站,提供静音按钮让用户解除静音。
- iframe(没试过,因为我们的需求是动态的播放内容,用文字转语音方案,没有现成的音频文件,所以没用到audio标签)
自动点击是不生效的,自动点击需要等手动点击之后才生效。不生效的原因是 浏览器内置了isTrusted
变量,这个变量只有等用户操作后才会变成true,自动点击事件才会生效。 也是出于安全考虑。
MDN文档如下:
Event接口的isTrusted是一个Boolean类型的只读属性.当事件由用户操作生成时为true,由脚本创建或修改,或通过调用EventTarget.dispatchEvent生成,为false