JSFiddle - React, Tailwind, and code Playground

by Dan Shahin

HTML

<h1>Speech Synthesis API demo console</h1>
<h1 id="synthesis-support">Your browser doesn't support "speechSynthesis" API. Try with Chrome Canary.</h1>
<form>
  <p>
    <select id="languages">
      <option disabled>Choose a voice</option>
    </select>
  </p>
  <p>
    <textarea id="text" placeholder="Text to speak">The quick brown fox jumps over the lazy dog.</textarea>
  </p>
  <!-- Seem to break some voices<p>
    <input type="range" id="volume" min="0.0" max="1.0" step="0.1" value="0.5" placeholder="Volume"/>
    <label for="volume">Volume</label>
  </p>-->
  <p>
    <input type="range" id="rate" min="0.1" max="10" step="0.1" value="1"/>
    <label for="rate">Rate</label>
  </p>
  <p>
    <input type="range" id="pitch" min="0" max="2" step="0.1" value="1"/>
    <label for="rate">Pitch</label>
  </p>
  <p>
    <button id="speak" type="button">Speak</button>
  </p>
  <p>
    <input type="checkbox" id="loop"/>
    <label for="loop">Loop</label>
  </p>
</form>
<p>
    <a href="https://twitter.com/NicuPrinFum">@NicuPrinFum</a>
</p>

CSS

#synthesis-support {
    display: none;
}
#synthesis-support.no {
    display: block;
}
a {
    text-decoration: none;
    color: #4679BD;
}

JavaScript

/*
 * Speech Synthesis API console
 * @NicuPrinFum
 */

(function(speechSynthesis) {
    var speech;

    function init() {
        if (support()) {
            // Warm it and wait, see https://code.google.com/p/chromium/issues/detail?id=334847
            speechSynthesis.getVoices();
            setTimeout(function(){view();}, 500);
        } else {
            $("#synthesis-support").addClass("no");
        }
    }
    function support() {
        return !!speechSynthesis;
    }
    function view() {
        var voices = speechSynthesis.getVoices();
        voices.forEach(function(voice, i) {
            var name = voice.name + (voice.default ? '(default)' :'');
            var language = $("<option></option>").text(name).val(i);
            $("#languages").append(language);
        });
        function startSpeaking() {
            var i = $("#languages option:selected").val();
            var params = {
                //volume: $("#volume").val(),
                rate: $("#rate").val(),
                pitch: $("#pitch").val()
            };
            speak(voices[i], $("#text").val(), params);
        }
        $("#speak").bind("click", function() {
            startSpeaking();
        });
        $(document).bind("speak-end", function() {
            if ($("#loop").is(":checked"))
                startSpeaking();
        });
    }
    function speak(voice, text, params) {
        msg = new SpeechSynthesisUtterance();
        msg.voice = voice;
        //msg.volume = parseInt(params.volume); // 0 to 1
        msg.rate = parseInt(params.rate, 10); // 0.1 to 10
        msg.pitch = parseInt(params.pitch, 10); //0 to 2
        msg.text = text;
        msg.onend = function() {
            $(document).trigger("speak-end");
        };
        speechSynthesis.speak(msg);
    }
    
    init();
})(window.speechSynthesis);