-1

I have not being able to use the getvoices() function from the speechsynthesis framework. My basic idea is to be able to click on the document and be able to read the text of the element in Spanish. Therefore, I am trying to use the promise and await paradigm to set the voice variable upon loading the document based on the list of available voices. What am I missing? thanks!

var synth = window.speechSynthesis;
function getVoices() {
    return new Promise(resolve => {
        let voices = speechSynthesis.getVoices()
            resolve(voices)
    })
}
async function getVoz() {
    const Voces = await getVoices();
    for(voz of Voces){
        if (voz.lang=="es-ES"){
            return voz
        }
    }
}
var voice = getVoz()

function sayit(){
  var div = document.getElementById('main')
  var what=div.innerHTML
  var hi = new SpeechSynthesisUtterance(what);
  hi.pitch = 1;
  hi.rate = 1;
  hi = voice;
  synth.speak(hi);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="script.js"></script>
</head>

<body>
  <div id="main" onclick="sayit()"> Hola Mundo </div>
</body>
</html>
Nithish
  • 5,393
  • 2
  • 9
  • 24

2 Answers2

4

I see at least 3 mistakes:

  • speechSynthesis.getVoices() is a synchronous method, so wrapping in in a Promise does nothing. It's not harmful, just pointless.
  • var voice = getVoz() - after this, voice is now the promise, not the result. However you cannot add await here since you are not inside an async function. You need to use .then() and a callback.
  • hi = voice; - this overwrites the entire hi variable with the Promise. Probably not what was intended.

Here's how I would write it:


function sayit(){
  var hi = new SpeechSynthesisUtterance(document.getElementById('main').innerHTML);
  hi.pitch = 1;
  hi.rate = 1;
  hi.voice = window.speechSynthesis.getVoices().find(voz => voz.lang == "es-ES");
  window.speechSynthesis.speak(hi);
}
Vilx-
  • 104,512
  • 87
  • 279
  • 422
0

After some more readings, I found a couple of things that solve my problem:

  1. the voicelist is loaded async to the page. An onvoiceschanged event is needed.
  2. this code works (await getVoices()) and the previous one does not const Voces = await getVoices()

The following code works

let synth = window.speechSynthesis;
let esp= 0
const getVoices = () => {
    return new Promise(resolve => {
        let voices = synth.getVoices()
        if (voices.length) {
          resolve(voices)
          return
        }
        const voiceschanged = () => {
          voices = synth.getVoices()
          resolve(voices)
        }
        speechSynthesis.onvoiceschanged = voiceschanged
    })
}

const getVoz = async () => {
  (await getVoices()).forEach(voice => {
    console.log(voice.name, voice.lang)
    if(voice.lang=="es-ES"){
      esp= voice
    }
  })
}
getVoz()

function sayit(){
  let div = document.getElementById('main')
  let what=div.innerHTML
  let hi = new SpeechSynthesisUtterance(what);
  hi.pitch = 1;
  hi.rate = 1;
  hi.voice = esp;
  synth.speak(hi);
}```