0

I am trying to produce a script that would count numbers (one, two, three… one zero, one one…) seemingly indefinitely using google text to speech (or similar) to play on a website.

Rather than having a program to run continuously on host server, it would use Javascript and, for example, the computer clock.

Could anyone help me to get this started?

Thanks

  • 2
    Please add what you already have tried (some code) or maybe make your first step here: https://stackoverflow.com/questions/15653145/using-google-text-to-speech-in-javascript – Roland Bär Aug 08 '22 at 11:29

1 Answers1

2

Here is a vanilla JS/HTML version:

let count = 1
let timer = null
let controller = new AbortController()
const synth = window.speechSynthesis
const utter = new SpeechSynthesisUtterance(count)
const text = document.getElementById('text')
const onUtterEnd = () => {
  count = count + 1
  utter.text = count
  text.innerHTML = `<mark>${count}</mark>`
  synth.speak(utter)
}
const start = () => {
  text.innerHTML = `<mark>${count}</mark>`
  controller = new AbortController()
  utter.addEventListener('end', onUtterEnd, { signal: controller.signal })
  synth.speak(utter)
}
const stop = () => {
  controller.abort()
  synth.cancel()
}

document.getElementById('start').addEventListener('click', start)
document.getElementById('stop').addEventListener('click', stop)
<button id="start">start</button>
<button id="stop">stop</button>
<p id="text"></p>

If you're using React you can use tts-react. Here is an example (change the counter logic to match your preferred way of counting):

import { useTts } from 'tts-react'
import { useState, useEffect } from 'react'

const SpeakCountedNumbers = () => {
  const [count, setCount] = useState(1)
  const { ttsChildren, play } = useTts({
    children: count,
    rate: 0.9,
    markTextAsSpoken: true,
    onEnd: useCallback(() => {
      setCount((prev) => prev + 1)
    }, [])
  })

  useEffect(() => {
    play()
  }, [count, play])

  return <>{ttsChildren}</>
}

This will render the number sequence, 1, 2, 3, ... while speaking each number and highlighting it in the document.

See it on Codesandbox. Certain browsers may require you to click the document (or interact with it in some way) before audio starts playing, for example Chrome.

morganney
  • 6,566
  • 1
  • 24
  • 35
  • Thank you for the response! The issue with this it that the calculation does keep calculating on the server, it restarts on browser refresh. Also, the space between the words, now 1,1 seconds, does not increase when it takes longer time to say a longer number sequence. I do also wonder, is the use of React necessary for a simple website? – user298959 Sep 17 '22 at 07:13
  • My example is only a start. If you want to tie the counter to a server you can, but you'd have to wire that up. If you want to adjust the speaking rate you can pass in `rate` or `volume` to `useTts`. No, you absolutely don't need React for this. Check out this gist for an example of how to do this using an `utterance.end` listener: https://gist.github.com/morganney/36d4442ac6790751a8381a1c57dbeac4 – morganney Sep 17 '22 at 13:06
  • I've updated the answer to include a vanilla JS/HTML snippet. – morganney Sep 17 '22 at 14:22