Short post about my experimental implementation of Web Speech API specifically the SpeechSynthesis interface that allows you to add the ability to play an audio version of each post.

The implementation applies directly to WordPress template code, but with a few minor changes you can use it in any case.

After improving this solution it would be nice to make it available as a plugin.

Experimental version of the code:

<div id="speak-container" style="display: none;">
  <button id="speak-button"></button>
</div>

<script>
  // Check browser support
  if ('speechSynthesis' in window) {
    // Cancel audio reader before page leave
    window.onbeforeunload = () => {
      window.speechSynthesis.cancel();
    }
    // Wait for voices initialisation
    window.speechSynthesis.onvoiceschanged = () => {
      const speakContainer = document.getElementById('speak-container');
      const button = document.getElementById('speak-button');
      const buttonTextPlay = "▶ Play audio version of the post";
      const buttonTextStop = "⏹ Stop audio version";
      let isPlaying = false;
      // Show play button if user has any voices installed
      if (window.speechSynthesis.getVoices().length) {
        button.textContent = buttonTextPlay;
 	speakContainer.style.display = 'initial';
      }

      const startAudioReader = (text) => {
        const msg = new SpeechSynthesisUtterance();
        // Set the text.
        msg.text = text;
        // Set the lang from Polylang plugin 
        msg.lang = '<?php echo str_replace('_', '-', get_locale()); ?>';

        // Queue this utterance.
        window.speechSynthesis.speak(msg);
      }

      // Set up an event listener for when the 'Play audio' button is clicked.
      button.addEventListener('click', () => {
        isPlaying = !isPlaying;
        if (!isPlaying) { 
          window.speechSynthesis.cancel();
          button.textContent = buttonTextPlay;
          return;
        }
        startAudioReader(`
          <?php echo str_replace('${', '\${', wp_strip_all_tags( get_the_content())); ?>
        `);
        button.textContent = buttonTextStop;
      });
    }
  }
</script>

Leave a Reply

Your email address will not be published. Required fields are marked *