Good day.
I'm having trouble with inconsistencies of my speech synthesis speaking long texts.
I'm trying to make text-to-speech in English and Mandarin. When I specify utterance.lang = 'en-US'; I found out that my article in English is read out until finished. However, when I'm using utterance.lang = 'zh-CN'; my text in English and Mandarin can only read out until 30 words only. I don't know if there's a problem with coding or anything.
The article:
E. Cyclocarpum
Enterolobium cyclocarpum, commonly known as guanacaste, caro caro, or elephant-ear tree, is a species of flowering tree in the pea family. Fabaceae, that is native to tropical regions of the Americas, from the central Mexico south to northern Brazil (Roraima) and Venezuela. It is known for its large proportions, its expansive, often spherical crown, and its curiously shaped seedpods. The abundance of this tree, especially in Guanacaste Province, Costa Rica, where it is prized for the shady relief it provides from the intense sun, coupled with its immensity, have made it a widely recognized species. It is the national tree of Costa Rica.
onload = function() {
if ('speechSynthesis' in window) with(speechSynthesis) {
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
function onClickPlay() {
if(!flag){
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('article').textContent);
utterance.lang = 'zh-CN';
utterance.onend = function(){
flag = false; playEle.className = pauseEle.className = ''; stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) { /* unpause/resume narration */
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}
function onClickPause() {
if(speaking && !paused){ /* pause narration */
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}
function onClickStop() {
if(speaking){ /* stop narration */
/* for safari */
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();
}
}
}
else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}
}
Good day.
I'm having trouble with inconsistencies of my speech synthesis speaking long texts.
I'm trying to make text-to-speech in English and Mandarin. When I specify utterance.lang = 'en-US'; I found out that my article in English is read out until finished. However, when I'm using utterance.lang = 'zh-CN'; my text in English and Mandarin can only read out until 30 words only. I don't know if there's a problem with coding or anything.
The article:
E. Cyclocarpum
Enterolobium cyclocarpum, commonly known as guanacaste, caro caro, or elephant-ear tree, is a species of flowering tree in the pea family. Fabaceae, that is native to tropical regions of the Americas, from the central Mexico south to northern Brazil (Roraima) and Venezuela. It is known for its large proportions, its expansive, often spherical crown, and its curiously shaped seedpods. The abundance of this tree, especially in Guanacaste Province, Costa Rica, where it is prized for the shady relief it provides from the intense sun, coupled with its immensity, have made it a widely recognized species. It is the national tree of Costa Rica.
onload = function() {
if ('speechSynthesis' in window) with(speechSynthesis) {
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);
function onClickPlay() {
if(!flag){
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('article').textContent);
utterance.lang = 'zh-CN';
utterance.onend = function(){
flag = false; playEle.className = pauseEle.className = ''; stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) { /* unpause/resume narration */
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}
function onClickPause() {
if(speaking && !paused){ /* pause narration */
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}
function onClickStop() {
if(speaking){ /* stop narration */
/* for safari */
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();
}
}
}
else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}
}
Share
Improve this question
edited Aug 27, 2019 at 4:11
enhzflep
13.1k2 gold badges34 silver badges52 bronze badges
asked Aug 27, 2019 at 3:32
Serra YaraSerra Yara
531 silver badge6 bronze badges
7
- Could you share the article you were testing on to produce this issue? – vadersfather Commented Aug 27, 2019 at 3:42
- Sure. My article is in php. But this is the article "Enterolobium cyclocarpum, commonly known as guanacaste, caro caro, or elephant-ear tree, is a species of flowering tree in the pea family, Fabaceae, that is native to tropical regions of the Americas, from central Mexico south..." my article is a bit too long. Cannot paste everything here. I dont know why it can only read out until 30 characters only. – Serra Yara Commented Aug 27, 2019 at 3:43
- @SerraYara - Your question says 30 words and this comment, 30 characters. Am I correct in assuming it's 30 words? – enhzflep Commented Aug 27, 2019 at 4:12
- Pardon me. It's actually 30 words. – Serra Yara Commented Aug 27, 2019 at 4:52
- What browser/OS are you using? Presumably Safari? – Frazer Commented Aug 27, 2019 at 8:36
2 Answers
Reset to default 12It's a known bug. The workaround is to issue a resume every 14 seconds.
For your code this means to add the following after 'speak(utterance)':
let r = setInterval(() => {
console.log(speechSynthesis.speaking);
if (!speechSynthesis.speaking) {
clearInterval(r);
} else {
speechSynthesis.resume();
}
}, 14000);
I've recently stumbled upon the issue where speech is cut off after a duration of 14(?) seconds as well. This causes for the synthesis to get stuck in 'speaking' mode, never marking it as done and thus never actually being able to check when it finishes talking. This also makes for all speech-synth options to be blocked until you restart your browser.
This bug only seems to happen when you use the promise options to fetch the voices and languages. If you don't need to option to select and just pre-set them, it seems to be working as should (at least for me).
The solution of Frazer didn't work for me until I also added a pause right before the resume to make it stop for a very short moment and then continue. This cancels the "max 14-second" bug.
With this small tweak added, the code from Frazer would look like:
let r = setInterval(() => {
console.log(speechSynthesis.speaking);
if (!speechSynthesis.speaking) {
clearInterval(r);
} else {
speechSynthesis.pause();
speechSynthesis.resume();
}
}, 14000);