sdkcarlos / artyom.js

A voice control - voice commands - speech recognition and speech synthesis javascript library. Create your own siri,google now or cortana with Google Chrome within your website.
http://sdkcarlos.github.io/sites/artyom.html
MIT License
1.23k stars 370 forks source link

artyom is recognizing the text which spoken by itself #7

Open siva3378 opened 7 years ago

siva3378 commented 7 years ago

While artyom speaks, it is also recognizing the text spoken by itself. I tried to stop/start obeying while it speaks, but it is not working as expected. Is there any way to stop listening while artyom speaks?

window.artyom.say(msg, {
    onStart() {
      window.artyom.dontObey();
    },
    onEnd() {
      window.artyom.obey();
    },
  });
sdkcarlos commented 7 years ago

Confirmed using the following code:

// add command
artyom.on(["hello"]).then((e) => {
    console.log("This shouldn't be executed, however it seems it's executed.")
});

// Start recognition
artyom.initialize({
    lang:"en-GB",// A lot of languages are supported. Read the docs !
    continuous:true,// recognize 1 command and stop listening !
    listen:true, // Start recognizing
    debug:true, // Show everything in the console
    speed:1 // talk normally
});

// Talk
window.artyom.say("Hello, execute hello command, hello. hello. hello", {
    onStart() {
        window.artyom.dontObey();
    },
    onEnd() {
        window.artyom.obey();
    }
});

I'll see what i can do.

yobre commented 7 years ago

+1

yobre commented 7 years ago

Ehi.. i'm solved in this way:

       var initObj = {
           speed: 1,
           lang: "it-IT",
           continuous: false,
           debug: true,
           listen: true // Start to listen commands !
       };

       artyom.say(msg, {
           onStart: function () {
           },
           onEnd: function () {
               artyom.fatality(); // Stop artyom
               setTimeout(function(){
                   artyom.initialize(initObj).then(function () { // re-initialize artyom
                      ......... // do something
                   });
               },250); 
           }
        });
FrancoisDeBellescize commented 7 years ago

Any update to stop listening while artyom is speaking ?

willyyang commented 6 years ago

^ any update? If not this library is ... :/

sdkcarlos commented 6 years ago

Well, after one year I decided to take a look to this problem :v. As someway I don't consider this a bug, as the most suitable environment to use Artyom will be with earphones with Microphone, I decided to not modify the library for this nor just add a new property in the initialization.

Instead the solution, using the latest version of artyom 1.0.6 because that's the only version that exposes the webkitspeechrecognition object internally used by artyom is invoking the abort method of the ArtyomWebkitSpeechRecognition object of your instance of Artyom in the onEnd callback of the method say:

let Assistant = new Artyom();

Assistant.say("Hello, how are you?", {
    onEnd (){
        // Abort the speech recognition when artyom stops talking !
        // This prevents any "hello" command from being executed indefinitely
        Assistant.ArtyomWebkitSpeechRecognition.abort();
    }
});

This solve the mentioned behaviour, when you add a command, for example "hello" and artyom triggers the command that speaks "hello". Artyom will recognize the text spoken by himself and will trigger the command "hello" over and over again. To solve this problem, use the previous snippet e.g:

let Assistant = new Artyom();

Assistant.addCommands({
    indexes: ["Hello", "How are you"],
    action: () => {
        // Then if the command is executed and you say hello again
        // It will enter into an endless loop because artyom is hearing itself
        // again and again ...

        // To prevent this, abort the current queue of the speech recognition instance
        // used by Artyom with the method abort on the onEnd callback of artyom.say:
        Assistant.say("Hello", {
            onEnd (){
                // Abort the speech recognition when artyom stops talking !
                // Then, the command won't be triggered when artyom says hello !
                Assistant.ArtyomWebkitSpeechRecognition.abort();
            }
        });
    }
});

// When artyom says this:
Assistant.say("Hello, how are you?");
// The Hello command will be triggered

It's worth to say, that this feature relies as well on the execution of the onEnd callback. Once the speech synthesis finishes, it's ready to recognize commands. After some tests it works properly, however if someone tries as well and fails, please let me know it.

hmontes commented 6 years ago

Okey. Thank you. Is not the best solution (because we need to add Assistant.ArtyomWebkitSpeechRecognition.abort(); in almost all "Assistant.say" but works.

Thank you 👍

willyyang commented 6 years ago

Thanks @sdkcarlos , will give this a try later

ZvirUSka commented 6 years ago

We can use global variables artyom.when("SPEECH_SYNTHESIS_END",function(){ artyom.ArtyomWebkitSpeechRecognition.abort(); }); I'm interested in the following There are no problems with the PC. But when I use on the phone I have an intersection when performing functions I use global variables to disable and enable the microphone, which would avoid the intersection, approximately so

artyom.when("SPEECH_SYNTHESIS_START",function(err){ if(recognizing){ artyom.fatality(); } });

artyom.when("SPEECH_SYNTHESIS_END",function(err){ artyom.ArtyomWebkitSpeechRecognition.abort(); if(recognizing){ setTimeout(function(){ artyom.initialize(initObj).then(function () { // re-initialize artyom console.log("Started"); // do something }); },0); artyom.clearGarbageCollection(); } });

1x-eng commented 6 years ago

None of the above mentioned solutions worked for me. However, using a callback on an event was the way to go.

artyom.when("SPEECH_SYNTHESIS_START", function(){
    if (artyom.isRecognizing()){
        artyom.dontObey();
    }
});
artyom.when("SPEECH_SYNTHESIS_END", function(){
    if(!artyom.isRecognizing() || !artyom.isSpeaking()){
        artyom.obey();
    }
});

That works like a charm! Artyom is a good sdk. Good work @sdkcarlos!

wipodev commented 4 years ago

well, to solve the problem, what I did was modify the function, execute by adding the following conditional:

`//if artyom is synthesizing voice it will only be able to accept command specified in the initialized

    if (_this.ArtyomProperties.speaking){
        if (voz.indexOf(_this.ArtyomProperties.interruptkeyword) != 0){
            _this.debug("Artyom requires with a interruptkeyword \"" + _this.ArtyomProperties.interruptkeyword + "\" but interrupt was not pronounced.", "warn");
            return;
        }            
    }`

of course add the following property to the ArtyomProperties:

interruptkeyword: 'interrupt'

and it is conditional on the function of initialize:

if (config.hasOwnProperty ("interruptkeyword")) {              this.ArtyomProperties.interruptkeyword = config.interruptkeyword;          }

shiftpi commented 3 years ago

Using the solution of @ZvirUSka seems to do the trick, without the need of defining a callback on each artyom.say:

artyom.when("SPEECH_SYNTHESIS_END", () => {
    artyom.ArtyomWebkitSpeechRecognition.abort();
});

This also works on phones for me (tested with Chrome 86 on Android)