How to change voice in Speech Synthesis?

懵懂的女人 提交于 2020-01-24 11:18:08

问题


I am trying out a simple example with 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>

But this gives an error that voices is undefined. I found that getVoices() is loaded async. I saw this answer and updated my code as shown below to use callback.

<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>

But due to some strange reason, the text is spoken three times instead of one. How can I fix this code?


回答1:


I can't replicate your issue, but try adding an event listener so that your function runs after the voices are loaded.

let voices, utterance;

function speakVoice() {
voices = this.getVoices();
utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[1];
speechSynthesis.speak(utterance);
};

speechSynthesis.addEventListener('voiceschanged', speakVoice);



回答2:


This can be seen on many JS Bin-type demos. For examples:

http://jsbin.com/sazuca/1/edit?html,css,js,output

https://codepen.io/matt-west/pen/wGzuJ

This behaviour is seen in Chrome, which uses the voiceschanged event, when a non-local voice is used. Another effect is that the list of voices is often triplicated.

The W3C specification says:

voiceschanged event

Fired when the contents of the SpeechSynthesisVoiceList, that the getVoices method will return, have changed. Examples include: server-side synthesis where the list is determined asynchronously, or when client-side voices are installed/uninstalled.

...so I presume that the event is fired once when Chrome gets the voices and then twice more when the first non-local voice is used.

Given that there doesn't seem to be a way to distinguish which change is triggering the event I have been using this ugly bit of code:

    // 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;
    }

Where loadVoices() is the function that adds the voices to a selection's options. It's not ideal, however it does work on all browsers (with speech synthesis) whether they use onvoiceschanged or not.




回答3:


You can simply add this code and use SpeechSynthesis in your project, it works for me.

var su;

su = new SpeechSynthesisUtterance();

su.text = "Hello World";

speechSynthesis.speak(su);

speechSynthesis.cancel();


来源:https://stackoverflow.com/questions/42694586/how-to-change-voice-in-speech-synthesis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!