Download Jar. Libraryless. Click here for Pure Java version (14048L/102K).
1 | !7 |
2 | |
3 | sbool autoClose = true; |
4 | static int initialDelay = 0; |
5 | sbool infoBox, repeatEverything; |
6 | |
7 | static int port; |
8 | static O onUtterance; // voidfunc(S) |
9 | static L<S> botsToSendUtterancesTo = ll("Voice Actions.", "Show Item Page.");
|
10 | static L<S> functionsToSendTo = ll(); |
11 | static L<WebSocket> webSockets = synchroList(); |
12 | sbool startRecognition; |
13 | static java.util.Timer stopper; |
14 | sS language = "en-US"; |
15 | sS myURL; |
16 | static JButton btn; |
17 | sbool hadAnyWebSockets; // Does Chrome work at all? |
18 | |
19 | p {
|
20 | botsToSendUtterancesTo = persistentList("Bots to send utterances to", botsToSendUtterancesTo);
|
21 | functionsToSendTo = persistentList("Fuctions to send to", botsToSendUtterancesTo);
|
22 | load('language);
|
23 | if (isMainProgram()) |
24 | infoBox = repeatEverything = true; |
25 | NanoHTTPD.SOCKET_READ_TIMEOUT = 24*3600*1000; // not long enough - TODO: Fix in NanoHTTPD |
26 | |
27 | port = serveHttpWithWebSockets(9999, func(NanoHTTPD.IHTTPSession handshake) {
|
28 | WebSocket ws = new WebSocket(handshake) {
|
29 | protected void onPong(WebSocketFrame pongFrame) { print("pong"); }
|
30 | protected void onMessage(WebSocketFrame messageFrame) {
|
31 | cancelTimeout(); |
32 | fS s = messageFrame.getTextPayload(); |
33 | thread {
|
34 | if (repeatEverything) sendOptInNewThread("Mouth.", infoBoxAndReturn(/*switcheroo*/(s)));
|
35 | else infoBoxOrPrint("User said: " + s, infoBox);
|
36 | pcallF(onUtterance, s); |
37 | for (S bot : cloneList(botsToSendUtterancesTo)) {
|
38 | print("Sending to bot " + bot);
|
39 | sendOptInNewThread(bot, "User said: *", s); |
40 | } |
41 | for (fS sf : cloneList(functionsToSendTo)) thread {
|
42 | makeAndCall(sf, s); |
43 | } |
44 | } |
45 | } |
46 | protected void onClose(WebSocketFrame.CloseCode code, String reason, boolean initiatedByRemote) { webSockets.remove(this); }
|
47 | protected void onException(IOException e) { printStackTrace(e); }
|
48 | }; |
49 | if (startRecognition) {
|
50 | startRecognition = false; |
51 | ws.send("start");
|
52 | } |
53 | |
54 | // close any other recognizers |
55 | for (WebSocket ws2 : cloneList(webSockets)) {
|
56 | pcall { ws2.close(WebSocketFrame.CloseCode.NormalClosure, ""); }
|
57 | webSockets.remove(ws2); |
58 | } |
59 | |
60 | hadAnyWebSockets = true; |
61 | |
62 | ret addAndReturn(webSockets, ws); |
63 | }); |
64 | myURL = print("http://localhost:" + port + "/popup");
|
65 | startChromeApp(myURL); |
66 | makeBot("Chrome Speech.");
|
67 | |
68 | showControls(jcenteredline(btn = jbutton("Open Speech Recognizer", r {
|
69 | startChromeApp(myURL) |
70 | }))); |
71 | awtEvery(btn, 500, r { setEnabled(btn, empty(webSockets)) });
|
72 | |
73 | /*thread "Chrome Re-Starter" {
|
74 | sleepSeconds(20); |
75 | repeat with sleep 5 {
|
76 | if (hadAnyWebSockets && empty(webSockets)) {
|
77 | startChromeApp(myURL); |
78 | sleepSeconds(15); |
79 | } |
80 | } |
81 | });*/ |
82 | } |
83 | |
84 | html {
|
85 | if (neq(uri, "/popup")) |
86 | ret hbody("Opening popup..." + hjavascript([[
|
87 | window.open('/popup', 'speech_recognizer', 'width=300,height=300,location=no');
|
88 | setTimeout(function() { window.close(); }, 10000);
|
89 | ]])); |
90 | |
91 | ret hhtml(hhead(htitle("Speech Recognizer")) + hbody(div(
|
92 | h3("Speech Recognizer")
|
93 | + loadJQuery() |
94 | + hdiv("Language: " + language, id := 'lang, style := "font-size: 10px")
|
95 | + hdiv("Results come here", id := 'results, style := "margin: 10px")
|
96 | + hjavascript([[ |
97 | var websocket; |
98 | |
99 | function stopRecognition() {
|
100 | recognition.stop(); |
101 | started = false; |
102 | $("#btn").html("Start recognition");
|
103 | document.title = "Speech Recognizer"; |
104 | } |
105 | |
106 | function startRecognition() {
|
107 | recognition.start(); |
108 | started = true; |
109 | $("#btn").html("Stop recognition");
|
110 | document.title = "Listening - Speech Recognizer"; |
111 | } |
112 | |
113 | function openWebSocket() {
|
114 | websocket = new WebSocket("ws://localhost:#PORT#/");
|
115 | websocket.onopen = function(event) {
|
116 | $("#btn").prop('disabled', false);
|
117 | }; |
118 | |
119 | websocket.onmessage = function(event) {
|
120 | if (event.data == 'start' && !started) startOrStop(); |
121 | if (event.data == 'stop' && started) startOrStop(); |
122 | if (event.data.substring(0, 9) == 'language ') {
|
123 | var l = event.data.substring(9); |
124 | recognition.lang = l; |
125 | $("#lang").html("Language: " + l);
|
126 | } |
127 | }; |
128 | |
129 | websocket.onclose = function(event) {
|
130 | $("#results").html("WebSocket closed");
|
131 | if (#AUTOCLOSE#) window.close(); |
132 | }; |
133 | } |
134 | |
135 | setTimeout(openWebSocket, #INITIALDELAY#); |
136 | |
137 | var recognition = new webkitSpeechRecognition(); |
138 | recognition.lang = "#LANGUAGE#"; |
139 | |
140 | recognition.onerror = function(event) {
|
141 | $("#results").html("Error: " + event.error);
|
142 | stopRecognition(); |
143 | } |
144 | |
145 | recognition.onresult = function(event) {
|
146 | var result = event.results[0]; |
147 | var transcript = result[0].transcript; |
148 | $("#results").html("Transcript: " + transcript);
|
149 | websocket.send(transcript); |
150 | stopRecognition(); |
151 | } |
152 | |
153 | recognition.onnomatch = function(event) {
|
154 | $("#results").html("-");
|
155 | stopRecognition(); |
156 | } |
157 | |
158 | var started = false; |
159 | |
160 | function startOrStop() {
|
161 | if (started) stopRecognition(); else {
|
162 | stopRecognition(); startRecognition(); |
163 | } |
164 | } |
165 | |
166 | window.resizeTo(300, 300); |
167 | ]]).replace("#PORT#", str(port)).replace("#AUTOCLOSE#", autoClose ? "true" : "false").replace("#INITIALDELAY#", str(initialDelay)).replace("#LANGUAGE#", language)
|
168 | + tag('button, "Start recognition", onclick := "startOrStop()", type := 'button, id := 'btn, disabled := 'disabled)
|
169 | //+ p(ahref("#", "Popup", onClick := "window.open('/', 'speech_recognizer', 'width=300,height=300,location=no'); return false;"));
|
170 | , style := "text-align: center")); |
171 | } |
172 | |
173 | svoid startRecognition {
|
174 | L<WebSocket> l = cloneList(webSockets); |
175 | if (empty(l)) startRecognition = true; |
176 | else {
|
177 | //print("Starting recognition." + (l(l) > 1 ? "Weird: Have " + l(l) + " websockets" : ""));
|
178 | pcall {
|
179 | first(l).send("start");
|
180 | } |
181 | } |
182 | } |
183 | |
184 | svoid stopRecognition {
|
185 | if (startRecognition) startRecognition = false; |
186 | if (nempty(webSockets)) pcall {
|
187 | first(webSockets).send("stop");
|
188 | } |
189 | } |
190 | |
191 | answer {
|
192 | if "start recognition timeout *" {
|
193 | final int seconds = parseInt($1); |
194 | startRecognition(); |
195 | stopper = timerOnce(toMS(seconds), f stopRecognition); |
196 | ret "OK"; |
197 | } |
198 | if "start recognition" { startRecognition(); ret "OK"; }
|
199 | if "stop recognition" { stopRecognition(); ret "OK"; }
|
200 | if "send to bot *" { setAdd(botsToSendUtterancesTo, $1); ret "OK"; }
|
201 | if "what bots are you sending to" ret sfu(botsToSendUtterancesTo); |
202 | if "clear send list" { clear(botsToSendUtterancesTo); ret "OK"; }
|
203 | |
204 | if "send to function *" { setAdd(functionsToSendTo, $1); ret "OK"; }
|
205 | if "what functions are you sending to" ret sfu(functionsToSendTo); |
206 | if "clear functions list" { clear(functionsToSendTo); ret "OK"; }
|
207 | if "language *" {
|
208 | setAndSave('language, $1);
|
209 | pcall { if (nempty(webSockets)) first(webSockets).send("language " + $1); }
|
210 | ret "OK"; |
211 | } |
212 | } |
213 | |
214 | svoid cancelTimeout {
|
215 | if (stopper != null) { stopper.cancel(); stopper = null; }
|
216 | } |
Began life as a copy of #1009223
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, wtqryiryparv
No comments. add comment
| Snippet ID: | #1009555 |
| Snippet name: | Chrome Speech Recognition Page + WebSocket [WORKS] |
| Eternal ID of this version: | #1009555/107 |
| Text MD5: | 5c14fca2dc288b4f79ab88e9d3a515b5 |
| Transpilation MD5: | 3f59c755a65030a0c396e89b1298ab2a |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX source code (desktop) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2017-10-06 02:43:17 |
| Source code size: | 7271 bytes / 216 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 1071 / 3291 |
| Version history: | 106 change(s) |
| Referenced in: | [show references] |