Kesinの知見置き場

知見を共有していきたいじゃないですか

Webアプリに高機能な音声認識を追加するWeb Speech API

最近、にわかに音声認識というものが盛り上がっています。
スマートフォンに搭載されている、AppleのSiri、NTTドコモのしゃべってコンシェル、Googleの音声検索あたりが有名ですが、お掃除ロボやエアコン、カーナビといった家電にも音声認識機能が搭載されるようになってきました。
認識の精度や意識の問題(人前で機械に話しかけるのはちょっと恥ずかしい)などの課題はありますが、音声認識はアプリや家電のUIの一部としてこれから普及していくと思われます。

ですが、一般の開発者にとって音声認識機能を自分のアプリやウェブサイトに組み込むのはまだまだ難しいです。
Juliusのようなオープンソース音声認識システムもありますが、一般の開発者が自前で音声認識サーバーを立てるのは敷居が高いと思います。

GoogleAppleばっかりズルい!音声認識が自分のWebサイトやアプリに組み込めたら夢が広がるのになー

  • Javascriptで数行で書けて、
  • 自分でサーバー立てる必要もなくて、
  • 認識精度もよくて、
  • 無料で使える音声認識システム

がどこかに転がってないかなー。という夢を見るわけですが、なんと実はもう既にあるのです!

*デモ機能を試すには最新版のChromeでアクセスをお願いします

簡単に使えるSpeech Input API

はいはい、知ってる知ってる。Chrome11から追加されたHTMLのinput要素にx-webkit-speechを加えると、フォームの入力に使えるおもちゃでしょ?
キーボードで打ったほうが100倍速いし、誰が使うんだよww

デモ

入力のみ
入力イベント検出

そんなものもあったかもしれませんが、違います

実はChrome25から、もっと低レベルな操作をJavascriptから行えるWeb Speech APIというのが実装されているのです。

低レベルな操作を可能にするWeb Speech API

Web Speech APIの機能を一つずつ紹介していきます。
その前に、Web Speech APIはSpeech Input APIと違って、最初にJavascriptでオブジェクトを作らないといけません。

var recognition = new webkitSpeechRecognition();
recognition.lang = "ja-JP";

認識する言語は日本語にしておきます。

音声認識の開始と終了

音声認識の開始がstart(), 終了がstop()になります。
認識が終了するとonresultイベントが呼び出されるので、ここで認識結果を取得して表示してあげます。

<input type="button" value="音声認識開始" onclick="recognition.start();"/>
<input type="button" value="音声認識終了" onclick="recognition.stop();"/>
<div id="state">停止中</div>
<div id="recognizedText"></div>
var recognition = new webkitSpeechRecognition();
recognition.lang = "ja-JP"

