aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/api/web_speech_api
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/api/web_speech_api
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/ja/web/api/web_speech_api')
-rw-r--r--files/ja/web/api/web_speech_api/index.html118
-rw-r--r--files/ja/web/api/web_speech_api/using_the_web_speech_api/index.html301
2 files changed, 419 insertions, 0 deletions
diff --git a/files/ja/web/api/web_speech_api/index.html b/files/ja/web/api/web_speech_api/index.html
new file mode 100644
index 0000000000..6e6486fa98
--- /dev/null
+++ b/files/ja/web/api/web_speech_api/index.html
@@ -0,0 +1,118 @@
+---
+title: Web Speech API
+slug: Web/API/Web_Speech_API
+tags:
+ - API
+ - Experimental
+ - Landing
+ - Reference
+ - Web Speech API
+ - recognition
+ - speech
+ - synthesis
+translation_of: Web/API/Web_Speech_API
+---
+<div>{{DefaultAPISidebar("Web Speech API")}}{{seecompattable}}</div>
+
+<div class="summary">
+<p>Web Speech API は、音声データをウェブアプリに組み入れることを可能にします。Web Speech API は、SpeechSynthesis (Text-to-Speech; 音声合成) と SpeechRecognition (Asynchronous Speech Recognition; 非同期音声認識) の 2 つの部分から成り立っています。</p>
+</div>
+
+<h2 id="Web_Speech_Concepts_and_Usage" name="Web_Speech_Concepts_and_Usage">Web Speech API のコンセプトと使用法</h2>
+
+<p>Web Speech API は、ウェブアプリが音声データを扱えるようにします。この API には 2 つの構成要素があります。</p>
+
+<ul>
+ <li>音声認識は {{domxref("SpeechRecognition")}} インターフェイス経由でアクセスされます。これは、音声入力 (通常はデバイスのデフォルト音声認識サービスを経由) から音声の文脈を認識し、適切に応答する機能を提供します。通常は、インターフェイスのコンストラクターを使用して新しい {{domxref("SpeechRecognition")}} オブジェクトを生成します。このオブジェクトは、デバイスのマイクを通して入力された音声を検知するための、いくつものイベントハンドラーを持ちます。{{domxref("SpeechGrammar")}} インターフェイスは、あなたのアプリが認識すべき特定の文法群のコンテナーを表します。文法は、<a href="http://www.w3.org/TR/jsgf/">JSpeech Grammar Format</a> (<strong>JSGF</strong>) を使用して定義されています。</li>
+ <li>音声合成は、{{domxref("SpeechSynthesis")}} インターフェイス経由でアクセスされます。これは、プログラムに、そのテキストコンテンツを読み上げる機能を提供します (通常はデバイスのデフォルトの音声合成を経由)。異なる音声の種類は、{{domxref("SpeechSynthesisVoice")}} オブジェクトで表され、発話してほしいテキストの異なる部分は、{{domxref("SpeechSynthesisUtterance")}} オブジェクトで表されます。これらを {{domxref("SpeechSynthesis.speak()")}} メソッドに渡すことによって発話されます。</li>
+</ul>
+
+<p>これらの機能の使い方についての詳細は、<a href="/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API">Using the Web Speech API</a> を参照してください。</p>
+
+<h2 id="Web_Speech_API_Interfaces" name="Web_Speech_API_Interfaces">Web Speech API インターフェイス</h2>
+
+<h3 id="Speech_recognition" name="Speech_recognition">音声認識</h3>
+
+<dl>
+ <dt>{{domxref("SpeechRecognition")}}</dt>
+ <dd>認識サービスのコントローラーインターフェイスです。認識サービスから送信された {{domxref("SpeechRecognitionEvent")}} も扱います。</dd>
+ <dt>{{domxref("SpeechRecognitionAlternative")}}</dt>
+ <dd>音声認識サービスにより認識されている単語を表します。</dd>
+ <dt>{{domxref("SpeechRecognitionError")}}</dt>
+ <dd>認識サービスからのエラーメッセージを表します。</dd>
+ <dt>{{domxref("SpeechRecognitionEvent")}}</dt>
+ <dd>{{event("result")}} イベントおよび {{event("nomatch")}} イベントのためのイベントオブジェクトです。暫定あるいは最終の音声認識結果に関連付けられたすべてのデータを含みます。</dd>
+ <dt>{{domxref("SpeechGrammar")}}</dt>
+ <dd>認識サービスに認識してほしい言葉または言葉のパターンです。</dd>
+ <dt>{{domxref("SpeechGrammarList")}}</dt>
+ <dd>{{domxref("SpeechGrammar")}} オブジェクトのリストを表します。</dd>
+ <dt>{{domxref("SpeechRecognitionResult")}}</dt>
+ <dd>一致した一つの認識結果を表します。これには、複数の {{domxref("SpeechRecognitionAlternative")}} オブジェクトが含まれることがあります。</dd>
+ <dt>{{domxref("SpeechRecognitionResultList")}}</dt>
+ <dd>{{domxref("SpeechRecognitionResult")}} オブジェクトのリストを表します。または、{{domxref("SpeechRecognition.continuous","continuous")}} モードで結果が捕捉された場合は、一つだけになります。</dd>
+</dl>
+
+<h3 id="Speech_synthesis" name="Speech_synthesis">音声合成</h3>
+
+<dl>
+ <dt>{{domxref("SpeechSynthesis")}}</dt>
+ <dd>音声サービスのコントローラーインターフェイスです。これは、デバイスで利用可能な合成音声についての情報を取得したり、発話の開始や一時停止などのコマンドを実行するために使用されます。</dd>
+ <dt>{{domxref("SpeechSynthesisErrorEvent")}}</dt>
+ <dd>音声サービスで {{domxref("SpeechSynthesisUtterance")}} オブジェクトの処理中に発生したあらゆるエラーについての情報を含みます。</dd>
+ <dt>{{domxref("SpeechSynthesisEvent")}}</dt>
+ <dd>音声サービスで処理されている {{domxref("SpeechSynthesisUtterance")}} オブジェクトの現在の状態についての情報を含みます。</dd>
+ <dt>{{domxref("SpeechSynthesisUtterance")}}</dt>
+ <dd>音声リクエストを表します。これは、音声サービスが読み上げるコンテンツとその読み上げ方 (言語、音声の高低、音量など) についての情報を含みます。</dd>
+</dl>
+
+<dl>
+ <dt>{{domxref("SpeechSynthesisVoice")}}</dt>
+ <dd>システムがサポートする音声を表します。すべての <code>SpeechSynthesisVoice</code> は、それ自身に関連する音声サービス (言語、名前、URI についての情報を含む) を持ちます。</dd>
+ <dt>{{domxref("Window.speechSynthesis")}}</dt>
+ <dd><code>SpeechSynthesisGetter</code> と呼ばれる <code>[NoInterfaceObject]</code> インターフェイスの一部として定義され、<code>Window</code> オブジェクトによって実装されたことで、<code>speechSynthesis</code> プロパティは {{domxref("SpeechSynthesis")}} コントローラーへのアクセスを提供します。したがって、音声合成機能へのエントリーポイントになります。</dd>
+</dl>
+
+<h2 id="Examples" name="Examples">例</h2>
+
+<p>Github 上の <a href="https://github.com/mdn/web-speech-api/">Web Speech API リポジトリー</a> には、音声合成や音声認識を説明するデモが含まれています。</p>
+
+<h2 id="Specifications" name="Specifications">仕様</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">仕様書</th>
+ <th scope="col">策定状況</th>
+ <th scope="col">備考</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('Web Speech API')}}</td>
+ <td>{{Spec2('Web Speech API')}}</td>
+ <td>初期定義</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの実装状況</h2>
+
+<h3 id="SpeechRecognition"><code>SpeechRecognition</code></h3>
+
+<div>
+
+
+<p>{{Compat("api.SpeechRecognition", 0)}}</p>
+
+<h3 id="SpeechSynthesis"><code>SpeechSynthesis</code></h3>
+
+<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div>
+
+<p>{{Compat("api.SpeechSynthesis", 0)}}</p>
+
+<h2 id="See_also" name="See_also">関連項目</h2>
+
+<ul>
+ <li><a href="/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API">Using the Web Speech API</a></li>
+ <li><a href="http://www.sitepoint.com/talking-web-pages-and-the-speech-synthesis-api/">SitePoint の記事</a></li>
+ <li><a href="http://updates.html5rocks.com/2014/01/Web-apps-that-talk---Introduction-to-the-Speech-Synthesis-API">HTML5Rocks の記事</a></li>
+ <li><a href="http://aurelio.audero.it/demo/speech-synthesis-api-demo.html">デモ</a> [aurelio.audero.it]</li>
+</ul></div>
diff --git a/files/ja/web/api/web_speech_api/using_the_web_speech_api/index.html b/files/ja/web/api/web_speech_api/using_the_web_speech_api/index.html
new file mode 100644
index 0000000000..3937d15679
--- /dev/null
+++ b/files/ja/web/api/web_speech_api/using_the_web_speech_api/index.html
@@ -0,0 +1,301 @@
+---
+title: Web Speech APIを使う
+slug: Web/API/Web_Speech_API/Using_the_Web_Speech_API
+translation_of: Web/API/Web_Speech_API/Using_the_Web_Speech_API
+---
+<p>Web Speech API は、音声認識と音声合成(text to speech または tts としても知られています)という 2 つの異なる分野の機能を提供しており、アクセシビリティと制御メカニズムに興味深い新しい可能性をもたらします。この記事では、両方の分野の簡単な紹介とデモを提供します。</p>
+
+<h2 id="音声認識">音声認識</h2>
+
+<p>音声認識ではデバイスのマイクを通して音声を受信し、音声認識サービスによって文法のリスト(基本的には特定のアプリで認識させたいボキャブラリー)と照合されます。単語やフレーズが正常に認識されると、結果(または結果のリスト)がテキスト文字列として返され、その結果としてさらなるアクションを開始することができます。</p>
+
+<p>Web Speech API には、このための主要なコントローラインターフェイスである {{domxref("SpeechRecognition")}} と、文法や結果などを表現するためのいくつかの密接に関連したインターフェースがあります。一般的には、デバイス上で利用可能なデフォルトの音声認識システムが音声認識に使用されます — 最近のほとんどのOSには音声コマンドを発行するための音声認識システムが搭載されています。macOSのDictation、iOSのSiri、Windows 10のCortana、AndroidのSpeechなどを考えてみてください。</p>
+
+<div class="note">
+<p><strong>注釈</strong>: Chrome などの一部のブラウザでは、Web ページで音声認識を使用するためにサーバーベースの認識エンジンが必要です。音声が認識処理のためにウェブサービスに送信されるため、オフラインでは機能しません。</p>
+</div>
+
+<h3 id="デモ">デモ</h3>
+
+<p>Web音声認識の簡単な使い方を示すために、<a href="https://github.com/mdn/web-speech-api/tree/master/speech-color-changer">Speech color changer</a>というデモを書いてみました。画面をタップ/クリックし、HTMLの色のキーワードを言うと、アプリの背景色がその色に変わります。</p>
+
+<p><img alt="The UI of an app titled Speech Color changer. It invites the user to tap the screen and say a color, and then it turns the background of the app that colour. In this case it has turned the background red." src="https://mdn.mozillademos.org/files/11975/speech-color-changer.png" style="border: 1px solid black; display: block; height: 533px; margin: 0px auto; width: 300px;"></p>
+
+<p>デモを実行するには、それが一部となっているGithubリポジトリをクローン(または<a href="https://github.com/mdn/web-speech-api/archive/master.zip">直接ダウンロード</a>)し、サポートされているデスクトップブラウザでHTML indexファイルを開くか、Chromeのようなサポートされているモバイルブラウザで<a href="https://mdn.github.io/web-speech-api/speech-color-changer/">ライブデモのURL</a>に移動することができます。</p>
+
+<h3 id="ブラウザ対応">ブラウザ対応</h3>
+
+<p>Web Speech API 音声認識のサポートは、通常 Chrome for Desktop と Android に限られています — Chrome はバージョン 33 付近からサポートしていますが、プレフィックス付きのインターフェイスを使用しているため、 <code>webkitSpeechRecognition</code> などのプレフィックス付きバージョンを含める必要があります。</p>
+
+<h3 id="HTMLとCSS">HTMLとCSS</h3>
+
+<p>アプリのHTMLとCSSは本当に簡単です。タイトル、説明段落、診断メッセージを出力するdivがあるだけです。</p>
+
+<pre class="brush: html notranslate">&lt;h1&gt;Speech color changer&lt;/h1&gt;
+&lt;p&gt;Tap/click then say a color to change the background color of the app.&lt;/p&gt;
+&lt;div&gt;
+ &lt;p class="output"&gt;&lt;em&gt;...diagnostic messages&lt;/em&gt;&lt;/p&gt;
+&lt;/div&gt;</pre>
+
+<p>このCSSでは、デバイスをまたいでも問題なく見えるように、非常にシンプルなレスポンシブ・スタイリングを提供しています。</p>
+
+<h3 id="JavaScript">JavaScript</h3>
+
+<p>JavaScriptをもう少し詳しく見てみましょう。</p>
+
+<h4 id="Chrome対応">Chrome対応</h4>
+
+<p>前述したように、Chrome は現在プレフィックス付きのプロパティで音声認識をサポートしているので、適切なオブジェクトを Chrome に供給し、そして将来的な実装でプレフィックスなしの機能をサポートする可能性も踏まえ、以下の行をコードの最初に追加しています。</p>
+
+<pre class="brush: js notranslate">var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition
+var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList
+var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent</pre>
+
+<h4 id="文法">文法</h4>
+
+<p>コードの次の部分では、アプリが認識する文法を定義します。次の変数は文法を保持するために定義されています。</p>
+
+<pre class="brush: js notranslate">var colors = [ 'aqua' , 'azure' , 'beige', 'bisque', 'black', 'blue', 'brown', 'chocolate', 'coral' ... ];
+var grammar = '#JSGF V1.0; grammar colors; public &lt;color&gt; = ' + colors.join(' | ') + ' ;'</pre>
+
+<p>使用されている文法形式は <a class="external external-icon" href="http://www.w3.org/TR/jsgf/">JSpeech Grammar Format</a> (<strong>JSGF</strong>) です — それについての詳細はリンク先の仕様書を参照してください。しかし、今のところは手っ取り早く実行してみましょう。</p>
+
+<ul>
+ <li>行の区切りはJavaScriptと同じようにセミコロンで区切られています。</li>
+ <li>最初の行 — <code>#JSGF V1.0;</code> — は、使用されているフォーマットとバージョンを示します。これは常に最初に含める必要があります。</li>
+ <li>2行目は認識したい用語のタイプを示します。<code>public</code> はパブリックルールであることを宣言し、角括弧内の文字列はこの用語の認識名 (<code>color</code>) を定義し、等号の後に続く項目のリストは、用語の適切な値として認識され受け入れられる代替値です。それぞれがパイプ文字で区切られていることに注意してください。</li>
+ <li>上記の構造に沿って別の行に好きなだけ多くの用語を定義し、かなり複雑な文法定義を含めることができます。この基本的なデモのために私たちは物事をシンプルにしています。 </li>
+</ul>
+
+<h4 id="文法を音声認識にプラグインする">文法を音声認識にプラグインする</h4>
+
+<p>次にやるべきことは、アプリケーションの認識を制御する音声認識インスタンスを定義することです。これは {{domxref("SpeechRecognition.SpeechRecognition()","SpeechRecognition()")}} コンストラクタを使用して行います。また、{{domxref("SpeechGrammarList.SpeechGrammarList()","SpeechGrammarList()")}} コンストラクタを使用して、文法を含む新しい音声文法リストも作成します。</p>
+
+<pre class="brush: js notranslate">var recognition = new SpeechRecognition();
+var speechRecognitionList = new SpeechGrammarList();</pre>
+
+<p>{{domxref("SpeechGrammarList.addFromString()")}} メソッドを使ってリストに <code>grammar</code> を追加します。 このメソッドは追加したい文字列をパラメータとして受けとり、さらにオプションで、リスト内で利用可能な他の文法との関係においてこの文法の重要度を指定する重み値を受け取ります(0から1までの範囲で指定できます)。追加された文法は{{domxref("SpeechGrammar")}} オブジェクトのインスタンスとしてリスト内で利用できます。</p>
+
+<pre class="brush: js notranslate">speechRecognitionList.addFromString(grammar, 1);</pre>
+
+<p>次に、 {{domxref("SpeechGrammarList")}} を {{domxref("SpeechRecognition.grammars")}} プロパティの値に設定することで、音声認識インスタンスに {{domxref("SpeechGrammarList")}} を追加します。次に進む前に、認識インスタンスの他のいくつかのプロパティも設定します。</p>
+
+<ul>
+ <li>{{domxref("SpeechRecognition.continuous")}}: 認識が開始されるたびに連続した結果をキャプチャする (<code>true</code>) か、または単一の結果だけをキャプチャする (<code>false</code>) かを制御します。</li>
+ <li>{{domxref("SpeechRecognition.lang")}}: 認識の言語を設定します。これを設定することは良い習慣であるため、推奨されます。</li>
+ <li>{{domxref("SpeechRecognition.interimResults")}}: 音声認識システムが中間的な結果を返すか、最終的な結果だけを返すか定義します。このシンプルなデモでは最終的な結果で十分です。</li>
+ <li>{{domxref("SpeechRecognition.maxAlternatives")}}: 結果ごとに返される代替候補数を設定します。これは、結果が完全に明確ではなく、ユーザーが正しいものを選択できるように代替候補のリストを表示したい場合などに便利な場合があります。しかし、このシンプルなデモでは必要ないのでここでは1つだけ指定します(これは実際にはデフォルトです)。</li>
+</ul>
+
+<pre class="brush: js notranslate">recognition.grammars = speechRecognitionList;
+recognition.continuous = false;
+recognition.lang = 'en-US';
+recognition.interimResults = false;
+recognition.maxAlternatives = 1;</pre>
+
+<h4 id="音声認識の開始">音声認識の開始</h4>
+
+<p>出力 {{htmlelement("div")}} とHTML要素への参照を取得(診断メッセージを出力したり、後でアプリの背景色を更新したりできるようにするため)した後、画面がタップ/クリックされたときに音声認識サービスが開始されるように onclick ハンドラを実装します。これは {{domxref("SpeechRecognition.start()")}} を呼び出すことで実現しています。 <code>forEach()</code> メソッドは何色を言っているかを示す色付きインジケータを出力するために使われています。</p>
+
+<pre class="brush: js notranslate">var diagnostic = document.querySelector('.output');
+var bg = document.querySelector('html');
+var hints = document.querySelector('.hints');
+
+var colorHTML= '';
+colors.forEach(function(v, i, a){
+ console.log(v, i);
+ colorHTML += '&lt;span style="background-color:' + v + ';"&gt; ' + v + ' &lt;/span&gt;';
+});
+hints.innerHTML = 'Tap/click then say a color to change the background color of the app. Try ' + colorHTML + '.';
+
+document.body.onclick = function() {
+ recognition.start();
+ console.log('Ready to receive a color command.');
+}</pre>
+
+<h4 id="結果の受け取りとハンドリング">結果の受け取りとハンドリング</h4>
+
+<p>音声認識が開始されると、結果やその他の周辺情報を取得するために使用できる多くのイベントハンドラがあります(<a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition#Event_handlers"><code>SpeechRecognition</code> のイベントハンドラのリスト</a> を参照してください)。最も一般的なものは {{domxref("SpeechRecognition.onresult")}} で、成功した結果を受信したときに発火されます。</p>
+
+<pre class="brush: js notranslate">recognition.onresult = function(event) {
+  var color = event.results[0][0].transcript;
+  diagnostic.textContent = 'Result received: ' + color + '.';
+  bg.style.backgroundColor = color;
+  console.log('Confidence: ' + event.results[0][0].confidence);
+}</pre>
+
+<p>ここの2行目はちょっと複雑そうなので、順を追って説明していきましょう。{{domxref("SpeechRecognitionEvent.results")}}プロパティは、 {{domxref("SpeechRecognitionResult")}} オブジェクトを含む {{domxref("SpeechRecognitionResultList")}} オブジェクトを返します。これはゲッターを持っているので配列のようにアクセスでき、最初の<code>[0]</code>は0の位置にある<code>SpeechRecognitionResult</code>を返します。各 <code>SpeechRecognitionResult</code> オブジェクトには、個々に認識された単語を含む {{domxref("SpeechRecognitionAlternative")}} オブジェクトが含まれています。これらは配列のようにアクセスできるようにゲッターも持っています  — 2 番目の<code>[0]</code>は、したがって位置 0 の <code>SpeechRecognitionAlternative</code> を返します。次に、その <code>transcript</code> プロパティを返して個々の認識結果を含む文字列を文字列として取得し、背景色をその色に設定し、認識された色をUIの診断メッセージとして報告します。</p>
+
+<p>また、 {{domxref("SpeechRecognition.onspeechend")}} ハンドラを使用して音声認識サービスの実行を停止します(1つの単語が認識され、それが発話され終わったら {{domxref("SpeechRecognition.stop()")}}) を使用します)。</p>
+
+<pre class="brush: js notranslate">recognition.onspeechend = function() {
+ recognition.stop();
+}</pre>
+
+<h4 id="エラーや認識されない発話のハンドリング">エラーや認識されない発話のハンドリング</h4>
+
+<p>最後の 2 つのハンドラは、定義された文法にない音声が認識されたケースやエラーが発生したケースを処理するためのものです。{{domxref("SpeechRecognition.onnomatch")}} は最初に言及したケースを処理することになっているようですが、今のところ正しく動作しているようには見えないことに注意してください(とにかく認識されたものを返すだけです)。</p>
+
+<pre class="brush: js notranslate">recognition.onnomatch = function(event) {
+ diagnostic.textContent = 'I didnt recognise that color.';
+}</pre>
+
+<p>{{domxref("SpeechRecognition.onerror")}} は、認識に成功して実際にエラーが発生したケースを処理します — {{domxref("SpeechRecognitionError.error")}} プロパティには、返された実際のエラーが含まれます。</p>
+
+<pre class="brush: js notranslate">recognition.onerror = function(event) {
+ diagnostic.textContent = 'Error occurred in recognition: ' + event.error;
+}</pre>
+
+<h2 id="Speech_synthesis">Speech synthesis</h2>
+
+<p>Speech synthesis (aka text-to-speech, or tts) involves receiving synthesising text contained within an app to speech, and playing it out of a device's speaker or audio output connection.</p>
+
+<p>The Web Speech API has a main controller interface for this — {{domxref("SpeechSynthesis")}} — plus a number of closely-related interfaces for representing text to be synthesised (known as utterances), voices to be used for the utterance, etc. Again, most OSes have some kind of speech synthesis system, which will be used by the API for this task as available.</p>
+
+<h3 id="Demo">Demo</h3>
+
+<p>To show simple usage of Web speech synthesis, we've provided a demo called <a href="https://mdn.github.io/web-speech-api/speak-easy-synthesis/">Speak easy synthesis</a>. This includes a set of form controls for entering text to be synthesised, and setting the pitch, rate, and voice to use when the text is uttered. After you have entered your text, you can press <kbd>Enter</kbd>/<kbd>Return</kbd> to hear it spoken.</p>
+
+<p><img alt="UI of an app called speak easy synthesis. It has an input field in which to input text to be synthesised, slider controls to change the rate and pitch of the speech, and a drop down menu to choose between different voices." src="https://mdn.mozillademos.org/files/11977/speak-easy-synthesis.png" style="border: 1px solid black; display: block; height: 533px; margin: 0px auto; width: 300px;"></p>
+
+<p>To run the demo, you can clone (or <a href="https://github.com/mdn/web-speech-api/archive/master.zip">directly download</a>) the Github repo it is part of, open the HTML index file in a supporting desktop browser, or navigate to the <a href="https://mdn.github.io/web-speech-api/speak-easy-synthesis/">live demo URL</a> in a supporting mobile browser like Chrome, or Firefox OS.</p>
+
+<h3 id="Browser_support">Browser support</h3>
+
+<p>Support for Web Speech API speech synthesis is still getting there across mainstream browsers, and is currently limited to the following:</p>
+
+<ul>
+ <li>
+ <p>Firefox desktop and mobile support it in Gecko 42+ (Windows)/44+, without prefixes, and it can be turned on by flipping the <code>media.webspeech.synth.enabled</code> flag to <code>true</code> in <code>about:config</code>.</p>
+ </li>
+ <li>
+ <p>Firefox OS 2.5+ supports it, by default, and without the need for any permissions.</p>
+ </li>
+ <li>
+ <p>Chrome for Desktop and Android have supported it since around version 33, without prefixes.</p>
+ </li>
+</ul>
+
+<h3 id="HTML_and_CSS">HTML and CSS</h3>
+
+<p>The HTML and CSS are again pretty trivial, simply containing a title, some instructions for use, and a form with some simple controls. The {{htmlelement("select")}} element is initially empty, but is populated with {{htmlelement("option")}}s via JavaScript (see later on.)</p>
+
+<pre class="brush: html notranslate">&lt;h1&gt;Speech synthesiser&lt;/h1&gt;
+
+&lt;p&gt;Enter some text in the input below and press return to hear it. change voices using the dropdown menu.&lt;/p&gt;
+
+&lt;form&gt;
+ &lt;input type="text" class="txt"&gt;
+ &lt;div&gt;
+ &lt;label for="rate"&gt;Rate&lt;/label&gt;&lt;input type="range" min="0.5" max="2" value="1" step="0.1" id="rate"&gt;
+ &lt;div class="rate-value"&gt;1&lt;/div&gt;
+ &lt;div class="clearfix"&gt;&lt;/div&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="pitch"&gt;Pitch&lt;/label&gt;&lt;input type="range" min="0" max="2" value="1" step="0.1" id="pitch"&gt;
+ &lt;div class="pitch-value"&gt;1&lt;/div&gt;
+ &lt;div class="clearfix"&gt;&lt;/div&gt;
+ &lt;/div&gt;
+ &lt;select&gt;
+
+ &lt;/select&gt;
+&lt;/form&gt;</pre>
+
+<h3 id="JavaScript_2">JavaScript</h3>
+
+<p>Let's investigate the JavaScript that powers this app.</p>
+
+<h4 id="Setting_variables">Setting variables</h4>
+
+<p>First of all, we capture references to all the DOM elements involved in the UI, but more interestingly, we capture a reference to {{domxref("Window.speechSynthesis")}}. This is API's entry point — it returns an instance of {{domxref("SpeechSynthesis")}}, the controller interface for web speech synthesis.</p>
+
+<pre class="brush: js notranslate">var synth = window.speechSynthesis;
+
+var inputForm = document.querySelector('form');
+var inputTxt = document.querySelector('.txt');
+var voiceSelect = document.querySelector('select');
+
+var pitch = document.querySelector('#pitch');
+var pitchValue = document.querySelector('.pitch-value');
+var rate = document.querySelector('#rate');
+var rateValue = document.querySelector('.rate-value');
+
+var voices = [];
+</pre>
+
+<h4 id="Populating_the_select_element">Populating the select element</h4>
+
+<p>To populate the {{htmlelement("select")}} element with the different voice options the device has available, we've written a <code>populateVoiceList()</code> function. We first invoke {{domxref("SpeechSynthesis.getVoices()")}}, which returns a list of all the available voices, represented by {{domxref("SpeechSynthesisVoice")}} objects. We then loop through this list — for each voice we create an {{htmlelement("option")}} element, set its text content to display the name of the voice (grabbed from {{domxref("SpeechSynthesisVoice.name")}}), the language of the voice (grabbed from {{domxref("SpeechSynthesisVoice.lang")}}), and <code>-- DEFAULT</code> if the voice is the default voice for the synthesis engine (checked by seeing if {{domxref("SpeechSynthesisVoice.default")}} returns <code>true</code>.)</p>
+
+<p>We also create <code>data-</code> attributes for each option, containing the name and language of the associated voice, so we can grab them easily later on, and then append the options as children of the select.</p>
+
+<pre class="brush: js notranslate">function populateVoiceList() {
+ voices = synth.getVoices();
+
+ for(i = 0; i &lt; voices.length ; i++) {
+ var option = document.createElement('option');
+ option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
+
+ if(voices[i].default) {
+ option.textContent += ' -- DEFAULT';
+ }
+
+ option.setAttribute('data-lang', voices[i].lang);
+ option.setAttribute('data-name', voices[i].name);
+ voiceSelect.appendChild(option);
+ }
+}</pre>
+
+<p>When we come to run the function, we do the following. This is because Firefox doesn't support {{domxref("SpeechSynthesis.onvoiceschanged")}}, and will just return a list of voices when {{domxref("SpeechSynthesis.getVoices()")}} is fired. With Chrome however, you have to wait for the event to fire before populating the list, hence the if statement seen below.</p>
+
+<pre class="brush: js notranslate">populateVoiceList();
+if (speechSynthesis.onvoiceschanged !== undefined) {
+ speechSynthesis.onvoiceschanged = populateVoiceList;
+}</pre>
+
+<h4 id="Speaking_the_entered_text">Speaking the entered text</h4>
+
+<p>Next, we create an event handler to start speaking the text entered into the text field. We are using an <a href="/en-US/docs/Web/API/GlobalEventHandlers/onsubmit">onsubmit</a> handler on the form so that the action happens when <kbd>Enter</kbd>/<kbd>Return</kbd> is pressed. We first create a new {{domxref("SpeechSynthesisUtterance.SpeechSynthesisUtterance()", "SpeechSynthesisUtterance()")}} instance using its constructor — this is passed the text input's value as a parameter.</p>
+
+<p>Next, we need to figure out which voice to use. We use the {{domxref("HTMLSelectElement")}} <code>selectedOptions</code> property to return the currently selected {{htmlelement("option")}} element. We then use this element's <code>data-name</code> attribute, finding the {{domxref("SpeechSynthesisVoice")}} object whose name matches this attribute's value. We set the matching voice object to be the value of the {{domxref("SpeechSynthesisUtterance.voice")}} property.</p>
+
+<p>Finally, we set the {{domxref("SpeechSynthesisUtterance.pitch")}} and {{domxref("SpeechSynthesisUtterance.rate")}} to the values of the relevant range form elements. Then, with all necessary preparations made, we start the utterance being spoken by invoking {{domxref("SpeechSynthesis.speak()")}}, passing it the {{domxref("SpeechSynthesisUtterance")}} instance as a parameter.</p>
+
+<pre class="brush: js notranslate">inputForm.onsubmit = function(event) {
+ event.preventDefault();
+
+ var utterThis = new SpeechSynthesisUtterance(inputTxt.value);
+ var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
+ for(i = 0; i &lt; voices.length ; i++) {
+ if(voices[i].name === selectedOption) {
+ utterThis.voice = voices[i];
+ }
+ }
+ utterThis.pitch = pitch.value;
+ utterThis.rate = rate.value;
+ synth.speak(utterThis);</pre>
+
+<p>In the final part of the handler, we include an {{domxref("SpeechSynthesisUtterance.onpause")}} handler to demonstrate how {{domxref("SpeechSynthesisEvent")}} can be put to good use. When {{domxref("SpeechSynthesis.pause()")}} is invoked, this returns a message reporting the character number and name that the speech was paused at.</p>
+
+<pre class="brush: js notranslate"> utterThis.onpause = function(event) {
+ var char = event.utterance.text.charAt(event.charIndex);
+ console.log('Speech paused at character ' + event.charIndex + ' of "' +
+ event.utterance.text + '", which is "' + char + '".');
+ }</pre>
+
+<p>Finally, we call <a href="/en-US/docs/Web/API/HTMLElement/blur">blur()</a> on the text input. This is mainly to hide the keyboard on Firefox OS.</p>
+
+<pre class="brush: js notranslate"> inputTxt.blur();
+}</pre>
+
+<h4 id="Updating_the_displayed_pitch_and_rate_values">Updating the displayed pitch and rate values</h4>
+
+<p>The last part of the code simply updates the <code>pitch</code>/<code>rate</code> values displayed in the UI, each time the slider positions are moved.</p>
+
+<pre class="brush: js notranslate">pitch.onchange = function() {
+ pitchValue.textContent = pitch.value;
+}
+
+rate.onchange = function() {
+ rateValue.textContent = rate.value;
+}</pre>