Libraryless. Click here for Pure Java version (2090L/17K/55K).
1 | !752 |
2 | |
3 | !include #1002931 // Pivo Logic (include) |
4 | |
5 | p { |
6 | pivoLoad(); |
7 | } |
8 | |
9 | static S rawLink(S pageName) { |
10 | ret "/" + parseSnippetID(getProgramID()) + "/raw/" + pageName; |
11 | } |
12 | |
13 | static S html(S uri, Map<S, S> params) { |
14 | if (eq(uri, "/has-speech")) { |
15 | S s = params.get("q"); |
16 | ((ThreadLocal<Boolean>) get(getMainBot(), "attn")).set(true); |
17 | pivoMode. set(true); |
18 | S text = //askSelf(s); |
19 | callStaticAnswerMethod(mc(), s); |
20 | if (empty(text)) ret ""; |
21 | S soundURL = getSoundURLCereproc(text, voice); |
22 | S html = [[ |
23 | <audio controls autoplay> |
24 | <source src="SRC" type="audio/mpeg"> |
25 | ! Kein Ton im Browser ! |
26 | </audio> |
27 | ]]; |
28 | html = html.replace("SRC", htmlencode(soundURL)); |
29 | ret "Speech: " + htmlencode(text) + "<br>" + html; |
30 | } |
31 | |
32 | if (eq(uri, "/empty")) { |
33 | ret ""; |
34 | } |
35 | |
36 | if (eq(uri, "/upper")) { |
37 | S html = [=[ |
38 | <!DOCTYPE html> |
39 | <meta charset="utf-8"> |
40 | <title>TinyBrain Speech Demo</title> |
41 | <style> |
42 | * { |
43 | font-family: Verdana, Arial, sans-serif; |
44 | } |
45 | a:link { |
46 | color:#000; |
47 | text-decoration: none; |
48 | } |
49 | a:visited { |
50 | color:#000; |
51 | } |
52 | a:hover { |
53 | color:#33F; |
54 | } |
55 | .button { |
56 | background: -webkit-linear-gradient(top,#008dfd 0,#0370ea 100%); |
57 | border: 1px solid #076bd2; |
58 | border-radius: 3px; |
59 | color: #fff; |
60 | display: none; |
61 | font-size: 13px; |
62 | font-weight: bold; |
63 | line-height: 1.3; |
64 | padding: 8px 25px; |
65 | text-align: center; |
66 | text-shadow: 1px 1px 1px #076bd2; |
67 | letter-spacing: normal; |
68 | } |
69 | .center { |
70 | padding: 10px; |
71 | text-align: center; |
72 | } |
73 | .final { |
74 | color: black; |
75 | padding-right: 3px; |
76 | } |
77 | .interim { |
78 | color: gray; |
79 | } |
80 | .info { |
81 | font-size: 34px; |
82 | text-align: center; |
83 | color: #777; |
84 | display: none; |
85 | } |
86 | .right { |
87 | float: right; |
88 | } |
89 | .sidebyside { |
90 | display: inline-block; |
91 | width: 45%; |
92 | min-height: 40px; |
93 | text-align: left; |
94 | vertical-align: top; |
95 | } |
96 | #headline { |
97 | font-size: 80px; |
98 | font-weight: 300; |
99 | } |
100 | #info { |
101 | font-size: 50px; |
102 | text-align: center; |
103 | color: #777; |
104 | visibility: hidden; |
105 | } |
106 | #results { |
107 | font-size: 55px; |
108 | font-weight: bold; |
109 | border: 1px solid #ddd; |
110 | padding: 15px; |
111 | text-align: left; |
112 | min-height: 50px; |
113 | } |
114 | #start_button { |
115 | border: 0; background-color:transparent; |
116 | padding: 0; |
117 | } |
118 | </style> |
119 | |
120 | <div id="info"> |
121 | <p id="info_start">Click on the microphone icon and begin speaking.</p> |
122 | <p id="info_speak_now">Speak after the bleep.</p> |
123 | <p id="info_no_speech">No speech was detected</p> |
124 | <p id="info_no_microphone" style="display:none"> |
125 | No microphone was found. Ensure that a microphone is installed and that |
126 | <a href="//support.google.com/chrome/bin/answer.py?hl=en&answer=1407892"> |
127 | microphone settings</a> are configured correctly.</p> |
128 | <p id="info_allow">Click the "Allow" button.</p> |
129 | <p id="info_denied">Permission to use microphone was denied.</p> |
130 | <p id="info_blocked">Permission to use microphone is blocked. To change, |
131 | go to chrome://settings/contentExceptions#media-stream</p> |
132 | <p id="info_upgrade">Web Speech API is not supported by this browser. |
133 | Upgrade to <a href="//www.google.com/chrome">Chrome</a> |
134 | version 25 or later.</p> |
135 | </div> |
136 | <div class="right"> |
137 | <button id="start_button" onclick="startButton(event)"> |
138 | <img id="start_img" src="http://tinybrain.de:8080/speech/mic.gif" width="120" alt="Start"></button> |
139 | </div> |
140 | <div id="results"> |
141 | <span id="final_span" class="final"></span> |
142 | <span id="interim_span" class="interim"></span> |
143 | <p> |
144 | </div> |
145 | <div class="center"> |
146 | <p> |
147 | <div id="div_language"> |
148 | <?= $mode ?> |
149 | |
150 | <select id="select_language" onchange="updateCountry()"></select> |
151 | |
152 | <select id="select_dialect"></select> |
153 | </div> |
154 | </div> |
155 | <script> |
156 | var langs = |
157 | [['Afrikaans', ['af-ZA']], |
158 | ['Bahasa Indonesia',['id-ID']], |
159 | ['Bahasa Melayu', ['ms-MY']], |
160 | ['Català', ['ca-ES']], |
161 | ['?eština', ['cs-CZ']], |
162 | ['Deutsch', ['de-DE']], |
163 | ['English', ['en-AU', 'Australia'], |
164 | ['en-CA', 'Canada'], |
165 | ['en-IN', 'India'], |
166 | ['en-NZ', 'New Zealand'], |
167 | ['en-ZA', 'South Africa'], |
168 | ['en-GB', 'United Kingdom'], |
169 | ['en-US', 'United States']], |
170 | ['Español', ['es-AR', 'Argentina'], |
171 | ['es-BO', 'Bolivia'], |
172 | ['es-CL', 'Chile'], |
173 | ['es-CO', 'Colombia'], |
174 | ['es-CR', 'Costa Rica'], |
175 | ['es-EC', 'Ecuador'], |
176 | ['es-SV', 'El Salvador'], |
177 | ['es-ES', 'España'], |
178 | ['es-US', 'Estados Unidos'], |
179 | ['es-GT', 'Guatemala'], |
180 | ['es-HN', 'Honduras'], |
181 | ['es-MX', 'México'], |
182 | ['es-NI', 'Nicaragua'], |
183 | ['es-PA', 'Panamá'], |
184 | ['es-PY', 'Paraguay'], |
185 | ['es-PE', 'Perú'], |
186 | ['es-PR', 'Puerto Rico'], |
187 | ['es-DO', 'República Dominicana'], |
188 | ['es-UY', 'Uruguay'], |
189 | ['es-VE', 'Venezuela']], |
190 | ['Euskara', ['eu-ES']], |
191 | ['Français', ['fr-FR']], |
192 | ['Galego', ['gl-ES']], |
193 | ['Hrvatski', ['hr_HR']], |
194 | ['IsiZulu', ['zu-ZA']], |
195 | ['Íslenska', ['is-IS']], |
196 | ['Italiano', ['it-IT', 'Italia'], |
197 | ['it-CH', 'Svizzera']], |
198 | ['Magyar', ['hu-HU']], |
199 | ['Nederlands', ['nl-NL']], |
200 | ['Norsk bokmål', ['nb-NO']], |
201 | ['Polski', ['pl-PL']], |
202 | ['Português', ['pt-BR', 'Brasil'], |
203 | ['pt-PT', 'Portugal']], |
204 | ['Român?', ['ro-RO']], |
205 | ['Sloven?ina', ['sk-SK']], |
206 | ['Suomi', ['fi-FI']], |
207 | ['Svenska', ['sv-SE']], |
208 | ['Türkçe', ['tr-TR']], |
209 | ['?????????', ['bg-BG']], |
210 | ['P??????', ['ru-RU']], |
211 | ['??????', ['sr-RS']], |
212 | ['???', ['ko-KR']], |
213 | ['??', ['cmn-Hans-CN', '??? (????)'], |
214 | ['cmn-Hans-HK', '??? (??)'], |
215 | ['cmn-Hant-TW', '?? (??)'], |
216 | ['yue-Hant-HK', '?? (??)']], |
217 | ['???', ['ja-JP']], |
218 | ['Lingua lat?na', ['la']]]; |
219 | |
220 | for (var i = 0; i < langs.length; i++) { |
221 | select_language.options[i] = new Option(langs[i][0], i); |
222 | } |
223 | select_language.selectedIndex = 5; |
224 | updateCountry(); |
225 | select_dialect.selectedIndex = 6; |
226 | showInfo('info_start'); |
227 | |
228 | function updateCountry() { |
229 | for (var i = select_dialect.options.length - 1; i >= 0; i--) { |
230 | select_dialect.remove(i); |
231 | } |
232 | var list = langs[select_language.selectedIndex]; |
233 | for (var i = 1; i < list.length; i++) { |
234 | select_dialect.options.add(new Option(list[i][1], list[i][0])); |
235 | } |
236 | select_dialect.style.visibility = list[1].length == 1 ? 'hidden' : 'visible'; |
237 | } |
238 | |
239 | var final_transcript = ''; |
240 | var recognizing = false; |
241 | var ignore_onend; |
242 | var ignore_result; |
243 | var start_timestamp; |
244 | if (!('webkitSpeechRecognition' in window)) { |
245 | upgrade(); |
246 | } else { |
247 | var contentFrame = parent.contentframe; |
248 | var lastText = ""; |
249 | |
250 | start_button.style.display = 'inline-block'; |
251 | var recognition = new webkitSpeechRecognition(); |
252 | recognition.continuous = false; // TRUE |
253 | recognition.interimResults = false; |
254 | |
255 | recognition.onstart = function() { |
256 | recognizing = true; |
257 | showInfo('info_speak_now'); |
258 | start_img.src = 'http://tinybrain.de:8080/speech/mic-animate.gif'; |
259 | }; |
260 | |
261 | recognition.onerror = function(event) { |
262 | if (event.error == 'no-speech') { |
263 | start_img.src = 'http://tinybrain.de:8080/speech/mic.gif'; |
264 | showInfo('info_no_speech'); |
265 | ignore_onend = true; |
266 | } |
267 | if (event.error == 'audio-capture') { |
268 | start_img.src = 'http://tinybrain.de:8080/speech/mic.gif'; |
269 | showInfo('info_no_microphone'); |
270 | ignore_onend = true; |
271 | } |
272 | if (event.error == 'not-allowed') { |
273 | if (event.timeStamp - start_timestamp < 100) { |
274 | showInfo('info_blocked'); |
275 | } else { |
276 | showInfo('info_denied'); |
277 | } |
278 | ignore_onend = true; |
279 | } |
280 | }; |
281 | |
282 | recognition.onend = function() { |
283 | recognizing = false; |
284 | if (ignore_onend) { |
285 | return; |
286 | } |
287 | start_img.src = 'http://tinybrain.de:8080/speech/mic.gif'; |
288 | |
289 | //final_transcript = ""; // DEH HACK |
290 | |
291 | if (!final_transcript) { |
292 | showInfo('info_start'); |
293 | return; |
294 | } |
295 | showInfo(''); |
296 | if (window.getSelection) { |
297 | window.getSelection().removeAllRanges(); |
298 | var range = document.createRange(); |
299 | range.selectNode(document.getElementById('final_span')); |
300 | window.getSelection().addRange(range); |
301 | } |
302 | }; |
303 | |
304 | recognition.onresult = function(event) { |
305 | var interim_transcript = ''; |
306 | if (ignore_result) { |
307 | ignore_result = false; |
308 | return; |
309 | } |
310 | for (var i = event.resultIndex; i < event.results.length; ++i) { |
311 | if (event.results[i].isFinal) { |
312 | var newData = event.results[i][0].transcript; |
313 | //final_transcript += newData; |
314 | final_transcript = newData; |
315 | var frameURL = "LINK/has-speech?q=" + encodeURIComponent(newData); |
316 | if (contentFrame && lastText != newData) { |
317 | lastText = newData; |
318 | contentFrame.location.href = frameURL; |
319 | } |
320 | } else { |
321 | interim_transcript += event.results[i][0].transcript; |
322 | } |
323 | } |
324 | final_transcript = capitalize(final_transcript); |
325 | final_span.innerHTML = linebreak(final_transcript); |
326 | interim_span.innerHTML = linebreak(interim_transcript); |
327 | if (/*final_transcript ||*/ interim_transcript) { |
328 | showButtons('inline-block'); |
329 | } |
330 | }; |
331 | |
332 | startRecognition(); |
333 | } |
334 | |
335 | function upgrade() { |
336 | start_button.style.visibility = 'hidden'; |
337 | showInfo('info_upgrade'); |
338 | } |
339 | |
340 | var two_line = /\n\n/g; |
341 | var one_line = /\n/g; |
342 | function linebreak(s) { |
343 | return s.replace(two_line, '<p></p>').replace(one_line, '<br>'); |
344 | } |
345 | |
346 | var first_char = /\S/; |
347 | function capitalize(s) { |
348 | return s.replace(first_char, function(m) { return m.toUpperCase(); }); |
349 | } |
350 | |
351 | function copyButton() { |
352 | if (recognizing) { |
353 | recognizing = false; |
354 | recognition.stop(); |
355 | } |
356 | copy_button.style.display = 'none'; |
357 | copy_info.style.display = 'inline-block'; |
358 | showInfo(''); |
359 | } |
360 | |
361 | function startButton(event) { |
362 | startRecognition(); |
363 | } |
364 | |
365 | function startRecognition() { |
366 | if (recognizing) { |
367 | recognition.stop(); |
368 | ignore_result = true; |
369 | return; |
370 | } |
371 | final_transcript = ''; |
372 | recognition.lang = select_dialect.value; |
373 | recognition.start(); |
374 | ignore_onend = false; |
375 | final_span.innerHTML = ''; |
376 | interim_span.innerHTML = ''; |
377 | start_img.src = 'http://tinybrain.de:8080/speech/mic-slash.gif'; |
378 | showInfo('info_allow'); |
379 | showButtons('none'); |
380 | start_timestamp = event.timeStamp; |
381 | } |
382 | |
383 | function showInfo(s) { |
384 | if (s) { |
385 | for (var child = info.firstChild; child; child = child.nextSibling) { |
386 | if (child.style) { |
387 | child.style.display = child.id == s ? 'inline' : 'none'; |
388 | } |
389 | } |
390 | info.style.visibility = 'visible'; |
391 | } else { |
392 | info.style.visibility = 'hidden'; |
393 | } |
394 | } |
395 | |
396 | var current_style; |
397 | function showButtons(style) { |
398 | if (style == current_style) { |
399 | return; |
400 | } |
401 | current_style = style; |
402 | copy_button.style.display = style; |
403 | copy_info.style.display = 'none'; |
404 | } |
405 | </script> |
406 | ]=]; |
407 | ret render(html); |
408 | } |
409 | |
410 | // frame set |
411 | |
412 | ret render([[ |
413 | <title>Pivo 1</title> |
414 | |
415 | <frameset rows="280,*"> |
416 | <frame src="LINK/upper"></frame> |
417 | <frame name="contentframe" src="LINK/empty"></frame> |
418 | </frameset> |
419 | ]]); |
420 | } |
421 | |
422 | static S render(S html) { |
423 | ret html.replace("LINK/", rawLink("")); |
424 | } |
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1002922 |
Snippet name: | Pivo Bot |
Eternal ID of this version: | #1002922/1 |
Text MD5: | d7d73a5c12596c4ccc6a158ba6c8c5cb |
Transpilation MD5: | 6ae2110b6eba1357fbc06629d75f1311 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-04-07 17:04:10 |
Source code size: | 11863 bytes / 424 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 806 / 1494 |
Referenced in: | [show references] |