voiceschanged event not fired in Safari
Asked Answered
C

1

4

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?

Coop answered 5/1, 2015 at 12:35 Comment(0)
M
8

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();
}
Memorabilia answered 29/1, 2015 at 14:34 Comment(3)
Thanks. I wish this was better documented somewhere. :/Coop
With this answer, we can select voice in Safari because only setting 'lang' was not enough. Thank you!Broome
it seems onvoiceschanged exists in speechsysnthesis but it never be calledCrosshatch

© 2022 - 2024 — McMap. All rights reserved.