Web Speech APIを使う

Web Speech APIが面白そうだなーという純粋な興味で試してみた。

仕様書はこれしか見つからないのだけど、この文章はSpeech API Community GroupによるものでW3C Standardじゃないって書いてある。現状はまだブラウザ独自仕様で標準化はされていないっぽい。
Web Speech API Specification

ブラウザのサポート状況は以下です。これ書いてる現時点ではChromeSafariのみでFirefoxIEは使えない。スマホAndroidChromeiOSSafariは使えるっぽい。
Can I use... Support tables for HTML5, CSS3, etc

試しに作ってみたデモ↓
http://minamijoyo.github.io/sandbox/webspeech/index.html
初期化の仕方がブラウザによって違うのかなぜかPC版のChromeでしか動かないので、PC版のChromeでお試し下さい。

デモのソース↓
https://github.com/minamijoyo/sandbox/tree/gh-pages/webspeech

以下、適当な解説。

音声の合成はSpeechSynthesisUtteranceというのを使う。newでインスタンス化してパラメータ設定してspeakでしゃべる。すごい簡単に使える。合成された音声は若干ぎこちない感は漂ってるけどまぁ聞き取れるレベルではある。

  $('#synthesisButton').click(function(){
    var synthesis = new SpeechSynthesisUtterance();
    synthesis.volume = 1;
    synthesis.rate = 1;
    synthesis.pitch = 2;
    synthesis.text = $('#synthesisText').val();
    synthesis.lang = $('#selectLang').val();

    speechSynthesis.speak(synthesis);
  });

音声の認識はwebkitSpeechRecognitionというのを使う。同じくnewでインスタンス化してstartで呼び出すが、こちらは明示的にstopもできるように初期化処理を外出ししてます。設定値 continuous = true にすると毎回startを呼ばなくても連続で認識します(が、しばらく放っておくと停止します)。interimResults = trueにすると認識処理中の中間状態の候補が取得できて見ため面白いです。recognitionFormControlはボタンのdisable/enableを切り替えるだけのサンプル用に勝手に定義した関数なので気にしないでください。

  var recognition = new webkitSpeechRecognition();
  recognition.continuous = true;
  recognition.interimResults = true;

  recognitionFormControl(false);

  $('#recognitionStartButton').click(function(){
    recognitionFormControl(true);
    recognition.lang = $('#selectLang').val();

    recognition.start();
  });

  $('#recognitionStopButton').click(function(){
    recognitionFormControl(false);

    recognition.stop();
  });

認識結果はonresultイベントでハンドリングします。isFinalがtrueになってると認識完了して確定した情報です。confidenceから認識の照合率が取得できます。

  recognition.onresult = function(e){
    var results = e.results;
    for(var i = e.resultIndex; i<results.length; i++){
      if(results[i].isFinal){
        $('#recognitionText').val(results[i][0].transcript).removeClass('isNotFinal');
        var confidence = results[i][0].confidence;
        $('#messageArea').html(
          "<p>state: onresult<br>" +
          "confidence: " + confidence + "</p>"
          );

      }else{
        $('#recognitionText').val(results[i][0].transcript).addClass('isNotFinal');
      }
    }
  };

試してみた感想。何度か試してみると認識がうまくいく時といかない時の挙動の違いが何から来るのかよくわからず、まだ標準化されてなくてこれから感漂うAPIですが、Webを音声で操作できるようになるとなんか夢が広がりそうで期待したいAPIです。あと日本語の音声認識はそこそこ上手くいくのに英語の音声認識がイマイチなのは発音が悪いんじゃボケとChromeさんに言われている気分になります。結構凹みます。