//話し声の認識中
recognition.onsoundstart = function(){
    $("#state").text("認識中");
};
//マッチする認識が無い
recognition.onnomatch = function(){
    $("#recognizedText").text("もう一度試してください");
};
//エラー
recognition.onerror= function(){
    $("#recognizedText").text("エラー");
};
//話し声の認識終了
recognition.onsoundend = function(){
    $("#state").text("停止中");
};
//認識が終了したときのイベント
recognition.onresult = function(event){
    var results = event.results;
    for (var i = event.resultIndex; i<results.length; i++){
        $("#recognizedText").text(results[i][0].transcript);
};

デモ

停止中

途中の認識結果の表示

Googleの音声検索を使ったことがある人は、認識途中に表示されている文字列が徐々に変化していく様子を見たことがあると思います。Web Speech APIではあの機能も実現することができます。

ソース

var recognition = new webkitSpeechRecognition();
recognition.lang = "ja-JP";
//中間結果の表示オン
recognition.interimResults = true;

recognition.onresult = function(event){
    var results = event.results;
    for (var i = event.resultIndex; i<results.length; i++){
        //認識の最終結果
        if(results[i].isFinal){
            $("#recognizedText").text(results[i][0].transcript);
        }
        //認識の中間結果
        else{
            $("#recognizedText").text(results[i][0].transcript);
        }
    }
};

デモ

停止中

実用性はあまりないような気もしますが、認識を頑張ってる様子が分かるのでユーザビリティ的にはあるとうれしいかもしれません

連続音声認識

個人的にはWeb Speech APIのメイン機能だと思っています。
今までは認識のたびにマイクの使用許可をいちいち出す必要がありましたが、recognition.continuous = trueのパラメータを与えるだけで以下のデモのようにバックグラウンドで音声認識を続けることが可能になります。

デモ

停止中

ついにきたかっっ!!!
ウェブサイトを声だけで操作する日も遠くないでしょう。認識された文章の解析とルール作りは大変だと思いますが、自前でどのようなAPIとでも連携できるSiri以上のアシスタントを作ることも不可能ではありません。他にも、

  • 音声コマンド操作
  • キーボードタイプの代わり
  • 音声テキストチャット
  • 音声コマンドで操作するゲーム

などなど。夢が広がりますね

複数の認識仮説の表示と認識信頼度

音声認識というのは、入力された音声信号をもっともらしい文章に変換するわけですが、それだけではなくて日本語としての”もっともらしさ”という情報も使って音声を日本語に変換します(漢字変換まで自動的に行なってくれるのはこのためです)。
今までは、あらゆる組み合わせの中から正しい日本語としての可能性が最も高い認識仮説を出力してくれていたわけですが、実は裏では他の認識仮説が選ばれる可能性もあったのです。
そのような選ばれなかった他の認識仮説と、それぞれの認識信頼度のスコアも取得することができます。

ソース

var recognition = new webkitSpeechRecognition();
recognition.lang = "ja-JP";
recognition.interimResults = true;
recognition.continuous = true;
//最大10個の認識仮説を取得する
recognition.maxAlternatives = 10;

recognition.onresult = function(event){
    var results = event.results;
    for (var i = event.resultIndex; i<results.length; i++){
        if(results[i].isFinal){
            $("#recognizedText").text(results[i][0].transcript);
        }
        else{
            $("#recognizedText").text(results[i][0].transcript);
        }
    }

    //トップ10の認識仮説の表示
    $("#recognizedDetail").empty();
    for (var i = event.resultIndex; i<results.length; i++){
        if(results[i].isFinal){
            for (var j = 0; j<recognition.maxAlternatives; j++){
                $("#recognizedDetail").append("<p>" + "ランク" + j + " " + results[i][j].transcript +
                                                ": " + results[i][j].confidence +
                                             "</p>");
            }
        }
    }
};

デモ

停止中

*2位以下のスコアが0となっているのは、まだGoogleのシステムが実装されていないためだと思われます。実装はよ。

オマケ的な機能ですが、音声認識で操作をさせるようなシステムを作りこむときには非常に使える情報です。
例えば、スコアが0.5以下だったときは、正しく認識できなかった可能性が高いので、ユーザーにもう一度入力をお願いするという使い方ができるでしょう。
音声コマンドで操作をさせるシステムでは、トリガーとなる言葉が含まれているかが重要になるので、1位の認識結果だけではなくて5位ぐらいまでの中にコマンドが含まれていればOKとすることで、発音が微妙だったりするときにも反応してくれる可能性が高くなります(逆に誤認識でコマンドが暴発する可能性も高くなりますが・・・)

まとめ

単発の音声認識ならSpeech Input API、より高度な音声認識システムを構築したいならWeb Speech APIを使うと今からでもウェブブラウザで実現できます!
(ただし現状ではChromeしか対応していません)

この記事で紹介した全機能を入れたソースコードgistに置いてあります。

おまけ

ブラウジング中のウェブサイト上のあらゆるフォーム入力欄で音声入力が可能になるSpeech Input EnablerというChrome拡張機能もあるようです。
片手が使えない時なんかは意外と便利です。

参考文献