SpeechSynthesis.getVoices() not listing voices in Firefox
Asked Answered
B

5

10

I am developing an application that requires me to use text to speech in the web browser. I am using the HTML5 Speech Synthesis for it. On Google Chrome the code runs fine, with all the available voices being listed using |getVoices()|, but in Firefox no voice is listed at all. I am testing my code on Firefox 56.0 (Ubuntu).

On searching over the internet, I did come across a StackOverflow answer that suggested that the getVoices() function should be called after the |onVoiceChanged| event

    window.speechSynthesis.onvoiceschanged = function() {
    window.speechSynthesis.getVoices();
    ... 
};

I am invoking the call in the above mentioned manner and it works as desired in Chrome, but not on Firefox.

Another StackOverflow answer suggested that I enable the |media.webspeech.synth.enabled| in about:config of Firefox, but in my Firefox the preference |media.webspeech.synth.enabled| is already set to true.

I checked the MDN documentation https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis/getVoices and the example on this page does not run for me in Firefox, but runs fine in Chrome. I found that CanIUse.com lists that SpeechSynthesis as supported in Firefox 55 onwards, but it does not work for me.

Also The demo by Mozilla Developer Network to demonstrate the Speech Synthesis fails to work on my Firefox, but runs fine on Google Chrome. I have extensively searched online for a solution but could not find one. Can someone please point me in the right direction here.

Blazon answered 7/10, 2017 at 6:28 Comment(5)
The demo works for me in Fx ESR 53.3.0 and current 56, on Win 10Flann
Do you call .getVoices() outside of onvoiceschanged event handler?Ejective
doesnt work for me in ff90 on manjaroImperceptive
As explained in my downvoted comment, you need to install a speech synthesizer and speech-dispatcher on Linux. Windows ships with one by default so it doesn't require that.Diphase
broken in manjaro tooImperceptive
P
2

Ran into the same issue and here's what I figured out.

  • Doesn't work for me on Firefox Ubuntu 16.04
  • On virtualbox Windows works. The voices come from Windows. "Microsoft David" is one of the choices.
  • Chrome works on Ubuntu, but only when it's online. It's not showing any traffic in the console, but the voice only works when it is online!
Parnas answered 20/1, 2018 at 5:56 Comment(0)
S
1

I'm running FireFox 58.0.2 (64-bit) under Windows 7 64 bit pro. The demo you mention does list one voice for me: Microsoft Anna - English (United States) (en-US). This voice is furnished by my Windows OS, not FireFox (Chrome lists 19 additional voices which are included with Chrome).

The reason your code works in Chrome but not Firefox is that Firefox doesn't invoke speechSynthesis.onvoiceschanged and Chrome does.

Why? Here is Mozilla's description of the voiceschanged event:

The voiceschanged event of the Web Speech API is fired when the list of SpeechSynthesisVoice objects that would be returned by the SpeechSynthesis.getVoices() method has changed (when the voiceschanged event fires.)

Just a guess, but possibly the reason for the difference is that Chrome fires the event after it "adds" voices to your page. Firefox doesn't, so it doesn't.

The aforementioned demo gets around this incompatibility by calling populateVoiceList() right before the conditional code that triggers it (fourth line from bottom below, from here (CC0 licensed):

function populateVoiceList() {
  voices = synth.getVoices();
  var selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
  voiceSelect.innerHTML = '';
  for(i = 0; i < voices.length ; i++) {
    var option = document.createElement('option');
    option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
    
    if(voices[i].default) {
      option.textContent += ' -- DEFAULT';
    }

    option.setAttribute('data-lang', voices[i].lang);
    option.setAttribute('data-name', voices[i].name);
    voiceSelect.appendChild(option);
  }
  voiceSelect.selectedIndex = selectedIndex;
}

populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
  speechSynthesis.onvoiceschanged = populateVoiceList;
}

This is the approach I've adopted for my web application; otherwise my list of voices never gets populated by Firefox. This code also happens to address a similar problem with Safari; see voiceschanged event not fired in Safari.

Soudan answered 18/4, 2018 at 14:46 Comment(0)
G
1

For anyone else still struggling with this, this is what fixed it for me. Assuming speech-dispatcher and espeak are already installed, the issue may be that there are multiple speech-dispatcher output modules installed and the default of them has no voices.

For example, on my system,

# spd-say -O lists output modules
$ spd-say -O
OUTPUT MODULES
espeak-ng-mbrola
espeak-ng

# spd-say -L lists all voices associated with the current
# output module
$ spd-say -L
                     NAME                 LANGUAGE                  VARIANT

$ 

Notice that spd-say -L outputs an empty table, even though spd-say "Hello world" works. I had no voices installed for the default speech-dispatcher module.

The second module in the list, espeak-ng, does have voices installed. Running spd-say -o espeak-ng -L produces a long table (-o selects a specific module).

Firefox seems to only query the default output module. This AskUbuntu post explains how to change the default output module.

Installing another output module, however, fixed the issue for me (I had trouble changing the default output module via /etc/speech-dispatcher/speechd.conf).

In short,

$ sudo apt install speech-dispatcher-pico

fixed the issue.

Guarino answered 26/5, 2022 at 7:59 Comment(4)
package doesn't exist on archImperceptive
Consider trying festival — it's another speech synthesizer that appears to be in the Arch repository. I'm not sure whether it automatically connects to speech-dispatcher, however...Guarino
Works for me on Arch, I had to install speech-dispatcher and espeak-ng, run spd-conf and restart Firefox. On the other hand Chromium still doesn't load any voice.Sparke
I still have the issue, even after spd-say -L provides the correct list and spd-conf succeeded.Romaromagna
D
0

The original bug seems to indicate you need speechd (speech-dispatcher) installed, see https://bugzilla.mozilla.org/show_bug.cgi?id=1003464.

Diphase answered 23/1, 2018 at 20:14 Comment(2)
You need to install speech-dispatcher as said.Diphase
still doesn't work on manjaroImperceptive
G
0

I had similar issue and solve it by using setTimeout, this is probably not the perfect solution but it works for me, give it a try

window.speechSynthesis.onvoiceschanged = setTimeout(function() {
    window.speechSynthesis.getVoices();
}, 1000);
Gronseth answered 8/9, 2022 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.