Marcelo Arias
Marcelo Arias

Reputation: 109

How to use SpeechSynthesis inside a setInterval function?

I need a way to continuously use speech synthesis (like a word every 5 seconds) after the user has done an action like pressing a button.

But I can't create this behavior using setInterval on Safari browsers. This is my code, removing the setInterval function works fine. But enabling setInterval to work every 5 seconds fails.

Code in codepen.io

<button type="button" id="speakBtn" disabled>Speak</button>
if ('speechSynthesis' in window) {
  speechSynthesis.cancel();
  speechSynthesis.getVoices();
  speakBtn.disabled = false;
}

const speak = () => {
  // Works without setInterval:
  setInterval(function () {
    const utter = new SpeechSynthesisUtterance();
    utter.text = "Hello world";
    speechSynthesis.speak(utter);
  }, 5000);
};

speakBtn.addEventListener('click', speak);

Upvotes: 0

Views: 195

Answers (1)

mcomella
mcomella

Reputation: 79

From my answer in https://stackoverflow.com/a/79296650/2219998, mobile Safari seems to require that the first utterance happens during a user interaction (even if it's empty!) in order to enable utterances in non-user-interactive places like timeouts/intervals. This works for me:

function speak(msg) {
  speechSynthesis.speak(new SpeechSynthesisUtterance(msg));
}

const startTimerButton = document.getElementById('start-timer');
startTimerButton.addEventListener('click', () => { 
  // Mobile Safari requires an utterance (even a blank one) during
  // a user interaction to enable utterances during timeouts.
  speak('');

  setInterval(() => {
    speak('another five seconds passed');
  }, 5 * 1000);
});
<button id="start-timer">Start</button>

Upvotes: 0

Related Questions