javascripttext-to-speechvoicespeech-synthesis

SpeechSynthesis API's getVoices method not working properly (returning EMPTY array)


When I was using the speechSynthesis API, I came across a problem when I attempted to change the voice of the speech utterance from the default voice.

I used the following code:

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
    
msg.voice = voices[2];
msg.text = "Hello World!";
speechSynthesis.speak(msg);

The above code was supposed to change the voice to "Microsoft Linda - English (Canada)", but it did NOT do this. However, when I executed the code directly in the developer console, the voice setting actually worked.

So, to investigate this, I checked the contents of the array that getVoices() returned, by doing this:

console.log(window.speechSynthesis.getVoices());

When I added this code in my HTML file, an empty array was printed.
When I executed this code directly in the developer console, the intended array was printed.

Why does this happen and how can I fix my code accordingly, such that I can change the voice property of the SpeechSynthesisUtterance object, without having to run the code directly in the developer's console?

Help would be very much appreciated.


Solution

  • I have found the solution to the issue. Apparently, getVoices() returned an empty array in the HTML file, because the program was invoking it before the voices loaded. So, I attached an onvoiceschanged event listener to speechSynthesis, which invokes the speech code, so that the speech code runs after the voices are loaded. This effectively worked and properly changed the voice.

    Here is the final code:

    var msg = new SpeechSynthesisUtterance();
        
    speechSynthesis.addEventListener("voiceschanged", () => {
        var voices = window.speechSynthesis.getVoices();
            
        msg.voice = voices[2];
        msg.text = "Hello World!";
        speechSynthesis.speak(msg);
    });
    

    Therefore, the reason the original code worked in the developer's console is because the voices were already loaded there.