How can I make my web browser speak programmatically?
Asked Answered
N

4

6

Is it possible to have a website speak a welcome message to users programmatically?

Suppose I wanted to greet users with an audio message upon successful login to my website. I know that I could record a greeting message(i.e. as an MP3), and play that, but I would want to be able to do this programmatically, since all users' names would be different.

For example, I might want to say Welcome, John Doe when John Doe logs in.

How could I do this with plain javascript?

NOTE: This is not intended for use in a production system, but rather intended to be used as a smaller portion of a bigger UX experiment.

Nonattendance answered 29/1, 2018 at 15:4 Comment(19)
Don’t. That is awful UX.Grapher
If you just want to do this for yourself or for fun, knock yourself out, but if you are building something which faces the public, then avoid this as it is not a good user experienceUpturn
Would suggest that a canonical Question/Answer the Answer should contain substantial relevant details as to the subject matter, see What is a canonical question/answer, and what is their purpose?. This Answer currently omits critical details as to how the Web Speech API is actually implemented at different browsers. window.speechSynthesis.getVoices() and onvoiceschanged event usage cannot be ignored for interop.Squander
@MartinBean No, it is not "awful UX", either from an accessibility using multiple variables to open different links or automation perspective. Corp.s are not investing resources into speech synthesis technologies for no reason.Squander
@MartinBean CES 2017: The Year of Voice RecognitionSquander
"greet users with an audio message upon successful login" is surely "awful ux". Although there may be practical reasons to use audio this way, that is not one of them under normal circumstances.Oquassa
@WesleyMurch What are "normal circumstances"? Consider an individual browsing the web who might happen to be vision impaired. How would you suggest to provide a meaningful notification to that user as to a particular functionality, feature or completion of a procedure?Squander
@Bakuriu Then you do not visit *outube for the same reason, yes?Squander
Related: Should I add sound effects to my web site? Why is sound sparingly used on websites? Should we use a sound/jingle when users arrive on our site or open our app?Foal
Consider this; Good UX is when the user expects what your site does. Practically no site greets you upon logging in, and users will not be expecting it. It will be jarring, especially in a public space.Aetiology
@Nonattendance "NOTE: This is not intended for use in a production system, but rather intended to be used as a smaller portion of a bigger UX experiment." Why do you attempt to qualify the premise of your Question in response to comments where you posted an Answer to your own Question? What is the purpose of posting this Question?Squander
@Dukeling The opinion as to "user experience" is an entirely different question than the technical capability of a browser to perform a given task.Squander
@Aetiology Where does OP ask for opinions as to what "Good UX" is at the original Question?Squander
@Squander I didn't post that comment as an answer. I posted it as a response to you arguing about whether it was bad UX.Aetiology
@Squander I did say "related" though, not "duplicates".Foal
@Aetiology There is no "argument". Could care less about others' opinion. The topic of "UX" was initiated a comment, then OP, for a reason known only to themselves, edited the original Question to mention "UX". The actual Question "How can I make my web browser talk?" has absolutely nothing to do with opinion as to "UX".Squander
@Dukeling No, those Questions are not "related". OP does not ask for opinions as to "UX" at the original Question. You cannot massage a topic into the Question that does not appear at the original Question. Will note that, from perspective here, the edit of the original Question to mention "UX" does bring into question the legitimacy of the premise of the Question itself; especially as the Answer by lacks essential components necessary for interop.Squander
@Squander You might want to argue with the people who posted the 9 comments above mine arguing about whether it's good UX - a single comment linking to posts where that is answered is a much cleaner solution and helps to avoid discussion in the comments (at least usually). Although, considering that 5 of those comments are yours, I do find myself a bit confused about your comment.Foal
@Dukeling Again, there is no "argument". We are dealing with facts. Already commented directly to those users as well. Not sure why or how the topic of "UX" is relevant at all (in their opinion) to the actual Question? The fact is that OP did not post the Question at ux . stackexchange, nor ask for opinion as to "UX" at the present Question either.Squander
S
20

For window.speechSynthesis.speak() to render audio output at Chromium browser the user needs to have speech-dispatcher installed and launch the browser with --enable-speech-dispatcher flag.

onvoiceschanged event handler and window.speech.synthesis.getVoices() needs to be called to populate the list of available voices. The API is not straightforward; .getVoices() may need to be called twice for the SpeechSynthesisVoice objects to populate the array returned by .getVoices().

Note that there is a potential for the calls to .speak() to be placed in a queue and not be rendered as audio output, which is not immediately evident; calling window.speechSynthesis.cancel() clears the queue, where the audio output could then be rendered unexpectedly.

You can then use window.speechSynthesis.speak().

Have been trying for some time now to get SSML parsing enabled by default at Chromium browser for *nix; without using an external web service which requires either some form of EUA or is not free as in beer.

The list of entities that have contacted and questions asked to achieve this is quite lengthy, for example

