Reputation: 95
I try to realize a small web page with a javascript, that allows to playback a spechsynthesis part from text in between two mp3.
As for whatever reason the onend statement of the spoken part does not work, I wanted to create a recursive function, that helps me. For that, I use the "speaking" methode of the SpeechSynthesis. But for whatever reason, speaking is never true.
I debugged and also tried several statements (see code), but it never ever turns out to be true. Is there something with the code? Otherwise, how to report a bug of this library?
function doSpeech() {
var synth = window.speechSynthesis;
var utterance1 = new SpeechSynthesisUtterance('How about we say this now? This is quite a long sentence to say.');
var utterance2 = new SpeechSynthesisUtterance('We should say another sentence too, just to be on the safe side.');
synth.speak(utterance1);
if(synth.speaking){
doNothing();
}else{
playEnd();
}
playEnd() just plays an mp3 if synth is speaking. Please note, when I put playEnd() in the if statement, it won't play. I can put whatever code in there, it is never reached, as synth.speaking will never be true. This example is close to the example of Mozilla foundations documentation on this (https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis/speaking). I wanted to test it, as the recursion never worked.
EDIT: Recursion still won't do it in my specific coding. Am I missing something here?
function doSpeech() {
var synth = window.speechSynthesis;
var speech = new SpeechSynthesisUtterance();
speech.text = getText();
speech.lang = "en-US";
speech.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == 'Google UK English Male'; })[0];
speech.addEventListener('start', function(){
speechEndLoop(synth);
});
synth.speak(speech);
}
function speechEndLoop(x) {
if (x.speaking) {
speechEndLoop(x);
} else {
playEnd();
}
}
Upvotes: 1
Views: 2159
Reputation: 3065
It works perfectly, the problem is that according to your code you are verifying immediately for the status. This may be a problem because it depends on how the API is converting the text to audio (using the local text to speech of the operative system or using the google servers):
function doSpeech() {
var synth = window.speechSynthesis;
var utterance1 = new SpeechSynthesisUtterance('How about we say this now? This is quite a long sentence to say. Make it longer !');
var utterance2 = new SpeechSynthesisUtterance('We should say another sentence too, just to be on the safe side. even longer !');
synth.speak(utterance1);
// If you check immediately (js code executed in less than ms) the
// status won't be true
if (synth.speaking) {
console.log("This is usually printed, if the utterance uses the default voice of the browser (native)");
}
// Wait 500ms to check for the status of the utterance
setTimeout(function(){
if (synth.speaking) {
console.log("This will be printed if starts after 500ms :)");
}
}, 500);
}
doSpeech();
In my case, both of the console.log statements are being printed. But if in your case it isn't being printed, execute your code only after the start event of the utterance:
function doSpeech() {
var synth = window.speechSynthesis;
var msg = new SpeechSynthesisUtterance();
msg.text = "We should say another sentence too, just to be on the safe side. even longer !";
msg.addEventListener('start', function () {
if(synth.speaking){
console.log("This will be printed !");
}
});
synth.speak(msg);
}
doSpeech();
Is pretty nice to work with the plain API by yourself, but if you want something more robust to solve the text to speech problem, i recommend you to use the JS Library Artyom.js, it offers a pretty nice wrapper for the Speech Synthesis API. Even with this library you will see the same behaviour:
function doSpeech() {
let assistant = new Artyom();
assistant.say('How about we say this now? This is quite a long sentence to say. Make it longer !', {
onStart: function() {
if(assistant.isSpeaking()){
console.log("This will be shown");
}
}
});
if(assistant.isSpeaking()){
console.log("This won't appear !");
}
}
doSpeech();
Upvotes: 1