diff --git a/README.md b/README.md index 0869a03..2628f40 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ # Text to Speech Using Web Speech API in JavaScript If you'd like to learn how to build this application, refer to [this article](https://zolomohan.hashnode.dev/text-to-speech-using-the-web-speech-api-in-javascript). + +## Browser Support + +This should work fine on the current versions of Firefox, Chrome and Edge. + +Chromium and Electron must be started with the argument `--enable-speech-dispatcher`. diff --git a/index.html b/index.html index a39f5ca..97fb81c 100644 --- a/index.html +++ b/index.html @@ -1,38 +1,50 @@ - - - - Text to Speech - - -

Text to Speech

-

Select Voice

- -
-
-

Volume

- - 1 -
-
-

Rate

- - 1 -
-
-

Pitch

- - 1 -
+ + + Text to Speech + + + + + +

Text to Speech

+

Select Voice

+ +
+
+

Volume

+ + 1
- -
- - - - +
+

Rate

+ + 1
- - - - +
+

Pitch

+ + 1 +
+
+ +
+ + + + +
+ + + + + + \ No newline at end of file diff --git a/textToSpeech.js b/textToSpeech.js index 0574d2e..7b101ad 100644 --- a/textToSpeech.js +++ b/textToSpeech.js @@ -1,49 +1,107 @@ +// Initialize new SpeechSynthesisUtterance object let speech = new SpeechSynthesisUtterance(); + +// Set speech Language speech.lang = "en"; +// global array of available voices let voices = []; -window.speechSynthesis.onvoiceschanged = () => { - voices = window.speechSynthesis.getVoices(); + +speechSynthesis.onvoiceschanged = () => { + populateVoiceList(); +} + +function populateVoiceList() { + // Get list of voices + voices = speechSynthesis.getVoices(); + + // Sort the list alphabetically + voices.sort((a, b) => { + let fa = a.name.toLowerCase(), + fb = b.name.toLowerCase(); + if (fa < fb) { return -1; } + if (fa > fb) { return 1; } + return 0; + }); + + // Initially set the First Voice in the Array. speech.voice = voices[0]; + let voiceSelect = document.querySelector("#voices"); - voices.forEach((voice, i) => (voiceSelect.options[i] = new Option(voice.name, i))); -}; + + voices.forEach((voice, i) => { + let option = document.createElement("option"); + option.textContent = voices[i].name + " (" + voices[i].lang + ")"; + + // Set the Index as the value, which we'll use later when the user updates the Voice using the Select Menu. + option.setAttribute("value", i); + + voiceSelect.appendChild(option); + }) +} + +// If the Browser supports speechSynthesis populate Voice List +if (typeof speechSynthesis !== "undefined") { + populateVoiceList(); +} document.querySelector("#rate").addEventListener("input", () => { + // Get rate Value from the input const rate = document.querySelector("#rate").value; + + // Set rate property of the SpeechSynthesisUtterance instance speech.rate = rate; + + // Update the rate label document.querySelector("#rate-label").innerHTML = rate; }); document.querySelector("#volume").addEventListener("input", () => { + // Get volume value from the input const volume = document.querySelector("#volume").value; + + // Set volume property of the SpeechSynthesisUtterance instance speech.volume = volume; + + // Update the volume label document.querySelector("#volume-label").innerHTML = volume; }); document.querySelector("#pitch").addEventListener("input", () => { + // Get pitch value from the input const pitch = document.querySelector("#pitch").value; + + // Set pitch property of the SpeechSynthesisUtterance instance speech.pitch = pitch; + + // Update the pitch label document.querySelector("#pitch-label").innerHTML = pitch; }); document.querySelector("#voices").addEventListener("change", () => { + // On Voice change, use the value of the select menu (which is the index of the voice in the global voice array) speech.voice = voices[document.querySelector("#voices").value]; }); document.querySelector("#start").addEventListener("click", () => { + // Set the text property with the value of the textarea speech.text = document.querySelector("textarea").value; - window.speechSynthesis.speak(speech); + + // Start Speaking + speechSynthesis.speak(speech); }); document.querySelector("#pause").addEventListener("click", () => { - window.speechSynthesis.pause(); + // Pause the speechSynthesis instance + speechSynthesis.pause(); }); document.querySelector("#resume").addEventListener("click", () => { - window.speechSynthesis.resume(); + // Resume the paused speechSynthesis instance + speechSynthesis.resume(); }); document.querySelector("#cancel").addEventListener("click", () => { - window.speechSynthesis.cancel(); + // Cancel the speechSynthesis instance + speechSynthesis.cancel(); });