diff --git a/webspeechdemo/main.css b/webspeechdemo/main.css new file mode 100644 index 0000000..b0def7a --- /dev/null +++ b/webspeechdemo/main.css @@ -0,0 +1,78 @@ + * { + font-family: Verdana, Arial, sans-serif; + } + a:link { + color:#000; + text-decoration: none; + } + a:visited { + color:#000; + } + a:hover { + color:#33F; + } + .button { + background: -webkit-linear-gradient(top,#008dfd 0,#0370ea 100%); + border: 1px solid #076bd2; + border-radius: 3px; + color: #fff; + display: none; + font-size: 13px; + font-weight: bold; + line-height: 1.3; + padding: 8px 25px; + text-align: center; + text-shadow: 1px 1px 1px #076bd2; + letter-spacing: normal; + } + .center { + padding: 10px; + text-align: center; + } + .final { + color: black; + padding-right: 3px; + } + .interim { + color: gray; + } + .info { + font-size: 14px; + text-align: center; + color: #777; + display: none; + } + .right { + float: right; + } + .sidebyside { + display: inline-block; + width: 45%; + min-height: 40px; + text-align: left; + vertical-align: top; + } + #headline { + font-size: 40px; + font-weight: 300; + } + #info { + font-size: 20px; + text-align: center; + color: #777; + visibility: hidden; + } + #results { + font-size: 14px; + font-weight: bold; + border: 1px solid #ddd; + padding: 15px; + text-align: left; + min-height: 150px; + -webkit-user-select: auto; + } + #start_button { + border: 0; + background-color:transparent; + padding: 0; + } diff --git a/webspeechdemo/main.js b/webspeechdemo/main.js new file mode 100644 index 0000000..bacdfbb --- /dev/null +++ b/webspeechdemo/main.js @@ -0,0 +1,12 @@ +/** + * Listens for the app launching then creates the window + * + * @see http://developer.chrome.com/apps/app.window.html + */ +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('webspeechdemo.html', { + id: 'speechwin', + width: 800, + height: 500 + }); +}); diff --git a/webspeechdemo/manifest.json b/webspeechdemo/manifest.json new file mode 100644 index 0000000..a0ea84d --- /dev/null +++ b/webspeechdemo/manifest.json @@ -0,0 +1,13 @@ +{ + "manifest_version": 2, + "name": "WebSpeechAPI app", + "version": "1", + "permissions": ["audioCapture"], + "app": { + "background": { + "scripts": ["main.js"] + } + }, + "minimum_chrome_version": "25" + +} diff --git a/webspeechdemo/speech.js b/webspeechdemo/speech.js new file mode 100644 index 0000000..1c94fe1 --- /dev/null +++ b/webspeechdemo/speech.js @@ -0,0 +1,261 @@ +var langs = +[['Afrikaans', ['af-ZA']], + ['Bahasa Indonesia',['id-ID']], + ['Bahasa Melayu', ['ms-MY']], + ['Català', ['ca-ES']], + ['Čeština', ['cs-CZ']], + ['Deutsch', ['de-DE']], + ['English', ['en-AU', 'Australia'], + ['en-CA', 'Canada'], + ['en-IN', 'India'], + ['en-NZ', 'New Zealand'], + ['en-ZA', 'South Africa'], + ['en-GB', 'United Kingdom'], + ['en-US', 'United States']], + ['Español', ['es-AR', 'Argentina'], + ['es-BO', 'Bolivia'], + ['es-CL', 'Chile'], + ['es-CO', 'Colombia'], + ['es-CR', 'Costa Rica'], + ['es-EC', 'Ecuador'], + ['es-SV', 'El Salvador'], + ['es-ES', 'España'], + ['es-US', 'Estados Unidos'], + ['es-GT', 'Guatemala'], + ['es-HN', 'Honduras'], + ['es-MX', 'México'], + ['es-NI', 'Nicaragua'], + ['es-PA', 'Panamá'], + ['es-PY', 'Paraguay'], + ['es-PE', 'Perú'], + ['es-PR', 'Puerto Rico'], + ['es-DO', 'República Dominicana'], + ['es-UY', 'Uruguay'], + ['es-VE', 'Venezuela']], + ['Euskara', ['eu-ES']], + ['Français', ['fr-FR']], + ['Galego', ['gl-ES']], + ['Hrvatski', ['hr_HR']], + ['IsiZulu', ['zu-ZA']], + ['Íslenska', ['is-IS']], + ['Italiano', ['it-IT', 'Italia'], + ['it-CH', 'Svizzera']], + ['Magyar', ['hu-HU']], + ['Nederlands', ['nl-NL']], + ['Norsk bokmål', ['nb-NO']], + ['Polski', ['pl-PL']], + ['Português', ['pt-BR', 'Brasil'], + ['pt-PT', 'Portugal']], + ['Română', ['ro-RO']], + ['Slovenčina', ['sk-SK']], + ['Suomi', ['fi-FI']], + ['Svenska', ['sv-SE']], + ['Türkçe', ['tr-TR']], + ['български', ['bg-BG']], + ['Pусский', ['ru-RU']], + ['Српски', ['sr-RS']], + ['한국어', ['ko-KR']], + ['中文', ['cmn-Hans-CN', '普通话 (中国大陆)'], + ['cmn-Hans-HK', '普通话 (香港)'], + ['cmn-Hant-TW', '中文 (台灣)'], + ['yue-Hant-HK', '粵語 (香港)']], + ['日本語', ['ja-JP']], + ['Lingua latīna', ['la']]]; + +for (var i = 0; i < langs.length; i++) { + select_language.options[i] = new Option(langs[i][0], i); +} +select_language.selectedIndex = 6; +updateCountry(); +select_dialect.selectedIndex = 6; +showInfo('info_start'); + +function updateCountry() { + for (var i = select_dialect.options.length - 1; i >= 0; i--) { + select_dialect.remove(i); + } + var list = langs[select_language.selectedIndex]; + for (var i = 1; i < list.length; i++) { + select_dialect.options.add(new Option(list[i][1], list[i][0])); + } + select_dialect.style.visibility = list[1].length == 1 ? 'hidden' : 'visible'; +} + +var create_email = false; +var final_transcript = ''; +var recognizing = false; +var ignore_onend; +var start_timestamp; +if (!('webkitSpeechRecognition' in window)) { + upgrade(); +} else { + start_button.style.display = 'inline-block'; + var recognition = new webkitSpeechRecognition(); + recognition.continuous = true; + recognition.interimResults = true; + + recognition.onstart = function() { + recognizing = true; + showInfo('info_speak_now'); + start_img.src = 'mic-animate.gif'; + }; + + recognition.onerror = function(event) { + if (event.error == 'no-speech') { + start_img.src = 'mic.gif'; + showInfo('info_no_speech'); + ignore_onend = true; + } + if (event.error == 'audio-capture') { + start_img.src = 'mic.gif'; + showInfo('info_no_microphone'); + ignore_onend = true; + } + if (event.error == 'not-allowed') { + if (event.timeStamp - start_timestamp < 100) { + showInfo('info_blocked'); + } else { + showInfo('info_denied'); + } + ignore_onend = true; + } + }; + + recognition.onend = function() { + recognizing = false; + if (ignore_onend) { + return; + } + start_img.src = 'mic.gif'; + if (!final_transcript) { + showInfo('info_start'); + return; + } + showInfo(''); + if (window.getSelection) { + window.getSelection().removeAllRanges(); + var range = document.createRange(); + range.selectNode(document.getElementById('final_span')); + window.getSelection().addRange(range); + } + if (create_email) { + create_email = false; + createEmail(); + } + }; + + recognition.onresult = function(event) { + var interim_transcript = ''; + for (var i = event.resultIndex; i < event.results.length; ++i) { + if (event.results[i].isFinal) { + final_transcript += event.results[i][0].transcript; + } else { + interim_transcript += event.results[i][0].transcript; + } + } + final_transcript = capitalize(final_transcript); + final_span.innerHTML = linebreak(final_transcript); + interim_span.innerHTML = linebreak(interim_transcript); + if (final_transcript || interim_transcript) { + showButtons('inline-block'); + } + }; +} + +function upgrade() { + start_button.style.visibility = 'hidden'; + showInfo('info_upgrade'); +} + +var two_line = /\n\n/g; +var one_line = /\n/g; +function linebreak(s) { + return s.replace(two_line, '

').replace(one_line, '
'); +} + +var first_char = /\S/; +function capitalize(s) { + return s.replace(first_char, function(m) { return m.toUpperCase(); }); +} + +function createEmail() { + var n = final_transcript.indexOf('\n'); + if (n < 0 || n >= 80) { + n = 40 + final_transcript.substring(40).indexOf(' '); + } + var subject = encodeURI(final_transcript.substring(0, n)); + var body = encodeURI(final_transcript.substring(n + 1)); + window.open('mailto:?subject=' + subject + '&body=' + body); +} + +function copyButton() { + if (recognizing) { + recognizing = false; + recognition.stop(); + } + copy_button.style.display = 'none'; + copy_info.style.display = 'inline-block'; + showInfo(''); +} + +function emailButton() { + if (recognizing) { + create_email = true; + recognizing = false; + recognition.stop(); + } else { + createEmail(); + } + email_button.style.display = 'none'; + email_info.style.display = 'inline-block'; + showInfo(''); +} + +function startButton(event) { + if (recognizing) { + recognition.stop(); + return; + } + final_transcript = ''; + recognition.lang = select_dialect.value; + recognition.start(); + ignore_onend = false; + final_span.innerHTML = ''; + interim_span.innerHTML = ''; + start_img.src = 'mic-slash.gif'; + showInfo('info_allow'); + showButtons('none'); + start_timestamp = event.timeStamp; +} + +function showInfo(s) { + if (s) { + for (var child = info.firstChild; child; child = child.nextSibling) { + if (child.style) { + child.style.display = child.id == s ? 'inline' : 'none'; + } + } + info.style.visibility = 'visible'; + } else { + info.style.visibility = 'hidden'; + } +} + +var current_style; +function showButtons(style) { + if (style == current_style) { + return; + } + current_style = style; + copy_button.style.display = style; + email_button.style.display = style; + copy_info.style.display = 'none'; + email_info.style.display = 'none'; +} + +document.getElementById("start_button").addEventListener("click", startButton); +document.getElementById("copy_button").addEventListener("click", copyButton); +document.getElementById("email_button").addEventListener("click", emailButton); +document.getElementById("select_language").addEventListener("change", updateCountry); + + diff --git a/webspeechdemo/webspeechdemo.html b/webspeechdemo/webspeechdemo.html index b4bc72e..86b6b0a 100644 --- a/webspeechdemo/webspeechdemo.html +++ b/webspeechdemo/webspeechdemo.html @@ -1,108 +1,34 @@ - -Web Speech API Demo - + + + + + Web Speech API Demo + +

- + Web Speech API Demonstration

Click on the microphone icon and begin speaking.

Speak now.

No speech was detected. You may need to adjust your - + microphone settings.

Click the "Allow" button above to enable your microphone.

Permission to use microphone was denied.

Permission to use microphone is blocked. To change, go to chrome://settings/contentExceptions#media-stream

Web Speech API is not supported by this browser. - Upgrade to Chrome + Upgrade to Chrome version 25 or later.

-
@@ -112,14 +38,14 @@

-
Press Control-C to copy text.
(Command-C on Mac.)
-
Text sent to default email application.
@@ -128,264 +54,11 @@

- +   
- \ No newline at end of file + + +