1

It seems that speechSynthesis is not allowed to run without user interaction, on some devices, some of the time. My PC browser used to warn about it, but now it works (I don't know if I managed to accidentally change something about permissions in the meantime), while my Android-powered tablet seems to allow it from localhost on http, but disallows it from my production site on https. Phones always disallow it.

I'm wondering if there is some method of determining whether it's allowed on the running device, so that I can show a notice, or hide the options that offer text-to-speech in my app?

Digital Ninja
  • 3,415
  • 5
  • 26
  • 51

1 Answers1

2

It's browser-dependent. Chrome, at least, used to permit speech by default without user interaction, but that changed a bit ago. One hacky way of checking would be to queue an empty utterance, then look to see if either SpeechSynthesis.speaking or SpeechSynthesis.pending is true:

// Allowed:
btn.onclick = () => {
  speechSynthesis.speak(new SpeechSynthesisUtterance(''));
  const worked = speechSynthesis.speaking || speechSynthesis.pending;
  console.log(worked);
};
<button id="btn">click</button>

// Not allowed, silent failure:
speechSynthesis.speak(new SpeechSynthesisUtterance(''));
const worked = speechSynthesis.speaking || speechSynthesis.pending;
console.log(worked);

Unfortunately, speechSynthesis.speak doesn't throw (even asynchronously) when speech is prevented due to no user interaction first, so checking the speaking property looks to be the only other way.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • This doesn't work for me. The first example with `onclick` event still says `false`. And this is on my PC Firefox, where both of them should ideally say `true` (since no-interaction speaking does work in practice) – Digital Ninja Oct 28 '19 at 06:53
  • Looks like with Firefox, new utterances turn on the `pending` state instead of the `speaking` state. – CertainPerformance Oct 28 '19 at 06:58