javascripttext-to-speechspeech-synthesis

How to set Speech Synthesis to a specific voice without overlapping with the default voice


I am currently trying to set a specific voice in speechSynthesis and I did it but the issue I am facing now is that whenever I trigger the voice, in my case I use a button, the first time I click the button, it triggers the voice from the lang that I put there which is en-GB, and the chosen voice will only effect on second click onwards. I want only 1 voice to work which is the one I chose from getVoices.You can try the code down below to see what I mean, thank you!

function speakTTS() {
  const voices = window.speechSynthesis.getVoices();
  const message = new SpeechSynthesisUtterance();
  message.text = "Please get me a bottle of water, thank you.";
  message.volume = 1; // Volume range = 0 - 1
  message.rate = 1.1; // Speed of the text read , default 1
  message.voice = voices[9]; // change voice
  message.lang = 'en-GB'; // Language, default 'en-US'
  window.speechSynthesis.speak(message);
  console.log(window.speechSynthesis.getVoices());
}
<button onClick=speakTTS()>Speak</button>


Solution

  • There is an onvoiceschanged event listener that we can use. It will fire when the voices have completely loaded.

    let voices
    
    window.speechSynthesis.onvoiceschanged = function() {
      voices = window.speechSynthesis.getVoices();
    };
    
    function speakTTS() {
      const message = new SpeechSynthesisUtterance();
      message.text = "Please get me a bottle of water, thank you.";
      message.volume = 1; // Volume range = 0 - 1
      message.rate = 1.1; // Speed of the text read , default 1
      message.voice = voices[9]; // change voice
      message.lang = 'en-GB'; // Language, default 'en-US'
      window.speechSynthesis.speak(message);
      console.log(voices);
    }
    <button onClick=speakTTS()>Speak</button>

    The onvoiceschanged property of the SpeechSynthesis interface represents an event handler that will run when the list of SpeechSynthesisVoice objects that would be returned by the SpeechSynthesis.getVoices() method has changed (when the voiceschanged event fires.)

    UDN Web Docs: SpeechSynthesis.onvoiceschanged