Commit 205e858a authored by nextime's avatar nextime

fix chrome voice recognition

parent 91985a0e
...@@ -217,6 +217,16 @@ ...@@ -217,6 +217,16 @@
$.post("/rest/v1.2/actions/speech_text/json", spobj.serialize(), speechResult ); $.post("/rest/v1.2/actions/speech_text/json", spobj.serialize(), speechResult );
} }
function setSpeechText(terms)
{
// XXX Sistema sta cosa!
console.debug("SpeechRecognized: "+terms);
$("#speech [name=text]").val(terms);
$("#speechsm [name=text]").val(terms);
sendSpeech($("#speech"));
}
// Test SpeechAPI // Test SpeechAPI
var speechStartWord='*terms'; var speechStartWord='*terms';
if((speechEnabled=='touch' && document.createElement('input').webkitSpeech==undefined) || speechEnabled=='continuous') if((speechEnabled=='touch' && document.createElement('input').webkitSpeech==undefined) || speechEnabled=='continuous')
...@@ -226,6 +236,7 @@ ...@@ -226,6 +236,7 @@
if(window.annyang) if(window.annyang)
{ {
$("#speechbutton").show(); // it isn't chrome with webkit-speech attribute, but it support WEB Speech API $("#speechbutton").show(); // it isn't chrome with webkit-speech attribute, but it support WEB Speech API
annyang.setCatchAll(setSpeechText);
} }
else else
{ {
...@@ -234,38 +245,33 @@ ...@@ -234,38 +245,33 @@
} }
} else { } else {
$("#speechbutton").hide(); $("#speechbutton").hide();
speechStartWord='ok domotica *terms'; if(window.annyang)
annyang.addCommands({'ok domotica *terms': setSpeechText});
} }
} else { } else {
speechEnabled='touch-chrome'; speechEnabled='touch-chrome';
} }
function setSpeechText(terms)
{
// XXX Sistema sta cosa!
$("#speech [name=text]").val(terms);
$("#speechsm [name=text]").val(terms);
console.debug("SpeechRecognized: "+terms)
sendSpeech($("#speech"));
}
var commands = { var commands = {
speechStartWord: setSpeechText 'hello domotica': function(){console.debug('hello domotika!');}
}; };
if(speechEnabled=='touch' || speechEnabled=='continuous') if(speechEnabled=='touch' || speechEnabled=='continuous')
{ {
try { try {
annyang.init(commands); annyang.addCommands(commands);
} catch(err) { } catch(err) {
annyang=null; annyang=null;
} }
if(annyang) { if(annyang) {
annyang.setLanguage('<?=$_DOMOTIKA['speechlang']?>'); annyang.setLanguage('<?=$_DOMOTIKA['speechlang']?>');
if(speechEnabled=='continuous') if(speechEnabled=='continuous')
annyang.start(); annyang.start({ autoRestart: true });
else if(speechEnabled=='touch') else if(speechEnabled=='touch')
annyang.setContinuous(false); //annyang.setContinuous(false);
$("#speechbutton").click(function() {
annyang.start({ autoRestart: false });
});
} else { } else {
$("#speechbutton").hide(); $("#speechbutton").hide();
speechEnabled='no'; speechEnabled='no';
......
//! annyang //! annyang
//! version : 1.1.0 //! version : 1.4.0
//! author : Tal Ater @TalAter //! author : Tal Ater @TalAter
//! license : MIT //! license : MIT
//! https://www.TalAter.com/annyang/ //! https://www.TalAter.com/annyang/
(function (undefined) { (function (undefined) {
"use strict"; "use strict";
/**
* # Quick Tutorial, Intro and Demos
*
* The quickest way to get started is to visit the [annyang homepage](https://www.talater.com/annyang/).
*
* For a more in-depth look at annyang, read on.
*
* # API Reference
*/
// Save a reference to the global object (window in the browser) // Save a reference to the global object (window in the browser)
var root = this; var root = this;
...@@ -24,6 +35,7 @@ ...@@ -24,6 +35,7 @@
} }
var commandsList = []; var commandsList = [];
var catchAllFunction = function(res) { console.debug("Recognized: "+res);};
var recognition; var recognition;
var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] }; var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };
var autoRestart; var autoRestart;
...@@ -56,15 +68,38 @@ ...@@ -56,15 +68,38 @@
}; };
var initIfNeeded = function() { var initIfNeeded = function() {
if (recognition === undefined) { if (!isInitialized()) {
root.annyang.init({}, false); root.annyang.init({}, false);
} }
}; };
var isInitialized = function() {
return recognition !== undefined;
};
root.annyang = { root.annyang = {
// Initialize annyang with a list of commands to recognize.
// e.g. annyang.init({'hello :name': helloFunction}) /**
// annyang understands commands with named variables, splats, and optional words. * Initialize annyang with a list of commands to recognize.
*
* ### Examples:
*
* var commands = {'hello :name': helloFunction};
* var commands2 = {'hi': helloFunction};
*
* // initialize annyang, overwriting any previously added commands
* annyang.init(commands, true);
* // adds an additional command without removing the previous commands
* annyang.init(commands2, false);
*
* As of v1.1.0 it is no longer required to call init(). Just start() listening whenever you want, and addCommands() whenever, and as often as you like.
*
* @param {Object} commands - Commands that annyang should listen to
* @param {Boolean} [resetCommands=true] - Remove all commands before initializing?
* @method init
* @deprecated
* @see [Commands Object](#commands-object)
*/
init: function(commands, resetCommands) { init: function(commands, resetCommands) {
// resetCommands defaults to true // resetCommands defaults to true
...@@ -74,8 +109,6 @@ ...@@ -74,8 +109,6 @@
resetCommands = !!resetCommands; resetCommands = !!resetCommands;
} }
try {
// Abort previous instances of recognition already running // Abort previous instances of recognition already running
if (recognition && recognition.abort) { if (recognition && recognition.abort) {
recognition.abort(); recognition.abort();
...@@ -85,17 +118,15 @@ ...@@ -85,17 +118,15 @@
recognition = new SpeechRecognition(); recognition = new SpeechRecognition();
// Set the max number of alternative transcripts to try and match with a command // Set the max number of alternative transcripts to try and match with a command
recognition.maxAlternatives = 5; recognition.maxAlternatives = 5;
recognition.continuous = true;
// In HTTPS, turn off continuous mode for faster results.
// In HTTP, turn on continuous mode for much slower results, but no repeating security notices
recognition.continuous = root.location.protocol === 'http:';
// Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage() // Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()
recognition.lang = 'en-US'; recognition.lang = 'en-US';
} catch(err) {
root.annyang = null;
return undefined;
}
recognition.onstart = function() { invokeCallbacks(callbacks.start); }; recognition.onstart = function() { invokeCallbacks(callbacks.start); };
recognition.onerror = function(event) { recognition.onerror = function(event) {
...@@ -163,6 +194,7 @@ ...@@ -163,6 +194,7 @@
} }
} }
invokeCallbacks(callbacks.resultNoMatch); invokeCallbacks(callbacks.resultNoMatch);
catchAllFunction(commandText);
return false; return false;
}; };
...@@ -175,10 +207,20 @@ ...@@ -175,10 +207,20 @@
} }
}, },
// Start listening (asking for permission first, if needed). /**
// Call this after you've initialized annyang with commands. * Start listening.
// Receives an optional options object: * It's a good idea to call this after adding some commands first, but not mandatory.
// { autoRestart: true } *
* Receives an optional options object which currently only supports one option:
* - `autoRestart` (Boolean, default: true) Should annyang restart itself if it is closed indirectly, because of silence or window conflicts?
*
* ### Examples:
* // Start listening, but don't restart automatically
* annyang.start({ autoRestart: false });
*
* @param {Object} [options] - Optional options.
* @method start
*/
start: function(options) { start: function(options) {
initIfNeeded(); initIfNeeded();
options = options || {}; options = options || {};
...@@ -191,14 +233,24 @@ ...@@ -191,14 +233,24 @@
recognition.start(); recognition.start();
}, },
// abort the listening session (aka stop) /**
* Stop listening.
*
* @method abort
*/
abort: function() { abort: function() {
initIfNeeded();
autoRestart = false; autoRestart = false;
if (isInitialized) {
recognition.abort(); recognition.abort();
}
}, },
// Turn on output of debug messages to the console. Ugly, but super-handy! /**
* Turn on output of debug messages to the console. Ugly, but super-handy!
*
* @param {Boolean} [newState=true] - Turn on/off debug messages
* @method debug
*/
debug: function(newState) { debug: function(newState) {
if (arguments.length > 0) { if (arguments.length > 0) {
debugState = !!newState; debugState = !!newState;
...@@ -207,19 +259,43 @@ ...@@ -207,19 +259,43 @@
} }
}, },
// Set the language the user will speak in. If not called, defaults to 'en-US'. /**
// e.g. 'fr-FR' (French-France), 'es-CR' (Español-Costa Rica) * Set the language the user will speak in. If this method is not called, defaults to 'en-US'.
*
* @param {String} language - The language (locale)
* @method setLanguage
* @see [Languages](#languages)
*/
setLanguage: function(language) { setLanguage: function(language) {
initIfNeeded(); initIfNeeded();
recognition.lang = language; recognition.lang = language;
}, },
setContinuous: function(cont) { setMaxAlternatives: function(max) {
initIfNeeded(); initIfNeeded();
recognition.continuous=cont; recognition.maxAlternatives = max;
}, },
// Add additional commands that annyang will respond to. Similar in syntax to annyang.init() setCatchAll: function(func) {
catchAllFunction = func;
},
/**
* Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands.
*
* ### Examples:
*
* var commands = {'hello :name': helloFunction, 'howdy': helloFunction};
* var commands2 = {'hi': helloFunction};
*
* annyang.addCommands(commands);
* annyang.addCommands(commands2);
* // annyang will now listen to all three commands
*
*
* @param {Object} commands - Commands that annyang should listen to
* @method addCommands
* @see [Commands Object](#commands-object)
*/
addCommands: function(commands) { addCommands: function(commands) {
var cb, var cb,
command; command;
...@@ -243,8 +319,33 @@ ...@@ -243,8 +319,33 @@
} }
}, },
// Remove existing commands. Called with a single phrase or an array of phrases /**
* Remove existing commands. Called with a single phrase, array of phrases, or methodically. Pass no params to remove all commands.
*
* ### Examples:
*
* var commands = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction};
*
* // Remove all existing commands
* annyang.removeCommands();
*
* // Add some commands
* annyang.addCommands(commands);
*
* // Don't respond to hello
* annyang.removeCommands('hello');
*
* // Don't respond to howdy or hi
* annyang.removeCommands(['howdy', 'hi']);
*
* @param {String|Array|Undefined} [commandsToRemove] - Commands to remove
* @method removeCommands
*/
removeCommands: function(commandsToRemove) { removeCommands: function(commandsToRemove) {
if (commandsToRemove === undefined) {
commandsList = [];
return;
}
commandsToRemove = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove]; commandsToRemove = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove];
commandsList = commandsList.filter(function(command) { commandsList = commandsList.filter(function(command) {
for (var i = 0; i<commandsToRemove.length; i++) { for (var i = 0; i<commandsToRemove.length; i++) {
...@@ -257,8 +358,27 @@ ...@@ -257,8 +358,27 @@
}, },
// Lets the user add a callback of one of 9 types: // Lets the user add a callback of one of 9 types:
// start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied //
// Can also optionally receive a context for the callback function as the third argument //
/**
* Add a callback function to be called in case one of the following events happens:
*
* start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied.
*
* ### Examples:
*
* annyang.addCallback('error', function () {
* $('.myErrorText').text('There was an error!');
* });
*
* // pass local context to a global function called notConnected
* annyang.addCallback('errorNetwork', notConnected, this);
*
* @param {String} type - Name of event that will trigger this callback
* @param {Function} callback - The function to call when event is triggered
* @param {Object} [context] - Optional context for the callback function
* @method addCallback
*/
addCallback: function(type, callback, context) { addCallback: function(type, callback, context) {
if (callbacks[type] === undefined) { if (callbacks[type] === undefined) {
return; return;
...@@ -272,3 +392,131 @@ ...@@ -272,3 +392,131 @@
}; };
}).call(this); }).call(this);
/**
* # Good to Know
*
* ## Commands Object
*
* Both the [init()]() and addCommands() methods receive a `commands` object.
*
* annyang understands commands with `named variables`, `splats`, and `optional words`.
*
* * Use `named variables` for one word arguments in your command.
* * Use `splats` to capture multi-word text at the end of your command (greedy).
* * Use `optional words` or phrases to define a part of the command as optional.
*
* ### Examples:
*
* <script>
* var commands = {
* // annyang will capture anything after a splat (*) and pass it to the function.
* // e.g. saying "Show me Batman and Robin" will call showFlickr('Batman and Robin');
* 'show me *term': showFlickr,
*
* // A named variable is a one word variable, that can fit anywhere in your command.
* // e.g. saying "calculate October stats" will call calculateStats('October');
* 'calculate :month stats': calculateStats,
*
* // By defining a part of the following command as optional, annyang will respond
* // to both: "say hello to my little friend" as well as "say hello friend"
* 'say hello (to my little) friend': greeting
* };
*
* var showFlickr = function(term) {
* var url = 'http://api.flickr.com/services/rest/?tags='+tag;
* $.getJSON(url);
* }
*
* var calculateStats = function(month) {
* $('#stats').text('Statistics for '+month);
* }
*
* var greeting = function() {
* $('#greeting').text('Hello!');
* }
* </script>
*
* ## Languages
*
* While there isn't an official list of supported languages (cultures? locales?), here is a list based on [anecdotal evidence](http://stackoverflow.com/a/14302134/338039).
*
* * Afrikaans `af`
* * Basque `eu`
* * Bulgarian `bg`
* * Catalan `ca`
* * Arabic (Egypt) `ar-EG`
* * Arabic (Jordan) `ar-JO`
* * Arabic (Kuwait) `ar-KW`
* * Arabic (Lebanon) `ar-LB`
* * Arabic (Qatar) `ar-QA`
* * Arabic (UAE) `ar-AE`
* * Arabic (Morocco) `ar-MA`
* * Arabic (Iraq) `ar-IQ`
* * Arabic (Algeria) `ar-DZ`
* * Arabic (Bahrain) `ar-BH`
* * Arabic (Lybia) `ar-LY`
* * Arabic (Oman) `ar-OM`
* * Arabic (Saudi Arabia) `ar-SA`
* * Arabic (Tunisia) `ar-TN`
* * Arabic (Yemen) `ar-YE`
* * Czech `cs`
* * Dutch `nl-NL`
* * English (Australia) `en-AU`
* * English (Canada) `en-CA`
* * English (India) `en-IN`
* * English (New Zealand) `en-NZ`
* * English (South Africa) `en-ZA`
* * English(UK) `en-GB`
* * English(US) `en-US`
* * Finnish `fi`
* * French `fr-FR`
* * Galician `gl`
* * German `de-DE`
* * Hebrew `he`
* * Hungarian `hu`
* * Icelandic `is`
* * Italian `it-IT`
* * Indonesian `id`
* * Japanese `ja`
* * Korean `ko`
* * Latin `la`
* * Mandarin Chinese `zh-CN`
* * Traditional Taiwan `zh-TW`
* * Simplified China zh-CN `?`
* * Simplified Hong Kong `zh-HK`
* * Yue Chinese (Traditional Hong Kong) `zh-yue`
* * Malaysian `ms-MY`
* * Norwegian `no-NO`
* * Polish `pl`
* * Pig Latin `xx-piglatin`
* * Portuguese `pt-PT`
* * Portuguese (Brasil) `pt-BR`
* * Romanian `ro-RO`
* * Russian `ru`
* * Serbian `sr-SP`
* * Slovak `sk`
* * Spanish (Argentina) `es-AR`
* * Spanish (Bolivia) `es-BO`
* * Spanish (Chile) `es-CL`
* * Spanish (Colombia) `es-CO`
* * Spanish (Costa Rica) `es-CR`
* * Spanish (Dominican Republic) `es-DO`
* * Spanish (Ecuador) `es-EC`
* * Spanish (El Salvador) `es-SV`
* * Spanish (Guatemala) `es-GT`
* * Spanish (Honduras) `es-HN`
* * Spanish (Mexico) `es-MX`
* * Spanish (Nicaragua) `es-NI`
* * Spanish (Panama) `es-PA`
* * Spanish (Paraguay) `es-PY`
* * Spanish (Peru) `es-PE`
* * Spanish (Puerto Rico) `es-PR`
* * Spanish (Spain) `es-ES`
* * Spanish (US) `es-US`
* * Spanish (Uruguay) `es-UY`
* * Spanish (Venezuela) `es-VE`
* * Swedish `sv-SE`
* * Turkish `tr`
* * Zulu `zu`
*/
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -32,9 +32,11 @@ IT_ACTIONS={ ...@@ -32,9 +32,11 @@ IT_ACTIONS={
"giu":c.IKAP_ACT_DOWN, "giu":c.IKAP_ACT_DOWN,
"apri":c.IKAP_ACT_OPEN, "apri":c.IKAP_ACT_OPEN,
"aprire":c.IKAP_ACT_OPEN, "aprire":c.IKAP_ACT_OPEN,
"apre":c.IKAP_ACT_OPEN,
"aprimi":c.IKAP_ACT_OPEN, "aprimi":c.IKAP_ACT_OPEN,
"chiudi":c.IKAP_ACT_CLOSE, "chiudi":c.IKAP_ACT_CLOSE,
"chiudere":c.IKAP_ACT_CLOSE, "chiudere":c.IKAP_ACT_CLOSE,
"chiude":c.IKAP_ACT_CLOSE,
"chiudimi":c.IKAP_ACT_CLOSE, "chiudimi":c.IKAP_ACT_CLOSE,
"alza":c.IKAP_ACT_UP, "alza":c.IKAP_ACT_UP,
"alzare":c.IKAP_ACT_UP, "alzare":c.IKAP_ACT_UP,
...@@ -43,9 +45,11 @@ IT_ACTIONS={ ...@@ -43,9 +45,11 @@ IT_ACTIONS={
"abbassare":c.IKAP_ACT_DOWN, "abbassare":c.IKAP_ACT_DOWN,
"abbassami":c.IKAP_ACT_DOWN, "abbassami":c.IKAP_ACT_DOWN,
"accendi":c.IKAP_ACT_ON, "accendi":c.IKAP_ACT_ON,
"accende":c.IKAP_ACT_ON,
"accendere":c.IKAP_ACT_ON, "accendere":c.IKAP_ACT_ON,
"spegni":c.IKAP_ACT_OFF, "spegni":c.IKAP_ACT_OFF,
"spegnere":c.IKAP_ACT_OFF, "spegnere":c.IKAP_ACT_OFF,
"spegne":c.IKAP_ACT_OFF,
"accendimi":c.IKAP_ACT_ON, "accendimi":c.IKAP_ACT_ON,
"spegnimi":c.IKAP_ACT_OFF, "spegnimi":c.IKAP_ACT_OFF,
"off":c.IKAP_ACT_OFF, "off":c.IKAP_ACT_OFF,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment