I'm using the speech synthesis API on Android-Chrome. The issue is that although there are 4 English voices available, it is always US English that is used by the browser, no matter what the code specifies. I can use other languages e.g. French, just not other English voices e.g en-AU, GB, or IN.
This code filters British English voice objects from the getVoices array and uses the first to utter the word 'tomato'. The problem is that the word is always pronounced "to-may-lo" not "to-mar-to" which means my text doesn't rhyme as it should.
The voice object that was used is displayed and (on the phones I've tried) is an GB one.
The html...
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Let's not call the whole thing off</title>
<script src="tomato.js" defer></script>
</head>
<body>
<div id="tomato" lang="en-GB">Tomato</div>
<div id="platform"></div>
</body>
</html>
And the script...
var platform = document.getElementById("platform");
var tomato = document.getElementById("tomato");
var voices = [];
var voicesGB = [];
voices = speechSynthesis.getVoices();
speechSynthesis.onvoiceschanged = function() {
voices = speechSynthesis.getVoices();
voicesGB = voices.filter(voice => /en(-|_)GB/.test(voice.lang));
};
function speak(word) {
var msg = new SpeechSynthesisUtterance();
msg.default = false;
msg.text = word;
msg.voice = voicesGB[0];
msg.lang = voicesGB[0].lang;
window.speechSynthesis.speak(msg);
for (var p in msg.voice) {
platform.innerHTML += p + ': ' + msg.voice[p] + '<br>\n';
}
}
tomato.addEventListener("click",() => {speak('tomato');});
And a jsbin: ,js,output Run this in Android Chrome and tap the word 'tomato'.
I have searched all over and tried various fixes. How do you control what voice Android-Chrome uses?
I'm using the speech synthesis API on Android-Chrome. The issue is that although there are 4 English voices available, it is always US English that is used by the browser, no matter what the code specifies. I can use other languages e.g. French, just not other English voices e.g en-AU, GB, or IN.
This code filters British English voice objects from the getVoices array and uses the first to utter the word 'tomato'. The problem is that the word is always pronounced "to-may-lo" not "to-mar-to" which means my text doesn't rhyme as it should.
The voice object that was used is displayed and (on the phones I've tried) is an GB one.
The html...
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Let's not call the whole thing off</title>
<script src="tomato.js" defer></script>
</head>
<body>
<div id="tomato" lang="en-GB">Tomato</div>
<div id="platform"></div>
</body>
</html>
And the script...
var platform = document.getElementById("platform");
var tomato = document.getElementById("tomato");
var voices = [];
var voicesGB = [];
voices = speechSynthesis.getVoices();
speechSynthesis.onvoiceschanged = function() {
voices = speechSynthesis.getVoices();
voicesGB = voices.filter(voice => /en(-|_)GB/.test(voice.lang));
};
function speak(word) {
var msg = new SpeechSynthesisUtterance();
msg.default = false;
msg.text = word;
msg.voice = voicesGB[0];
msg.lang = voicesGB[0].lang;
window.speechSynthesis.speak(msg);
for (var p in msg.voice) {
platform.innerHTML += p + ': ' + msg.voice[p] + '<br>\n';
}
}
tomato.addEventListener("click",() => {speak('tomato');});
And a jsbin: https://jsbin./xefukemuga/edit?html,js,output Run this in Android Chrome and tap the word 'tomato'.
I have searched all over and tried various fixes. How do you control what voice Android-Chrome uses?
The only way to work around this issue on Android version 5.0.2 is to change the default voice in the Android settings and then restart the device. That will let you use the voice you want, but the other English ones will then be unavailable. Here is some more detail:
SpeechSynthesis.getVoices() will return several options for English (United States, Australia, Nigeria, India, and United Kingdom) but only one is available at a time. You can pick which one by going to the Settings app, then Controls->Language and input->Text-to-speech options. Select the gear icon next to Google Text-to-speech Engine, then under Language you can update the exact locale you want to use. If you select "Install voice data" you can even select from a sample of different voices for some locales. You need to restart the device after changing this setting for it to take effect.
The voice used on an Android device when you play a SpeechSynthesisUtterance will depend on what you have selected in the Android settings. You can choose which language you want to play from javascript (see below for details) but you have no control over the locale or exact voice used.
This problem occurs on Chrome and Firefox, so it is likely a problem with the Android platform's implementation of the speechSynthesis API. It's unlikely that a browser update will fix this, but different versions of Android might. (My test device is on Android 5.0.2, so if this is fixed in a future update, please let me know).
With the latest version of Android (13) you can switch the system settings (System -> Languages & input -> Text-to-speech output). If you change the language to "English (United Kingdom)" you can then use that in your web app. This is obviously not ideal for your users, but if you are developing an app only for yourself, it works great.