Read aloud code

This was a lot easier said than done but it would be nice to see this on every webpage one day

<button id=”enable-tts”>Play / Resume</button>

<button id=”pause-tts”>Pause</button>

<button id=”stop-tts”>Stop</button>

<script>

let audioEnabled = false;

let spoken = new WeakSet();

let currentUtterance = null;

document.getElementById(‘enable-tts’).onclick = () => {

  audioEnabled = true;

  // Resume if paused

  if (speechSynthesis.paused) {

    speechSynthesis.resume();

    return;

  }

  // Start fresh

  const text = document.querySelector(‘main’)?.innerText || document.body.innerText;

  speak(text);

};

document.getElementById(‘pause-tts’).onclick = () => {

  if (speechSynthesis.speaking && !speechSynthesis.paused) {

    speechSynthesis.pause();

  }

};

document.getElementById(‘stop-tts’).onclick = () => {

  audioEnabled = false;

  speechSynthesis.cancel();

};

function speak(text) {

  if (!audioEnabled || !text) return;

  speechSynthesis.cancel(); // stop previous

  currentUtterance = new SpeechSynthesisUtterance(text);

  speechSynthesis.speak(currentUtterance);

}

const observer = new MutationObserver(mutations => {

  if (!audioEnabled) return;

  mutations.forEach(m => {

    m.addedNodes.forEach(node => {

      if (node.nodeType === 1 && !spoken.has(node)) {

        const text = node.innerText?.trim();

        if (text && text.length > 30) {

          spoken.add(node);

          speak(text);

        }

      }

    });

  });

});

observer.observe(document.body, { childList: true, subtree: true });

</script>

Leave a Reply

Discover more from Freeview

Subscribe now to keep reading and get access to the full archive.

Continue reading