我正在尝试使用Speechsynthesis的简单示例。
<script>
voices = window.speechSynthesis.getVoices()
var utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[4];
utterance.lang = voices[4].lang;
window.speechSynthesis.speak(utterance);
</script>
但这会产生错误,声音未定义。我发现getVoices()是异步加载的。我看到this回答并更新了我的代码,如下所示使用回调。
<script>
window.speechSynthesis.onvoiceschanged = function() {
voices = window.speechSynthesis.getVoices()
var utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[4];
utterance.lang = voices[4].lang;
window.speechSynthesis.speak(utterance);
};
</script>
但是由于一些奇怪的原因,文本被说了三次而不是一次。我该如何修复此代码?
答案 0 :(得分:3)
我无法复制您的问题,但尝试添加一个事件监听器,以便在加载语音后运行您的函数。
let voices, utterance;
function speakVoice() {
voices = this.getVoices();
utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[1];
speechSynthesis.speak(utterance);
};
speechSynthesis.addEventListener('voiceschanged', speakVoice);
答案 1 :(得分:3)
这可以在许多JS Bin类型的演示中看到。例如:
http://jsbin.com/sazuca/1/edit?html,css,js,output
https://codepen.io/matt-west/pen/wGzuJ
在使用非本地语音时,Chrome会使用voiceschanged事件。另一个影响是声音列表通常是三重的。
W3C规范说:
voiceschanged event
当内容被解雇时 将返回getVoices方法将返回的SpeechSynthesisVoiceList 改变。示例包括:列表所在的服务器端综合 异步确定,或客户端声音时 安装/卸载强>
...所以我认为当Chrome获得声音时会触发一次事件,而当使用第一个非本地声音时则会触发两次。
鉴于似乎没有办法区分哪个更改正在触发事件,我一直在使用这个丑陋的代码:
// Add voices to dropdown list
loadVoices();
// For browsers that use voiceschanged event
speechSynthesis.onvoiceschanged = function(e) {
// Load the voices into the dropdown
loadVoices();
// Don't add more options when voiceschanged again
speechSynthesis.onvoiceschanged = null;
}
其中loadVoices()是将声音添加到选择选项的功能。它并不理想,但它适用于所有浏览器(使用语音合成),无论是否使用onvoices。
答案 2 :(得分:-1)
您可以简单地添加此代码并在项目中使用SpeechSynthesis,它适用于我。
var su;
su = new SpeechSynthesisUtterance();
su.text = "Hello World";
speechSynthesis.speak(su);
speechSynthesis.cancel();