Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

voiceschanged event not fired in Safari

As far as I can tell, the voiceschanged event doesn't fire in Safari, either on macs or in iOS. Also odd, it doesn't seem to fire in Chrome on iOS either, but I'm assuming Chrome on iOS uses the same JavaScript engine as Safari.

Here's a demonstration that I used to verify: http://jsbin.com/gosaqihi/9/edit?js,console (taken from Getting the list of voices in speechSynthesis of Chrome (Web Speech API))

I've also tried it using addEventListener:

speechSynthesis.addEventListener("voiceschanged", function () {
    var voices = speechSynthesis.getVoices(),
        keys = Object.keys(voices[0]),
        i, j;

    document.write("<table border=1><tr>");

    for ( i = 0; i < keys.length; i++ ) {
        document.write("<td>" + keys[i] + "</td>");
    }

    document.write("</tr>");

    for ( i = 0; i < voices.length; i++ ) {
        document.write("</tr>");
        for ( j = 0; j < keys.length; j++ ) {
            document.write("<td>" + voices[i][keys[j]] + "</td>");
        }
        document.write("</tr>");
    }

    document.write("<table>");
}, false);

Both approaches (onvoiceschanged, addEventListener) work fine in Chrome for Windows, Android, and Mac, but fail on Chrome for iOS and Safari for Mac and iOS. As far as I can tell, Safari simply doesn't fire the voiceschanged event.

Complicating things, I don't actually own any Apple devices, so I've had to figure this out by having friends try things.

Is there something special I need to do in Safari to get the list of voices? Or is the Speech Synthesis API simply not (fully) implemented yet?

like image 424
Asmor Avatar asked Mar 18 '23 11:03

Asmor


1 Answers

Apparently Safari only has partial support for the Web Speech API so far.

What you could do for your code to work in different environments is to detect if onvoiceschanged exists in speechSynthesis. If not, you can just call speechSynthesis.getVoices() without listening for onvoiceschanged.

function doVoices() {
    var voices = speechSynthesis.getVoices(),
    // ...
}

if ('onvoiceschanged' in speechSynthesis) {
    speechSynthesis.onvoiceschanged = doVoices;
} else {
    doVoices();
}
like image 174
Sarah Elan Avatar answered Mar 23 '23 00:03

Sarah Elan