How to change voice in Speech Synthesis?
Asked Answered
R

4

9

I am trying out a simple example with Speechsynthesis.

<script>

voices = window.speechSynthesis.getVoices()
var utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[4];
utterance.lang = voices[4].lang;
window.speechSynthesis.speak(utterance);

</script>

But this gives an error that voices is undefined. I found that getVoices() is loaded async. I saw this answer and updated my code as shown below to use callback.

<script>
window.speechSynthesis.onvoiceschanged = function() {
voices = window.speechSynthesis.getVoices()
var utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[4];
utterance.lang = voices[4].lang;
window.speechSynthesis.speak(utterance);
};
</script>

But due to some strange reason, the text is spoken three times instead of one. How can I fix this code?

Radio answered 9/3, 2017 at 11:46 Comment(0)
C
6

I can't replicate your issue, but try adding an event listener so that your function runs after the voices are loaded.

let voices, utterance;

function speakVoice() {
voices = this.getVoices();
utterance = new SpeechSynthesisUtterance("Hello World");
utterance.voice = voices[1];
speechSynthesis.speak(utterance);
};

speechSynthesis.addEventListener('voiceschanged', speakVoice);
Crus answered 23/3, 2017 at 3:37 Comment(2)
Is there anyway to set voice for all utterances that will be created? Or does it need to be defined for each utterance?Unbar
@Unbar you could probably just create a single utterance, set the voice object and keep updating the utterance text before each speak: let utt = new window.SpeechSynthesisUtterance(); utt.voice = voices[2]; utt.text = 'say this'; speechSynthesis.speak(utt);Crus
H
4

This can be seen on many JS Bin-type demos. For examples:

http://jsbin.com/sazuca/1/edit?html,css,js,output

https://codepen.io/matt-west/pen/wGzuJ

This behaviour is seen in Chrome, which uses the voiceschanged event, when a non-local voice is used. Another effect is that the list of voices is often triplicated.

The W3C specification says:

voiceschanged event

Fired when the contents of the SpeechSynthesisVoiceList, that the getVoices method will return, have changed. Examples include: server-side synthesis where the list is determined asynchronously, or when client-side voices are installed/uninstalled.

...so I presume that the event is fired once when Chrome gets the voices and then twice more when the first non-local voice is used.

Given that there doesn't seem to be a way to distinguish which change is triggering the event I have been using this ugly bit of code:

    // Add voices to dropdown list
    loadVoices();
    // For browsers that use voiceschanged event
    speechSynthesis.onvoiceschanged = function(e) {
        // Load the voices into the dropdown
        loadVoices();
        // Don't add more options when voiceschanged again
        speechSynthesis.onvoiceschanged = null;
    }

Where loadVoices() is the function that adds the voices to a selection's options. It's not ideal, however it does work on all browsers (with speech synthesis) whether they use onvoiceschanged or not.

Holbert answered 23/5, 2017 at 11:5 Comment(0)
A
1

Faced the same problem just now & the solution is pretty easy. Just declare the voices globally not just inside the onclick function & do it two times

utterance.voice = window.speechSynthesis.getVoices()[Math.floor(Math.random()*6)]
setTimeout(() => {
    utterance.voice = window.speechSynthesis.getVoices()[Math.floor(Math.random()*6)]
}, 1000)

The Utterance is variable containing speechSynthesisisUtterance()

The Brave browser only supports 6 types of voices as compared to 24 of chrome, that's why I choose any random voice b/w 1-6.

Allergic answered 20/1, 2023 at 13:46 Comment(0)
S
-3

You can simply add this code and use SpeechSynthesis in your project, it works for me.

var su;

su = new SpeechSynthesisUtterance();

su.text = "Hello World";

speechSynthesis.speak(su);

speechSynthesis.cancel();
Symbolist answered 11/12, 2017 at 11:4 Comment(1)
He's asking how to change the voicePremonition

© 2022 - 2024 — McMap. All rights reserved.