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

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

ウェブ 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);
    };
}

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

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

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

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

ユーザーの声に耳を傾けて、ウェブページを魅力的にしましょう。

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

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