23

I used speechSynthesis API in this way:

speechSynthesis.speak(new SpeechSynthesisUtterance("hello world"));

But right now I get error after update Google Chrome:

[Deprecation] speechSynthesis.speak() without user activation is no longer allowed since M71, around December 2018. See https://www.chromestatus.com/feature/5687444770914304 for more details speechSynthesisMessage @ application-2c16c437c2795ae01c0a8852e5f8da58dad99d6e17814a31f1eea19922c5ebd2.js:147

How I can fix this issue and ask permission?

8 Answers 8

24

This is part of Chrome's new policies regarding making sound from web-pages.
You simply need your user to provide an user-gesture (for which you can find a list here) during the lifetime of the parent document (i.e the event may long be dead, as long as the user ever interacted with the page).

Note that these events can even traverse frames, so for instance, in StackOverflow, the simple fact that you do have to click on the "Run" button will make the inner frame allowed to execute this code:

const ut = new SpeechSynthesisUtterance('No warning should arise');
speechSynthesis.speak(ut);

And in your code, you simply have to provide some kind of an UI that will ensure your users have interacted with the page before you call this method (e.g a button / toggle will do perfectly).

3
  • So, we can call this speechSynthesis.speak(message); multiple times for 1 (initial) user interaction?
    – kb0000
    Commented Apr 26, 2020 at 13:38
  • 3
    doesn't work for me, Version 84.0.4147.105 (Official Build) (64-bit), os - linux mint
    – devellopah
    Commented Aug 12, 2020 at 20:24
  • 2
    Doesn't work for me, Chromium 86.0.4240.75 (Official Build) (64-bit), on Ubuntu 20.04 (but DOES work in Firefox 82.0 (64-bit) on the same OS.
    – obe
    Commented Apr 18, 2021 at 19:24
12

If you set your site address as "trusted" in chrome://settings/content/sound it seems to enable sound and speech synthesis even without user interactions.

I use Chrome in a TV just as a system monitor, using kiosk mode and without any user interactions. It doesn't even have keyboard and mouse. Still, I was able to enable in some versions of Chrome/Chromium, but not in others.

1
  • UPDATE: I'm using Chromium in Raspbian, seems it no longer comes with pre-installed voices. So I synth the voices elsewhere and sent them as audio files, working fine now even without user interactions.
    – TNT
    Commented Dec 31, 2019 at 13:30
5

This error means entire document (Website) has no user interaction and Google Chrome update its policy regarding making sound from the website without user interaction.

User interaction means: click, dblclick, mouseup, pointerup, reset, submit etc.

Solution:

So, if you want to run speechSynthesis.speak(); without real user interaction, then you just create temporary user interaction using a method like .click(), etc.

1
  • FWIW i tried this and it did not work. created a click event handler on a dom element and then after loading triggered that click event and the speech still did not fire afterward when it came time to play
    – dr b
    Commented Feb 27, 2021 at 23:10
2

Although I haven't found any way to ask permission, the user can enable permission in Google Chrome:

  1. Click on the icon on the left of the URL bar, and open Site settings

  2. Change the Sound setting from "Automatic (default)" to "Allow"

After doing that, the site will be able to make sounds without any user interaction, including speech.

Unfortunately, I haven't found a way in code to know whether this is working or not. (Perhaps we could try one of the other audio APIs and see if it responds with an error message.)

0

I resorted to swal("Click OK to speak").then(() => speakButton.click()); (with https://sweetalert.js.org) -- https://patarapolw.github.io/tts-api/?q=你好&lang=zh-CN&rate=0.8

Note that if (confirm("Click OK to speak")) speakButton.click() doesn't work.

1
  • I tried confirm() and alert(). Yeah, those clicks don't count, apparently. Commented May 25, 2020 at 12:24
0

use a mock btn to start the speak works for me.

be careful to check the page is muted or not, which took me some hrs to find the bug.(when the page is muted, the speak() method will return an error "not-allowed")

speak(message: string): Observable<string> {

return new Observable(observer => {

  const callback = () => {
    const utterance = new SpeechSynthesisUtterance(message);

    utterance.voice = speechSynthesis.getVoices().find((voice) => voice.lang === 'zh-CN' && voice.localService === true);
    utterance.onend = () => {
      console.log('TTS_SPEAK', message);
      observer.next(message);
      observer.complete();
    };
    utterance.onerror = (err) => {
      if(err.error === 'not-allowed') {
        this.msg.warning('The page is muted');
      }
      observer.error(err)
    };
    window.speechSynthesis?.speak(utterance);
  }

  if (!window.navigator.userAgent.includes('Edg') && window.navigator.userAgent.includes('Chrome')) {
    // https://stackoverflow.com/questions/41539680/speechsynthesis-speak-not-working-in-chrome
    // https://chromestatus.com/feature/5687444770914304
    const btn = document.createElement('button');
    btn.style.display = 'none';

    btn.id = 'TTS_btn';
    btn.addEventListener('click', () => {
      callback();
    });

    document.body.appendChild(btn);


    let event = new MouseEvent('click', {
      view: window,
      bubbles: true,
      cancelable: true
    })
    btn.dispatchEvent(event);

    document.body.removeChild(btn);

  } else {
    callback();
  }



});

}

-1

I was having same issue, and could sort it by using window.onload like this:

window.onload = function(){ 
var u = new SpeechSynthesisUtterance('All is Ok');
 u.text = 'Hello World';    
 u.lang = 'en-US';
 u.rate = 1;
 u.pitch = .4;     
 speechSynthesis.speak(u);
}

Of course this triggers only once after page is loaded, but it was a good solution for me.

-3

A simple hack, without needing a real user activity, is to execute a click event on a hidden button like so.

document.querySelector('button').click();
var msg = new SpeechSynthesisUtterance('Test');
1
  • have you tested? Commented Jun 17, 2021 at 19:18

Not the answer you're looking for? Browse other questions tagged or ask your own question.