annyang_rails 0.2.0 → 0.2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/app/assets/javascripts/annyang.js +67 -19
- data/lib/annyang_rails/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzE5NzFjZmY0ZTNhZThlOTA2NWExMDJjZGU5Y2VhYmRiYTY5NDY4OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTM1Njc4ZTAxYTgzOTIyYzQxYmIwZWY2MmI2M2I3NjM4YjQwMTk3OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDRhMjgwNGRmNjIyNjc3MjA5ZjhmN2E0YTE4MDc4ZWE3MzkzMzQ5Njk1MDkz
|
10
|
+
MWI5YjQ0NTFjYzE2Y2I1YTQzZDU5MzE5YTQ5MzA3NzdkYTk3N2ExZWU5ZmE1
|
11
|
+
MTNhOWY1NWM1NTJjY2IxM2E1N2VmNzRlNDAzODRjMmUzYWFmYWE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NGE5MTI5NzJkMjM4OThjMTU5OWE1ZTk3ZTdlMGIyOWE5ZWQzZTRjMmIzYjZi
|
14
|
+
M2UxNDVmZWI1ZWNjNDM0MTk4YTlkMDhhN2Q1OWZlZjliMDc0ODg4NzlhODBm
|
15
|
+
ZTk0Y2VhM2RlYTM0YTQ2N2Q1NGE5NDIwM2FhOTUwMGU4YjM4MDI=
|
@@ -1,20 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
* https://github.com/TalAter/annyang
|
7
|
-
*/
|
1
|
+
//! annyang
|
2
|
+
//! version : 0.2.0
|
3
|
+
//! author : Tal Ater @TalAter
|
4
|
+
//! license : MIT
|
5
|
+
//! https://www.TalAter.com/annyang/
|
8
6
|
(function () {
|
9
7
|
"use strict";
|
10
8
|
|
9
|
+
// Save a reference to the global object (window in the browser)
|
11
10
|
var root = this;
|
11
|
+
|
12
|
+
// Get the SpeechRecognition object, while handling browser prefixes
|
12
13
|
var SpeechRecognition = root.webkitSpeechRecognition ||
|
13
14
|
root.mozSpeechRecognition ||
|
14
15
|
root.msSpeechRecognition ||
|
15
16
|
root.oSpeechRecognition ||
|
16
17
|
root.SpeechRecognition;
|
18
|
+
|
17
19
|
// Check browser support
|
20
|
+
// This is done as early as possible, to make it as fast as possible for unsupported browsers
|
18
21
|
if ( !SpeechRecognition ) {
|
19
22
|
root.annyang = null;
|
20
23
|
return null;
|
@@ -23,12 +26,12 @@
|
|
23
26
|
var commandsList;
|
24
27
|
var recognition;
|
25
28
|
var lang = 'en-US';
|
26
|
-
var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [] };
|
29
|
+
var callbacks = { start: [], error: [], end: [], result: [], resultMatch: [], resultNoMatch: [], errorNetwork: [], errorPermissionBlocked: [], errorPermissionDenied: [] };
|
27
30
|
var autoRestart;
|
31
|
+
var lastStartedAt = 0;
|
28
32
|
var debugState = false;
|
29
33
|
var debugStyle = 'font-weight: bold; color: #00f;';
|
30
34
|
|
31
|
-
|
32
35
|
// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
|
33
36
|
var optionalParam = /\s*\((.*?)\)\s*/g;
|
34
37
|
var optionalRegex = /(\(\?:[^)]+\))\?/g;
|
@@ -46,13 +49,17 @@
|
|
46
49
|
return new RegExp('^' + command + '$', 'i');
|
47
50
|
};
|
48
51
|
|
52
|
+
// This method receives an array of callbacks to iterate over, and invokes each of them
|
49
53
|
var invokeCallbacks = function(callbacks) {
|
50
54
|
for (var j = 0, l = callbacks.length; j < l; j++) {
|
51
|
-
callbacks[j].apply(
|
55
|
+
callbacks[j].callback.apply(callbacks[j].context);
|
52
56
|
}
|
53
57
|
};
|
54
58
|
|
55
59
|
root.annyang = {
|
60
|
+
// Initialize annyang with a list of commands to recognize.
|
61
|
+
// e.g. annyang.init({'hello :name': helloFunction})
|
62
|
+
// annyang understands commands with named variables, splats, and optional words.
|
56
63
|
init: function(commands) {
|
57
64
|
|
58
65
|
// Abort previous instances of recognition already running
|
@@ -60,21 +67,48 @@
|
|
60
67
|
recognition.abort();
|
61
68
|
}
|
62
69
|
|
63
|
-
// initiate
|
70
|
+
// initiate SpeechRecognition
|
64
71
|
recognition = new SpeechRecognition();
|
65
72
|
|
73
|
+
// Set the max number of alternative transcripts to try and match with a command
|
66
74
|
recognition.maxAlternatives = 5;
|
67
75
|
recognition.continuous = true;
|
76
|
+
// Sets the language to the default 'en-US'. This can be changed with annyang.setLanguage()
|
68
77
|
recognition.lang = lang;
|
69
78
|
|
70
79
|
recognition.onstart = function() { invokeCallbacks(callbacks.start); };
|
71
80
|
|
72
|
-
recognition.onerror = function()
|
81
|
+
recognition.onerror = function(event) {
|
82
|
+
invokeCallbacks(callbacks.error);
|
83
|
+
switch (event.error) {
|
84
|
+
case 'network':
|
85
|
+
invokeCallbacks(callbacks.errorNetwork);
|
86
|
+
break;
|
87
|
+
case 'not-allowed':
|
88
|
+
case 'service-not-allowed':
|
89
|
+
// if permission to use the mic is denied, turn off auto-restart
|
90
|
+
autoRestart = false;
|
91
|
+
// determine if permission was denied by user or automatically.
|
92
|
+
if (new Date().getTime()-lastStartedAt < 200) {
|
93
|
+
invokeCallbacks(callbacks.errorPermissionBlocked);
|
94
|
+
} else {
|
95
|
+
invokeCallbacks(callbacks.errorPermissionDenied);
|
96
|
+
}
|
97
|
+
break;
|
98
|
+
}
|
99
|
+
};
|
73
100
|
|
74
101
|
recognition.onend = function() {
|
75
102
|
invokeCallbacks(callbacks.end);
|
103
|
+
// annyang will auto restart if it is closed automatically and not by user action.
|
76
104
|
if (autoRestart) {
|
77
|
-
|
105
|
+
// play nicely with the browser, and never restart annyang automatically more than once per second
|
106
|
+
var timeSinceLastStart = new Date().getTime()-lastStartedAt;
|
107
|
+
if (timeSinceLastStart < 1000) {
|
108
|
+
setTimeout(root.annyang.start, 1000-timeSinceLastStart);
|
109
|
+
} else {
|
110
|
+
root.annyang.start();
|
111
|
+
}
|
78
112
|
}
|
79
113
|
};
|
80
114
|
|
@@ -82,12 +116,15 @@
|
|
82
116
|
invokeCallbacks(callbacks.result);
|
83
117
|
var results = event.results[event.resultIndex];
|
84
118
|
var commandText;
|
119
|
+
// go over each of the 5 results and alternative results received (we've set maxAlternatives to 5 above)
|
85
120
|
for (var i = 0; i<results.length; i++) {
|
121
|
+
// the text recognized
|
86
122
|
commandText = results[i].transcript.trim();
|
87
123
|
if (debugState) {
|
88
124
|
root.console.log('Speech recognized: %c'+commandText, debugStyle);
|
89
125
|
}
|
90
126
|
|
127
|
+
// try and match recognized text to one of the commands on the list
|
91
128
|
for (var j = 0, l = commandsList.length; j < l; j++) {
|
92
129
|
var result = commandsList[j].command.exec(commandText);
|
93
130
|
if (result) {
|
@@ -98,6 +135,7 @@
|
|
98
135
|
root.console.log('with parameters', parameters);
|
99
136
|
}
|
100
137
|
}
|
138
|
+
// execute the matched command
|
101
139
|
commandsList[j].callback.apply(this, parameters);
|
102
140
|
invokeCallbacks(callbacks.resultMatch);
|
103
141
|
return true;
|
@@ -113,21 +151,28 @@
|
|
113
151
|
this.addCommands(commands);
|
114
152
|
},
|
115
153
|
|
154
|
+
// Start listening (asking for permission first, if needed).
|
155
|
+
// Call this after you've initialized annyang with commands.
|
156
|
+
// Receives an optional options object:
|
157
|
+
// { autoRestart: true }
|
116
158
|
start: function(options) {
|
117
159
|
options = options || {};
|
118
|
-
if (
|
160
|
+
if (options.autoRestart !== void 0) {
|
119
161
|
autoRestart = !!options.autoRestart;
|
120
162
|
} else {
|
121
163
|
autoRestart = true;
|
122
164
|
}
|
165
|
+
lastStartedAt = new Date().getTime();
|
123
166
|
recognition.start();
|
124
167
|
},
|
125
168
|
|
169
|
+
// abort the listening session (aka stop)
|
126
170
|
abort: function() {
|
127
171
|
autoRestart = false;
|
128
172
|
recognition.abort();
|
129
173
|
},
|
130
174
|
|
175
|
+
// Turn on output of debug messages to the console. Ugly, but super-handy!
|
131
176
|
debug: function(newState) {
|
132
177
|
if (arguments.length > 0) {
|
133
178
|
debugState = !!newState;
|
@@ -136,6 +181,8 @@
|
|
136
181
|
}
|
137
182
|
},
|
138
183
|
|
184
|
+
// Set the language the user will speak in. If not called, defaults to 'en-US'.
|
185
|
+
// e.g. 'fr-FR' (French-France), 'es-CR' (Español-Costa Rica)
|
139
186
|
setLanguage: function(language) {
|
140
187
|
lang = language;
|
141
188
|
if (recognition && recognition.abort) {
|
@@ -143,6 +190,7 @@
|
|
143
190
|
}
|
144
191
|
},
|
145
192
|
|
193
|
+
// Add additional commands that annyang will respond to. Similar in syntax to annyang.init()
|
146
194
|
addCommands: function(commands) {
|
147
195
|
var cb,
|
148
196
|
command;
|
@@ -163,10 +211,10 @@
|
|
163
211
|
}
|
164
212
|
},
|
165
213
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
addCallback: function(type, callback) {
|
214
|
+
// Lets the user add a callback of one of 9 types:
|
215
|
+
// start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied
|
216
|
+
// Can also optionally receive a context for the callback function as the third argument
|
217
|
+
addCallback: function(type, callback, context) {
|
170
218
|
if (callbacks[type] === void 0) {
|
171
219
|
return;
|
172
220
|
}
|
@@ -174,7 +222,7 @@
|
|
174
222
|
if (typeof cb !== 'function') {
|
175
223
|
return;
|
176
224
|
}
|
177
|
-
callbacks[type].push(cb);
|
225
|
+
callbacks[type].push({callback: cb, context: context || this});
|
178
226
|
}
|
179
227
|
};
|
180
228
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: annyang_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.0
|
4
|
+
version: 0.2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guy Israeli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|