acoti / articulate.js

A jQuery plugin that lets the browser speak to you.
http://articulate.purefreedom.com
MIT License
139 stars 28 forks source link

Change speaking immediately #7

Closed HazardCreative closed 5 years ago

HazardCreative commented 5 years ago

The voice won't stop speaking the current section if something else is told to start. I need to have the option to switch right away and force something else to speak. I tried writing a function this way:

$().articulate('stop'); $(obj).articulate('speak');

...but it only starts speaking if the browser wasn't already speaking. Is there another way to accomplish this?

acoti commented 5 years ago

I'm not actively supporting this anymore, but it does seem like you have the proper approach. In my demos, stopping an existing voice and playing a new one is not an issue, but that's based on a person clicking a button and pressing another one. There's a natural delay between the two voices.

So I wonder if the browser needs some sort of pause in there, so it can kind of reset itself, Maybe set a window.timeout of 500ms before starting the new voice?

HazardCreative commented 5 years ago

I'm calling out seconds remaining in a timer, so it's critical that the voice isn't noticeably delayed. I've tried writing a function so that during the final seconds, the voice is cut short (by setting stop on a timeout). While this works a little better it still isn't getting the job done completely—for very short speech, stop() seems to not cut off immediately, or it prevents speech from starting at all.

I haven't tried altering the speech rate to see if that makes a difference, but knowing operating system voices are different I'd hate to rely on that kind of tweaking.

On Thu, Dec 6, 2018 at 10:42 AM Adam Coti notifications@github.com wrote:

I'm not actively supporting this anymore, but it does seem like you have the proper approach. In my demos, stopping an existing voice and playing a new one is not an issue, but that's based on a person clicking a button and pressing another one. There's a natural delay between the two voices.

So I wonder if the browser needs some sort of pause in there, so it can kind of reset itself, Maybe set a window.timeout of 500ms before starting the new voice?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/acoti/articulate.js/issues/7#issuecomment-444916045, or mute the thread https://github.com/notifications/unsubscribe-auth/AG1l9-XypKvnBkbT-Ip67bD99ZoNFgMAks5u2TrhgaJpZM4ZGpQE .

acoti commented 5 years ago

At this point, you may be bumping up against browser limitations on how they implement speech synthesis. If I think of some other approach you can try, I'll let you know. Please keep me posted on how your testing proceeds.

HazardCreative commented 5 years ago

Thanks for your help. I think it is browser limitations as well, because different browsers on different devices gave slightly different results. I wasn't able to resolve this for very short duration speech as in my use case.

As a workaround, I switched to playing an audio file to mark the final seconds. The audio file will play in parallel with speech synthesis if needed.

sullyj3 commented 5 years ago

I ran into the same issue, it definitely seems to be a problem with the speechSynthesis api. A minimal self contained example is the following:

<html>
    <body>
        <div><button onclick="playFirst()">Play First</button></div>
        <div><button onclick="playSecond()">Play Second</button></div>

        <script type="text/javascript">
            const myText = "the first text";
            const myText2 = "the second text!";

            function playFirst() {
                speechSynthesis.speak(new SpeechSynthesisUtterance(myText));
            }

            function playSecond() {
                speechSynthesis.cancel();
                speechSynthesis.speak(new SpeechSynthesisUtterance(myText2));
            }
        </script>
    </body>
</html>

If you click the first button, then the second whilst the text from the first is still being spoken, the speech stops, and the second string is not spoken.

sullyj3 commented 5 years ago

Hmm, it seems like the above snippet works in firefox, but not chrome.

acoti commented 5 years ago

One thing I want to point out: there is a Chrome fix at lines 66-69 in the annotated "articulate.js" file. This was necessary at the time when the speech synthesis API was relatively new, but is also two years old. Perhaps this "fix" is no longer needed or is, somehow, affecting what you are trying to do.