macdonst / SpeechRecognitionPlugin

W3C Web Speech API - Speech Recognition plugin for PhoneGap
MIT License
188 stars 97 forks source link

Does not fire on the first hit. Immediately hit the record button again and it works. #46

Open tshade opened 8 years ago

tshade commented 8 years ago

I'm using this code :

var recognition; document.addEventListener('deviceready', ondeviceReady, false);

function ondeviceReady() {

recognition = new SpeechRecognition(); recognition.lang="es"; recognition.onresult = function(event) { if (event.results.length > 0) { var resultado=event.results[0][0].transcript; $("#textbox").val(resultado);

    }
}

}

tested on Android 5.0 ,it does not work on the first record, but works fine on Android 4.4.2 .

munsterlander commented 8 years ago

I am having the same issue. I working my way through the plugin to see what is going on.

Edit: There is something wrong with the java side implementation I think. Unfortunately, after review I was unable to find anything that stood out. I have come up with a JS workaround to make it work with a single button press - this is totally the worst way to fix this though.

function startSpeechProcess(){ 
    setTimeout(function(){ recognition.start(); }, 100);
    recognition.start();
}
kest85 commented 8 years ago

This workaround sometimes works and sometimes not. Is there a better solution?

munsterlander commented 8 years ago

Increase the time from 100 to 500 or even 1000. That made it work everytime for me, but then caused an annoying delay in beeps. Either way, this is a horrible workaround and I wished we could figured out the root cause.

kest85 commented 8 years ago

Longer timeout helps a bit, especialy for slower devices. But sometimes it still do not work, whatever timeout I set. To repeat this issue, you have to test many times, and open app many times on different devices, because when it works - it works, but there are some cases when something happens and it stops working, at least for several retries or till app reloads, so it looks buggy to end users. I hope someone will find the root cause of this behavior and fix.

jcesarmobile commented 8 years ago

I can not reproduce the issue.

In your example you don't call start anywhere

munsterlander commented 8 years ago

You can add recognition.start();, right after: recognition.lang="es"; you will still get the same result that we were all discussing. For whatever reason, for the most recent android update, you have to hit start twice to get it to recognize audio.

I would assume the reason that @tshade did not include that line, is @tshade was showing the init code as anyone can call recognition.start() from anywhere in the app, in the way he initialized the recognizer.

jcesarmobile commented 8 years ago

When you say "The most recent android update", which update do you mean? OP said he was using android 5.0. I can't reproduce on 5.0.2

munsterlander commented 8 years ago

I have the issue on 5.1.1

kest85 commented 8 years ago

This issue exists on most android versions (4.x.x and 5.x.x), at least on Samsung devices, which I use for testing (galaxy s2, s3, s4, s6 edge). I noticed 1 major difference between android 4 and android 5 behavior:

I have read other issues of this plugin: people are blaming "Ok Google" functionality, so I have tried to disable it in phone settings, but it have not fixed the isue. Only after playing with phone settings (voice input and "ok google"), this plugin started bahaving unpredictably and not working 90% of the time, even though I have changed back to default settings... (samsung galaxy s4, android 5.0.1, but I think this is not phone model or OS version issue, because previously it worked fine with double call of start() function)

lincolnberryiii commented 8 years ago

The timeout workaround isn't working for me. However, I did notice that I get almost 100% results if I speak IMMEDIATELY after the beep. I added a prompt to the user if no words are found.

Here is an example based on my approach:

var recording = false;
var spokenInput = '';

function startRecognition() {
    if (!recording) {

        recording = true;
        spokenInput = '';

        var recognition = new SpeechRecognition();

        recognition.onresult = function(event) {
            if (event.results.length > 0) {
                spokenInput = event.results[0][0].transcript;
            }
        };

        recognition.onend = function() {
            recording = false;
            if (spokenInput) {
               alert(spokenInput);
            } else {
                alert('For best results, try speaking immediately after the beep!');
            }
        };

        setTimeout(function() {
            recognition.stop();
        }, 6000); // Force stop  after 6 seconds

        recognition.start();

    }
}