Adding pause and play functionality to Speech Synthesis API












2















I'm new to JavaScript and I am trying to add a pause button by linking a button to synth.pause(speakText); where const synth = window.speechSynthesis; and const speakText = new SpeechSynthesisUtterance(textInput.value);.



I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function. I tried making speakText a global variable by calling its constructor outside of the function but that causes speak() to throw an error.



Any idea on how I can achieve this?



JS Code:






//Speak
const speak = () => {
//Check to see if already speaking
if (synth.speaking && state === "play") {
console.error("Already speaking");
state = "paused";
console.log("state: " + state);
return;
}
//Make sure there is some input
if (textInput.value !== "" && state === "stop") {
const speakText = new SpeechSynthesisUtterance(textInput.value);
state = "play";

//Speak error
speakText.onerror = e => {
console.log("Something went wrong!");
};

//Selected voice
const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
"data-name"
);

//Loop through voices to set the correct voice
voices.forEach(voice => {
if (selectedVoice === voice.name) {
speakText.voice = voice;
}
});

//Set the rate and pitch
speakText.rate = rate.value;
speakText.pitch = pitch.value;

//Speak end
speakText.onend = e => {
console.log("Done Speaking");
state = "stop";
};

speakController(speakText);
}
};

const speakController = speakText => {
console.log("state: " + state);
if (state === "play") {
synth.speak(speakText);
} else if (state === "pause") {
synth.pause(speakText);
} else if (state === "stop") {
synth.cancel(speakText);
}
};

//----------EVENT LISTENERS----------
var state = "stop";

// Text form submit
textForm.addEventListener("submit", e => {
e.preventDefault();
speak();
textInput.blur();
});

//Pause button
pauseButton.addEventListener("onClick", e => {
e.preventDefault();
speakController;
});