Firefox at *nix also does not parse SSML.

Perhaps with more interest by users at large we can finally get this feature enabled by default.

Though there are workarounds for SSML parsing without using an external web service; this first link below is still unanswered; though includes PHP code that calls the binary using shell_exec() following $_POST to a local server

Note, that there are several bug with the current Web Speech API implementation, notably that changing volume property at SpeechSynthesisUtterance has no effect on audio output at both Chromium and Firefox

There is also a bug when using .pause() and .resume(), which encountered when trying to programmatically parse <break> element of SSML

An alternative to using the apparently dead Web Speech API is speak.js which was created by porting espeak to JavaScript or meSpeak.js, which is a fork of speak.js. espeak-ng is now actively maintained, for example using a modified version of meSpeak.js

or using online dictionaries which serve voice files reflecting the word

Interestingly, after posting that Answer the "gstatic" "dictionary" no longer served the audio files.

Fortunately, we have

This is a web, Android and iOS app for collecting speech donations for the Common Voice project.

which is quite active.


We can also use Native Message at both Chromium/Chrome and Firefox to call interact with the native shell and call the binary itself

this code achieves expected result with minimal modification using Native Messaging

or as a drastic measure, change the binary


(opinion, supported by facts follow)

There is a substantial web service market for speech synthesis technologies, both in the generation thereof ( "[L]yrebird") and the recognition of - for profit i.e.g., "*lexa"; "*olly"; (*bm) "*atson *luemix"; (*oogle) "*ctions"; etc.

It is up to open source developers to continue efforts directed towards maintaining open source (FOSS; FLOSS) speech synthesis technologies at open source browsers. If we want these technologies to be implemented in browsers by default, open source developers have to compose the code to make that happen.

Squander answered 29/1, 2018 at 15:7 Comment(5)
Very thorough. I'd like to add that Safari supports the API everywhere it runs (so yeah, "only" iOS and macOS) and unlike Chromium, does the speech synthesis offline (macOS has had the capability for decades) which enables a couple of time-sensitive features not available with Google's synthesis.Levant
@Levant Have not tried macOS/safari. Yes, noticed that Chromium source code has has *pple copyright for several of the files related to ttsSquander
@Levant macOS/safari does not support SSML parsing by default, correct?Squander
Indeed, as far as I know Safari doesn't support SSML (probably because the underlying MacOS API doesn't either) but that shouldn't be a problem for the OP's simple needs. Plain text should work fine.Levant
@Levant Following the edit to the original Question am not certain what the purpose the Question, nor what the requirement is. Asked you about SSML parsing at macOS/safari to confirm that the functionality is still absent at macOS/safari.Squander
N
6

This is possible with the SpeechSynthesisUtterance interface of the Web Speech API. More info on this here.

The javascript below will say "Welcome John Doe" when executed in Chrome. Make sure the volume is up!

const message = new SpeechSynthesisUtterance('Welcome, John Doe'); 
window.speechSynthesis.speak(message);

The Web Speech API also provides a speech recognition interface. The following code will print spoken words to the browser's console.

const recognition = new webkitSpeechRecognition();
recognition.onresult = function(event) {
  for (let i = event.resultIndex; i < event.results.length; ++i) {
    console.log(event.results[i][0].transcript); 
  }
}

To start capturing speech, run recognition.start();
To stop capturing speech, run recognition.stop();

Given this is experimental technology, it is not going to be perfect, and it is not supported in all browsers and versions. Check the browser compatibility table for supported browsers and versions.

Nonattendance answered 29/1, 2018 at 15:4 Comment(6)
The example should include .getVoices() call, which is not that straightforward to use.Squander
Note, voices are loaded asynchronously. The call to window.speechSynthesis.speak() could occur before the SpeechSynthesisVoice objects have populated the array returned by .getVoices()Squander
Are recognition and synthesis done locally or they use the internet ?Ergotism
@Ergotism Locally. Chrome is shipped with their own version of voices capable of being set and used by SpeechSynthesisUtterance.Squander
@Squander niceErgotism
Well, just spent a few hours trying to get a speech working for the happy new year countdown using string manipulation and hard-coded audios; feeling angry I didn't notice this answer earlier.Dawdle
D
-1

I made a function that makes life easier. You only have to execute the function with a languagecode, for example speak('hello world','en') for English, see other codes

function speak(text, language) {
    const synth = window.speechSynthesis;
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.voice = synth.getVoices().find(voice => voice.lang.split('-')[0].toLowerCase() === language.split('-')[0].toLowerCase());
    synth.speak(utterance);
}

Check the Web_Speech_API documentation

Demos answered 28/5, 2022 at 18:13 Comment(0)
B
-2
const utterance = new SpeechSynthesisUtterance(name);
const voices = speechSynthesis.getVoices();
utterance.voice = voices[0];
speechSynthesis.speak(utterance);
Baloney answered 17/9 at 7:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.