音声駆動型ウェブアプリ - Web Speech API の概要

新しい JavaScript Web Speech API を使用すると、ウェブページに音声認識機能を簡単に追加できます。この API を使用すると、Chrome バージョン 25 以降の音声認識機能をきめ細かく柔軟に制御できます。以下に、話していると認識されたテキストがほぼすぐに表示される例を示します。

Web Speech API のデモ

デモ / ソース

仕組みを詳しく見ていきましょう。まず、webkitSpeechRecognition オブジェクトが存在するかどうかをチェックし、ブラウザが Web Speech API をサポートしているかどうかを確認します。アップグレードしていない場合は、ブラウザをアップグレードすることをおすすめします。(この API はまだ試験運用版のため、現時点ではベンダー プレフィックスが付いています)。最後に、音声インターフェースを提供する webkitSpeechRecognition オブジェクトを作成し、その属性とイベント ハンドラの一部を設定します。

if (!('webkitSpeechRecognition' in window)) {
    upgrade();
} else {
    var recognition = new webkitSpeechRecognition();
    recognition.continuous = true;
    recognition.interimResults = true;

    recognition.onstart = function() { ... }
    recognition.onresult = function(event) { ... }
    recognition.onerror = function(event) { ... }
    recognition.onend = function() { ... }
    ...

continuous のデフォルト値は false です。ユーザーが話を終了すると、音声認識も終了します。このモードは、短い入力フィールドなどの単純なテキストに適しています。このデモでは true に設定して、ユーザーが話しているときに一時停止しても認識が継続するようにします。

interimResults のデフォルト値は false です。認識ツールから返される結果は最終的なものであり、変更されることはありません。このデモでは true に設定されているため、暫定的な結果を早期に取得でき、変更される可能性があります。デモを注意してご覧ください。グレーのテキストは暫定的なテキストで、ときどき変更される可能性があります。黒いテキストは認識ツールからの回答で、最終としてマークされ、変更されることはありません。

開始するには、ユーザーがマイクのボタンをクリックします。このコードがトリガーされます。

function startButton(event) {
    ...
    final_transcript = '';
    recognition.lang = select_dialect.value;
    recognition.start();

音声認識ツールの音声言語を「lang」に設定するユーザーが選択プルダウン リストで選択した BCP-47 値。たとえば、英語(米国)の場合は「en-US」を選択します。設定されていない場合、デフォルトで HTML ドキュメントのルート要素と階層の lang が使用されます。Chrome の音声認識は、さまざまな言語(デモソースの「langs」の表を参照)と、このデモに含まれていない右から左に記述する言語(he-IL や ar-EG など)をサポートしています。

言語を設定したら、recognition.start() を呼び出して音声認識ツールを有効にします。このメソッドは音声のキャプチャを開始すると、onstart イベント ハンドラを呼び出し、新しい結果セットごとに onresult イベント ハンドラを呼び出します。

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);
    };
}

このハンドラは、これまでに受け取ったすべての結果を 2 つの文字列 final_transcriptinterim_transcript に連結します。結果の文字列には、ユーザーが「新しい段落」と言ったときなどに「\n」が含まれる可能性があるため、linebreak 関数を使用してこれらを HTML タグの <br> または <p> に変換します。最後に、これらの文字列を、黒のテキストでスタイル設定された final_span とグレーのテキストでスタイル設定された interim_span という、対応する <span> 要素の innerHTML として設定します。

interim_transcript はローカル変数です。前回の onresult イベント以降、中間結果はすべて変更されている可能性があるため、このイベントが呼び出されるたびに完全に再構築されます。for ループを 0 から開始することで、final_transcript についても同じことができます。ただし、最終的なテキストは変更されないため、final_transcript をグローバルに設定して、このイベントのコードを少し効率化しました。これにより、このイベントは event.resultIndex で for ループを開始し、新しい最終テキストを追加するだけで済みます。

これで完了です。コードの残りの部分は、すべての要素をきれいにするためのものです。状態を維持し、ユーザーに有益なメッセージを表示し、マイクボタンの GIF 画像を静的なマイク、マイクスラッシュ画像、点滅する赤いドットのマイクアニメーションの間で入れ替えます。

マイクスラッシュの画像は、recognition.start() が呼び出されると表示され、onstart が起動すると mic-Animation に置き換えられます。これは通常、スラッシュがあまり目立たない程度の速さで発生しますが、音声認識を初めて使用する場合は、ユーザーにマイクの使用許可を求める必要があります。この場合、onstart はユーザーが許可した場合にのみ呼び出されます。HTTPS でホストされているページでは許可を繰り返し要求する必要はありませんが、HTTP でホストされているページでは許可が繰り返し要求されています。

ユーザーの声に耳を傾けることで、ウェブページをより魅力的に見せることができます。

皆様からのご意見、ご感想をお待ちしております。

この API からの音声データを Google がどのように取り扱うかについては、Chrome のプライバシー ホワイトペーパーをご覧ください。