Here is a confusing and wired issue in my code.
I just wrote a simple speech recognition code using web speech API, it works fine.
At each start of the recognition I create and initiate a timer to stop and end the recognition after 14 seconds like this:
recognition.onstart = function(event) {
//Fired when the speech recognition service has begun listening
console.log('SpeechRecognition.onstart');
// start timer at first recognaze firing
if(firstTime === true){
console.log('Entered firstTime block ')
timer = setInterval(stopwatch, 500);
firstTime = false;
function stopwatch() {
secs += 0.5;
console.log(secs);
if(secs >= 14){
clearInterval(timer);
speaking = false;
recognition.stop();
console.log("Timer has stoped!");
}
}
}
}
As you see I clear the interval and stop the recognition after 14 seconds.
Now What if I want to do the exact thing when the user presses the space key on his keyboard? maybe I can execute the exact lines of clearing and stoping the recognition like this:
window.onkeypress = function(event) {
if (event.keyCode == 32) {
console.log("User pressed Space Key");
clearInterval(timer);
speaking = false;
recognition.stop();
console.log("So this should be another way to end the whole thing!");
}
};
This time it doesn't work as expected!
let's have a quick look at the code: (I'll say what is the confusing issue in a second)
JS
// Using a button to initiate the Recognize() crashes the code
function onclicked() {
Recognize();
}
// But if we use a timeout to initiate Recognize() instead of clicking the button the code works fine
// console.log('started')
// setTimeout(function(){
// Recognize();
// }, 4000)
function Recognize() {
var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList;
var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent;
let secs = 0;
let speaking = true;
let firstTime = true;
let timer;
var recognition = new SpeechRecognition();
var speechRecognitionList = new SpeechGrammarList();
recognition.grammars = speechRecognitionList;
recognition.lang = 'en-US';
recognition.continuous = true;
recognition.interimResults = true;
recognition.maxAlternatives = 1;
recognition.start();
window.onkeypress = function(event) {
if (event.keyCode == 32) {
console.log("User pressed Space Key");
clearInterval(timer);
speaking = false;
recognition.stop();
console.log("So this should be another way to end the whole thing!");
}
};
recognition.onresult = function(event) {
window.interim_transcript = '';
window.speechResult = '';
for (var i = event.resultIndex; i < event.results.length; ++i) {
// Verify if the recognized text is the last with the isFinal property
if (event.results[i].isFinal) {
speechResult += event.results[i][0].transcript;
console.log("Final Recognized Speech: ", speechResult);
recognition.stop();
} else {
interim_transcript += event.results[i][0].transcript;
}
}
}
recognition.onspeechend = function() {
recognition.stop();
console.log('Speech ended!');
}
recognition.onend = function(event) {
//Fired when the speech recognition service has disconnected.
console.log('onend executed...');
if(typeof speechResult !== 'undefined'){
console.log('User has spoken something..')
clearInterval(timer);
} else {
if(speaking === true) {
console.log('No speech detected but still we have time, so give user another chance..')
recognition.start();
} else {
//User was silent and the time has finished so he is incorrect
console.log('No speech detected and no time, we failed..')
}
}
};
recognition.onstart = function(event) {
//Fired when the speech recognition service has begun listening
console.log('SpeechRecognition.onstart');
// start timer at first recognaze firing
if(firstTime === true){
console.log('Entered firstTime block ')
timer = setInterval(stopwatch, 500);
firstTime = false;
function stopwatch() {
secs += 0.5;
console.log(secs);
if(secs >= 14){
clearInterval(timer);
speaking = false;
recognition.stop();
console.log("Timer has stoped!");
}
}
}
}
};
HTML
<!DOCTYPE html>
<html>
<body>
<button onclick="onclicked()">Click me</button>
</body>
</html>
Using a button to initiate the Recognize()
crashes the code but using a timeout to initiate Recognize()
instead of clicking the button work as expected!
Please use CodePen to test this:https://codepen.io/pixy-dixy/pen/rNaRmOX?editors=0010
Why does this unexpected behavior happen? Am I missing something? Please help I'm so much confused :(
UPDATE: It seems that code works fine in both scenarios only if I click the blank part of the page (Not the button) before pressing the space key!