Web SpeechRecognition APIを使って、Web フロントで音声認識をする

面白プロデュース事業部 フロントエンジニアのゆうもやです。 面白法人カヤックでは、毎月社員が個人で制作したものを発表する「つくっていいとも」という会があります。

カヤックの社員は、業務に関係なく自由に制作・試作することで常に新しいアイデアを生み出すことに取り組んでいます。 今回は、そんなアイデアのネタになりそうなWeb SpeechRecognition APIのご紹介です。

Web SpeechRecognition API とは?

Web SpeechRecognition APIは、ブラウザで音声認識を行うためのAPIです。ブラウザに標準で実装されているため、サーバーや特別なライブラリをインストールする必要なく、JavaScriptだけで利用することができます。

対応状況

一部非対応のブラウザはあるものの、ChromeとSafari 14.1以降ではPCとモバイル両対応しているため、多くのユーザーが利用できます。Microsoft Edgeで動かないのが惜しいですね。

Safari

Safari 14.1(2021年)から対応しています。iPhoneでも利用できます。

アプリ内ブラウザでは使用できません。また、ホーム画面に追加されたWebアプリでは使用できません。 また、SpeechGrammar, SpeechGrammarListは未対応です。

Chrome

Chrome25(2014 年)から対応しています。iPhone, Androidでも利用できます。

音声の解析には Google のサーバーが使用されます。そのためインターネットに接続されていない場合は使用できません。その代わり精度はとても良いです。

Firefox, Edge

未対応です。Android, iPhoneでも利用できません。

デモ

この Web SpeechRecognition API にテストの音声を読ませるだけであれば、Google のデモサイトでサクッと試せます。

ですが、それだけでは味気ないので、実際にコードを書いて「ボタンを押すと音声認識を開始、認識途中結果と認識最終結果を表示する」サンプルを作ってみました。

まずはサンプルの動作例をご覧ください。

動作デモ

ソースコード

ということで、サンプルのソースコードを紹介します。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div class="container">
      <button id="button">はじめる</button>
      <div id="result"></div>
    <script type="module" src="/sample.js"></script>
  </body>
</html>

ボタンだけのシンプルなHTMLから、以下のJavaScriptを読み込んでいます。

const SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition
const recognition = new SpeechRecognition()
recognition.lang = 'ja-JP'
recognition.interimResults = true // 中間の認識結果も取得する
recognition.continuous = true // 認識が終了しないようにする


const resultDiv = document.getElementById('result') as HTMLDivElement

//#buttonが押されたら音声認識を開始する
document.getElementById('button').addEventListener('click', () => {
  recognition.start()
})

let finalTranscript = '' // 確定した認識結果
recognition.onresult = async (event) => {
  let interimTranscript = '' // 途中の認識結果
  for (let i = event.resultIndex; i < event.results.length; i++) {
    const results = event.results
    const transcript = results[i][0].transcript
    if (results[i].isFinal) {
      finalTranscript += transcript
    } else {
      interimTranscript = transcript
    }

    resultDiv.innerHTML = finalTranscript + '<i style="color:gray">' + interimTranscript + '</i>'
  }
}
recognition.error = (event) => {
  console.log('エラーが発生しました。', event.error)
}
recognition.onaudiostart = () => {
  console.log('録音が開始されました。')
}
recognition.onend = () => {
  console.log('音声認識が終了しました。')
}
recognition.onnomatch = () => {
  console.log('認識できませんでした。')
}

サンプルコード解説

オブジェクト名の統一

ブラウザによって異なるオブジェクト名を統一して、ブラウザの差異を吸収します。

const SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;

結果の取得

音声認識が完了した時にresultイベントが発行されます。今回の場合、recognition.continuous = trueとしているため、定期的にresultイベントが発行されます。

SpeechRecognition.interimResultsをtrueにすると認識途中の結果を取得することができ、ユーザーが喋っている途中でも暫定の結果を返します。これによりユーザーへフィードバックを早く行えます。

確定した認識結果はSpeechRecognitionResultisFinalプロパティが、trueの場合に取得できます。

注意点

Web SpeechRecognition APIの注意事項として、一定期間マイクの無音が続いた場合、音声認識が自動的に終了します。Chromeの場合は10秒前後で自動終了するため、継続して音声認識を行う場合は注意が必要です。 また、環境とブラウザにによってはローカルホストで動かない場合があります。その場合、HTTPSサーバーを立ち上げて動かしてください。

まとめ

今回は Web SpeechRecognition APIのご紹介をしました。プレフィクスが必要だったり、一部のブラウザでは未対応だったりとまだ使いづらい部分もありますが、フロントエンドだけで音声認識ができるのは非常に魅力的です。Edge とFirefoxは未対応ですが、ChromeとSafariではPCとモバイルの両方に対応しているので、使えるユーザーは非常に多いです。ぜひ、音声認識を活用したサービスを作ってみてはいかがでしょうか。

カヤックでは、新しい技術が好きなエンジニアを募集しています