share|improve this question



























    2















    I'm new to JavaScript and I am trying to add a pause button by linking a button to synth.pause(speakText); where const synth = window.speechSynthesis; and const speakText = new SpeechSynthesisUtterance(textInput.value);.



    I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function. I tried making speakText a global variable by calling its constructor outside of the function but that causes speak() to throw an error.



    Any idea on how I can achieve this?



    JS Code:






    //Speak
    const speak = () => {
    //Check to see if already speaking
    if (synth.speaking && state === "play") {
    console.error("Already speaking");
    state = "paused";
    console.log("state: " + state);
    return;
    }
    //Make sure there is some input
    if (textInput.value !== "" && state === "stop") {
    const speakText = new SpeechSynthesisUtterance(textInput.value);
    state = "play";

    //Speak error
    speakText.onerror = e => {
    console.log("Something went wrong!");
    };

    //Selected voice
    const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
    "data-name"
    );

    //Loop through voices to set the correct voice
    voices.forEach(voice => {
    if (selectedVoice === voice.name) {
    speakText.voice = voice;
    }
    });

    //Set the rate and pitch
    speakText.rate = rate.value;
    speakText.pitch = pitch.value;

    //Speak end
    speakText.onend = e => {
    console.log("Done Speaking");
    state = "stop";
    };

    speakController(speakText);
    }
    };

    const speakController = speakText => {
    console.log("state: " + state);
    if (state === "play") {
    synth.speak(speakText);
    } else if (state === "pause") {
    synth.pause(speakText);
    } else if (state === "stop") {
    synth.cancel(speakText);
    }
    };

    //----------EVENT LISTENERS----------
    var state = "stop";

    // Text form submit
    textForm.addEventListener("submit", e => {
    e.preventDefault();
    speak();
    textInput.blur();
    });

    //Pause button
    pauseButton.addEventListener("onClick", e => {
    e.preventDefault();
    speakController;
    });












    share|improve this question

























      2












      2








      2








      I'm new to JavaScript and I am trying to add a pause button by linking a button to synth.pause(speakText); where const synth = window.speechSynthesis; and const speakText = new SpeechSynthesisUtterance(textInput.value);.



      I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function. I tried making speakText a global variable by calling its constructor outside of the function but that causes speak() to throw an error.



      Any idea on how I can achieve this?



      JS Code:






      //Speak
      const speak = () => {
      //Check to see if already speaking
      if (synth.speaking && state === "play") {
      console.error("Already speaking");
      state = "paused";
      console.log("state: " + state);
      return;
      }
      //Make sure there is some input
      if (textInput.value !== "" && state === "stop") {
      const speakText = new SpeechSynthesisUtterance(textInput.value);
      state = "play";

      //Speak error
      speakText.onerror = e => {
      console.log("Something went wrong!");
      };

      //Selected voice
      const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
      "data-name"
      );

      //Loop through voices to set the correct voice
      voices.forEach(voice => {
      if (selectedVoice === voice.name) {
      speakText.voice = voice;
      }
      });

      //Set the rate and pitch
      speakText.rate = rate.value;
      speakText.pitch = pitch.value;

      //Speak end
      speakText.onend = e => {
      console.log("Done Speaking");
      state = "stop";
      };

      speakController(speakText);
      }
      };

      const speakController = speakText => {
      console.log("state: " + state);
      if (state === "play") {
      synth.speak(speakText);
      } else if (state === "pause") {
      synth.pause(speakText);
      } else if (state === "stop") {
      synth.cancel(speakText);
      }
      };

      //----------EVENT LISTENERS----------
      var state = "stop";

      // Text form submit
      textForm.addEventListener("submit", e => {
      e.preventDefault();
      speak();
      textInput.blur();
      });

      //Pause button
      pauseButton.addEventListener("onClick", e => {
      e.preventDefault();
      speakController;
      });












      share|improve this question














      I'm new to JavaScript and I am trying to add a pause button by linking a button to synth.pause(speakText); where const synth = window.speechSynthesis; and const speakText = new SpeechSynthesisUtterance(textInput.value);.



      I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function. I tried making speakText a global variable by calling its constructor outside of the function but that causes speak() to throw an error.



      Any idea on how I can achieve this?



      JS Code:






      //Speak
      const speak = () => {
      //Check to see if already speaking
      if (synth.speaking && state === "play") {
      console.error("Already speaking");
      state = "paused";
      console.log("state: " + state);
      return;
      }
      //Make sure there is some input
      if (textInput.value !== "" && state === "stop") {
      const speakText = new SpeechSynthesisUtterance(textInput.value);
      state = "play";

      //Speak error
      speakText.onerror = e => {
      console.log("Something went wrong!");
      };

      //Selected voice
      const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
      "data-name"
      );

      //Loop through voices to set the correct voice
      voices.forEach(voice => {
      if (selectedVoice === voice.name) {
      speakText.voice = voice;
      }
      });

      //Set the rate and pitch
      speakText.rate = rate.value;
      speakText.pitch = pitch.value;

      //Speak end
      speakText.onend = e => {
      console.log("Done Speaking");
      state = "stop";
      };

      speakController(speakText);
      }
      };

      const speakController = speakText => {
      console.log("state: " + state);
      if (state === "play") {
      synth.speak(speakText);
      } else if (state === "pause") {
      synth.pause(speakText);
      } else if (state === "stop") {
      synth.cancel(speakText);
      }
      };

      //----------EVENT LISTENERS----------
      var state = "stop";

      // Text form submit
      textForm.addEventListener("submit", e => {
      e.preventDefault();
      speak();
      textInput.blur();
      });

      //Pause button
      pauseButton.addEventListener("onClick", e => {
      e.preventDefault();
      speakController;
      });








      //Speak
      const speak = () => {
      //Check to see if already speaking
      if (synth.speaking && state === "play") {
      console.error("Already speaking");
      state = "paused";
      console.log("state: " + state);
      return;
      }
      //Make sure there is some input
      if (textInput.value !== "" && state === "stop") {
      const speakText = new SpeechSynthesisUtterance(textInput.value);
      state = "play";

      //Speak error
      speakText.onerror = e => {
      console.log("Something went wrong!");
      };

      //Selected voice
      const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
      "data-name"
      );

      //Loop through voices to set the correct voice
      voices.forEach(voice => {
      if (selectedVoice === voice.name) {
      speakText.voice = voice;
      }
      });

      //Set the rate and pitch
      speakText.rate = rate.value;
      speakText.pitch = pitch.value;

      //Speak end
      speakText.onend = e => {
      console.log("Done Speaking");
      state = "stop";
      };

      speakController(speakText);
      }
      };

      const speakController = speakText => {
      console.log("state: " + state);
      if (state === "play") {
      synth.speak(speakText);
      } else if (state === "pause") {
      synth.pause(speakText);
      } else if (state === "stop") {
      synth.cancel(speakText);
      }
      };

      //----------EVENT LISTENERS----------
      var state = "stop";

      // Text form submit
      textForm.addEventListener("submit", e => {
      e.preventDefault();
      speak();
      textInput.blur();
      });

      //Pause button
      pauseButton.addEventListener("onClick", e => {
      e.preventDefault();
      speakController;
      });





      //Speak
      const speak = () => {
      //Check to see if already speaking
      if (synth.speaking && state === "play") {
      console.error("Already speaking");
      state = "paused";
      console.log("state: " + state);
      return;
      }
      //Make sure there is some input
      if (textInput.value !== "" && state === "stop") {
      const speakText = new SpeechSynthesisUtterance(textInput.value);
      state = "play";

      //Speak error
      speakText.onerror = e => {
      console.log("Something went wrong!");
      };

      //Selected voice
      const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
      "data-name"
      );

      //Loop through voices to set the correct voice
      voices.forEach(voice => {
      if (selectedVoice === voice.name) {
      speakText.voice = voice;
      }
      });

      //Set the rate and pitch
      speakText.rate = rate.value;
      speakText.pitch = pitch.value;

      //Speak end
      speakText.onend = e => {
      console.log("Done Speaking");
      state = "stop";
      };

      speakController(speakText);
      }
      };

      const speakController = speakText => {
      console.log("state: " + state);
      if (state === "play") {
      synth.speak(speakText);
      } else if (state === "pause") {
      synth.pause(speakText);
      } else if (state === "stop") {
      synth.cancel(speakText);
      }
      };

      //----------EVENT LISTENERS----------
      var state = "stop";

      // Text form submit
      textForm.addEventListener("submit", e => {
      e.preventDefault();
      speak();
      textInput.blur();
      });

      //Pause button
      pauseButton.addEventListener("onClick", e => {
      e.preventDefault();
      speakController;
      });






      javascript text-to-speech






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 3 at 0:19









      Siman ShresthaSiman Shrestha

      415




      415
























          1 Answer
          1






          active

          oldest

          votes


















          2















          [..How..] to add a pause button by linking a button to synth.pause(speakText);




          The cheap answer would be to have the button call speechSynthesis.pause() (which doesn't take arguments) - because synth is just a copy of the global window.speechSynthesis property.



          A better solution is to create a controller that exposes an interface of methods and properties to outside callers, and encapsulates its own internal workings.



          You touched on the problem here:




          I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.




          which means there's a code structure design issue. But there is another problem: the speech synthesizer doesn't have states of "play", "pause" and "stop". It has two mutually exclusive states of "play" and "pause", and a totally independent condition of "queue empty".



          I don't propose to fix the posted code - although I certainly tried. Here's what I ended up with to determine what was going on - it is experimental code but hopefully the podcast will help!






          "use strict";
          const tr = {
          queue: null,
          pause: null,
          play: null,
          cancel: null,
          defaultRate: 1.1,
          defaultPitch: 1,
          // voice selection to do;
          };
          function createTextReader( tr) {
          let synth = window.speechSynthesis; // abbreviation
          let Utter = SpeechSynthesisUtterance; // abbreviation
          // queue
          tr.queue = (text, rate, pitch, voiceIndex) => {
          let utter = new Utter();
          utter.text = text;
          utter.rate = rate || tr.defaultRate || 1;
          utter.pitch = pitch || tr.defaultPitch || 1;
          // voice selection to do
          // if( voiceParam) ....
          synth.speak( utter);
          };
          tr.pause = () => synth.pause();
          tr.play = () => synth.resume();
          tr.cancel = () => synth.cancel();
          }
          window.addEventListener( "DOMContentLoaded", function (e) {
          createTextReader( tr)}, false);
          window.addEventListener("unload", e=>tr.cancel(), false);

          <textarea cols=40 rows=4 id="queueText">
          Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

          Press "pause" to pause reading.

          Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

          Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

          This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

          Oh, and don't forget to cancel speech synthesis on window unload.

          Thanks for listening!
          </textarea><br>
          <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
          <p>
          <button type="button" onclick="tr.pause()">pause</button>
          <button type="button" onclick="tr.play()">play</button>
          <button type="button" onclick="tr.cancel()">cancel</button>
          <p>





          The link for the MDN page referred to is https://mdn.github.io/web-speech-api/speak-easy-synthesis/






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014865%2fadding-pause-and-play-functionality-to-speech-synthesis-api%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2















            [..How..] to add a pause button by linking a button to synth.pause(speakText);




            The cheap answer would be to have the button call speechSynthesis.pause() (which doesn't take arguments) - because synth is just a copy of the global window.speechSynthesis property.



            A better solution is to create a controller that exposes an interface of methods and properties to outside callers, and encapsulates its own internal workings.



            You touched on the problem here:




            I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.




            which means there's a code structure design issue. But there is another problem: the speech synthesizer doesn't have states of "play", "pause" and "stop". It has two mutually exclusive states of "play" and "pause", and a totally independent condition of "queue empty".



            I don't propose to fix the posted code - although I certainly tried. Here's what I ended up with to determine what was going on - it is experimental code but hopefully the podcast will help!






            "use strict";
            const tr = {
            queue: null,
            pause: null,
            play: null,
            cancel: null,
            defaultRate: 1.1,
            defaultPitch: 1,
            // voice selection to do;
            };
            function createTextReader( tr) {
            let synth = window.speechSynthesis; // abbreviation
            let Utter = SpeechSynthesisUtterance; // abbreviation
            // queue
            tr.queue = (text, rate, pitch, voiceIndex) => {
            let utter = new Utter();
            utter.text = text;
            utter.rate = rate || tr.defaultRate || 1;
            utter.pitch = pitch || tr.defaultPitch || 1;
            // voice selection to do
            // if( voiceParam) ....
            synth.speak( utter);
            };
            tr.pause = () => synth.pause();
            tr.play = () => synth.resume();
            tr.cancel = () => synth.cancel();
            }
            window.addEventListener( "DOMContentLoaded", function (e) {
            createTextReader( tr)}, false);
            window.addEventListener("unload", e=>tr.cancel(), false);

            <textarea cols=40 rows=4 id="queueText">
            Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

            Press "pause" to pause reading.

            Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

            Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

            This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

            Oh, and don't forget to cancel speech synthesis on window unload.

            Thanks for listening!
            </textarea><br>
            <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
            <p>
            <button type="button" onclick="tr.pause()">pause</button>
            <button type="button" onclick="tr.play()">play</button>
            <button type="button" onclick="tr.cancel()">cancel</button>
            <p>





            The link for the MDN page referred to is https://mdn.github.io/web-speech-api/speak-easy-synthesis/






            share|improve this answer




























              2















              [..How..] to add a pause button by linking a button to synth.pause(speakText);




              The cheap answer would be to have the button call speechSynthesis.pause() (which doesn't take arguments) - because synth is just a copy of the global window.speechSynthesis property.



              A better solution is to create a controller that exposes an interface of methods and properties to outside callers, and encapsulates its own internal workings.



              You touched on the problem here:




              I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.




              which means there's a code structure design issue. But there is another problem: the speech synthesizer doesn't have states of "play", "pause" and "stop". It has two mutually exclusive states of "play" and "pause", and a totally independent condition of "queue empty".



              I don't propose to fix the posted code - although I certainly tried. Here's what I ended up with to determine what was going on - it is experimental code but hopefully the podcast will help!






              "use strict";
              const tr = {
              queue: null,
              pause: null,
              play: null,
              cancel: null,
              defaultRate: 1.1,
              defaultPitch: 1,
              // voice selection to do;
              };
              function createTextReader( tr) {
              let synth = window.speechSynthesis; // abbreviation
              let Utter = SpeechSynthesisUtterance; // abbreviation
              // queue
              tr.queue = (text, rate, pitch, voiceIndex) => {
              let utter = new Utter();
              utter.text = text;
              utter.rate = rate || tr.defaultRate || 1;
              utter.pitch = pitch || tr.defaultPitch || 1;
              // voice selection to do
              // if( voiceParam) ....
              synth.speak( utter);
              };
              tr.pause = () => synth.pause();
              tr.play = () => synth.resume();
              tr.cancel = () => synth.cancel();
              }
              window.addEventListener( "DOMContentLoaded", function (e) {
              createTextReader( tr)}, false);
              window.addEventListener("unload", e=>tr.cancel(), false);

              <textarea cols=40 rows=4 id="queueText">
              Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

              Press "pause" to pause reading.

              Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

              Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

              This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

              Oh, and don't forget to cancel speech synthesis on window unload.

              Thanks for listening!
              </textarea><br>
              <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
              <p>
              <button type="button" onclick="tr.pause()">pause</button>
              <button type="button" onclick="tr.play()">play</button>
              <button type="button" onclick="tr.cancel()">cancel</button>
              <p>





              The link for the MDN page referred to is https://mdn.github.io/web-speech-api/speak-easy-synthesis/






              share|improve this answer


























                2












                2








                2








                [..How..] to add a pause button by linking a button to synth.pause(speakText);




                The cheap answer would be to have the button call speechSynthesis.pause() (which doesn't take arguments) - because synth is just a copy of the global window.speechSynthesis property.



                A better solution is to create a controller that exposes an interface of methods and properties to outside callers, and encapsulates its own internal workings.



                You touched on the problem here:




                I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.




                which means there's a code structure design issue. But there is another problem: the speech synthesizer doesn't have states of "play", "pause" and "stop". It has two mutually exclusive states of "play" and "pause", and a totally independent condition of "queue empty".



                I don't propose to fix the posted code - although I certainly tried. Here's what I ended up with to determine what was going on - it is experimental code but hopefully the podcast will help!






                "use strict";
                const tr = {
                queue: null,
                pause: null,
                play: null,
                cancel: null,
                defaultRate: 1.1,
                defaultPitch: 1,
                // voice selection to do;
                };
                function createTextReader( tr) {
                let synth = window.speechSynthesis; // abbreviation
                let Utter = SpeechSynthesisUtterance; // abbreviation
                // queue
                tr.queue = (text, rate, pitch, voiceIndex) => {
                let utter = new Utter();
                utter.text = text;
                utter.rate = rate || tr.defaultRate || 1;
                utter.pitch = pitch || tr.defaultPitch || 1;
                // voice selection to do
                // if( voiceParam) ....
                synth.speak( utter);
                };
                tr.pause = () => synth.pause();
                tr.play = () => synth.resume();
                tr.cancel = () => synth.cancel();
                }
                window.addEventListener( "DOMContentLoaded", function (e) {
                createTextReader( tr)}, false);
                window.addEventListener("unload", e=>tr.cancel(), false);

                <textarea cols=40 rows=4 id="queueText">
                Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

                Press "pause" to pause reading.

                Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

                Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

                This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

                Oh, and don't forget to cancel speech synthesis on window unload.

                Thanks for listening!
                </textarea><br>
                <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
                <p>
                <button type="button" onclick="tr.pause()">pause</button>
                <button type="button" onclick="tr.play()">play</button>
                <button type="button" onclick="tr.cancel()">cancel</button>
                <p>





                The link for the MDN page referred to is https://mdn.github.io/web-speech-api/speak-easy-synthesis/






                share|improve this answer














                [..How..] to add a pause button by linking a button to synth.pause(speakText);




                The cheap answer would be to have the button call speechSynthesis.pause() (which doesn't take arguments) - because synth is just a copy of the global window.speechSynthesis property.



                A better solution is to create a controller that exposes an interface of methods and properties to outside callers, and encapsulates its own internal workings.



                You touched on the problem here:




                I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.




                which means there's a code structure design issue. But there is another problem: the speech synthesizer doesn't have states of "play", "pause" and "stop". It has two mutually exclusive states of "play" and "pause", and a totally independent condition of "queue empty".



                I don't propose to fix the posted code - although I certainly tried. Here's what I ended up with to determine what was going on - it is experimental code but hopefully the podcast will help!






                "use strict";
                const tr = {
                queue: null,
                pause: null,
                play: null,
                cancel: null,
                defaultRate: 1.1,
                defaultPitch: 1,
                // voice selection to do;
                };
                function createTextReader( tr) {
                let synth = window.speechSynthesis; // abbreviation
                let Utter = SpeechSynthesisUtterance; // abbreviation
                // queue
                tr.queue = (text, rate, pitch, voiceIndex) => {
                let utter = new Utter();
                utter.text = text;
                utter.rate = rate || tr.defaultRate || 1;
                utter.pitch = pitch || tr.defaultPitch || 1;
                // voice selection to do
                // if( voiceParam) ....
                synth.speak( utter);
                };
                tr.pause = () => synth.pause();
                tr.play = () => synth.resume();
                tr.cancel = () => synth.cancel();
                }
                window.addEventListener( "DOMContentLoaded", function (e) {
                createTextReader( tr)}, false);
                window.addEventListener("unload", e=>tr.cancel(), false);

                <textarea cols=40 rows=4 id="queueText">
                Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

                Press "pause" to pause reading.

                Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

                Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

                This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

                Oh, and don't forget to cancel speech synthesis on window unload.

                Thanks for listening!
                </textarea><br>
                <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
                <p>
                <button type="button" onclick="tr.pause()">pause</button>
                <button type="button" onclick="tr.play()">play</button>
                <button type="button" onclick="tr.cancel()">cancel</button>
                <p>





                The link for the MDN page referred to is https://mdn.github.io/web-speech-api/speak-easy-synthesis/






                "use strict";
                const tr = {
                queue: null,
                pause: null,
                play: null,
                cancel: null,
                defaultRate: 1.1,
                defaultPitch: 1,
                // voice selection to do;
                };
                function createTextReader( tr) {
                let synth = window.speechSynthesis; // abbreviation
                let Utter = SpeechSynthesisUtterance; // abbreviation
                // queue
                tr.queue = (text, rate, pitch, voiceIndex) => {
                let utter = new Utter();
                utter.text = text;
                utter.rate = rate || tr.defaultRate || 1;
                utter.pitch = pitch || tr.defaultPitch || 1;
                // voice selection to do
                // if( voiceParam) ....
                synth.speak( utter);
                };
                tr.pause = () => synth.pause();
                tr.play = () => synth.resume();
                tr.cancel = () => synth.cancel();
                }
                window.addEventListener( "DOMContentLoaded", function (e) {
                createTextReader( tr)}, false);
                window.addEventListener("unload", e=>tr.cancel(), false);

                <textarea cols=40 rows=4 id="queueText">
                Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

                Press "pause" to pause reading.

                Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

                Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

                This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

                Oh, and don't forget to cancel speech synthesis on window unload.

                Thanks for listening!
                </textarea><br>
                <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
                <p>
                <button type="button" onclick="tr.pause()">pause</button>
                <button type="button" onclick="tr.play()">play</button>
                <button type="button" onclick="tr.cancel()">cancel</button>
                <p>





                "use strict";
                const tr = {
                queue: null,
                pause: null,
                play: null,
                cancel: null,
                defaultRate: 1.1,
                defaultPitch: 1,
                // voice selection to do;
                };
                function createTextReader( tr) {
                let synth = window.speechSynthesis; // abbreviation
                let Utter = SpeechSynthesisUtterance; // abbreviation
                // queue
                tr.queue = (text, rate, pitch, voiceIndex) => {
                let utter = new Utter();
                utter.text = text;
                utter.rate = rate || tr.defaultRate || 1;
                utter.pitch = pitch || tr.defaultPitch || 1;
                // voice selection to do
                // if( voiceParam) ....
                synth.speak( utter);
                };
                tr.pause = () => synth.pause();
                tr.play = () => synth.resume();
                tr.cancel = () => synth.cancel();
                }
                window.addEventListener( "DOMContentLoaded", function (e) {
                createTextReader( tr)}, false);
                window.addEventListener("unload", e=>tr.cancel(), false);

                <textarea cols=40 rows=4 id="queueText">
                Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

                Press "pause" to pause reading.

                Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

                Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

                This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

                Oh, and don't forget to cancel speech synthesis on window unload.

                Thanks for listening!
                </textarea><br>
                <button type="button" onclick="tr.queue(queueText.value)">queue text</button>
                <p>
                <button type="button" onclick="tr.pause()">pause</button>
                <button type="button" onclick="tr.play()">play</button>
                <button type="button" onclick="tr.cancel()">cancel</button>
                <p>






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 3 at 12:57









                traktor53traktor53

                7,9221832




                7,9221832
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014865%2fadding-pause-and-play-functionality-to-speech-synthesis-api%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    MongoDB - Not Authorized To Execute Command

                    How to fix TextFormField cause rebuild widget in Flutter

                    in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith