🎙️

Web Speech APIを使って主要ブラウザ向けに音声認識機能を提供する

2021/12/29に公開

このエントリーでは、Web Speech APIを使って主要ブラウザ向けに音声認識機能を提供する方法を紹介します。音声認識機能とは、マイク等で入力した音声をテキストで出力する機能です。Web Speech APIを使うJavaScriptのコードを挿入すると、ウェブサイト上で音声認識による入力インターフェースを無料で提供できます。

Web Speech APIの音声認識機能はこれまでChromeでしか使えなかったのですが、今年に入ってSafariとEdgeも利用可能ブラウザに含まれるようになりました(互換性リスト参照)。Firefoxなどサポートしていないブラウザもありますが、多くの利用者がWeb Speech APIによる音声認識機能を使える状況になってきました。

音声認識機能というのは一般的に利用料金がかなりかかります。月数十分までであれば、主要なクラウドサービスの音声認識APIの無料枠を利用する方法があります。しかし、利用時間がその枠を超える懸念がある場合、そしてブラウザ内の機能として使う用途のみであれば、Web Speech APIを使用する判断もあると思います。

音声認識機能の利用例

こちらのサンプルコードをベースに、音声認識機能の利用例を2つ見ていきます。両方ともNetlifyでホストしているので、実際にアクセスして試していただくこともできます。なお、このエントリーの内容はWindows 10のChromeとEdgeでのみ動作確認をしています。

音声認識結果を使ってGoogle検索

Click to Speakボタンを押すと、初回はマイクの利用許可が求められます(サイト単位で許可設定のブラウザへの記憶が可能)。利用許可を行い、検索したい言葉(ここでは「新宿でおすすめのランチ」)をマイクに向かって話しかけると、音声認識されたテキストでGoogle検索してくれます。

https://webspeechapi-example1.netlify.app/

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Web Speech API Example 1</title>
</head>
<body>
<script type="text/javascript">
    const recognition = new webkitSpeechRecognition();
    recognition.lang = "ja-JP";
    recognition.onresult = (event) => {
      if (event.results.length > 0) {
        q.value = event.results[0][0].transcript;
        q.form.submit();
      }
    }
</script>
<form action="https://www.google.com/search?q=">
    <input type="search" id="q" name="q" size=60>
    <input type="button" value="Click to Speak" onclick="recognition.start()">
</form>
</body>
</html>

読み上げた内容をテキスト変換させる

Click to Speakボタンを押すと、初回はマイクの利用許可が求められます(サイト単位で許可設定のブラウザへの記憶が可能)。利用許可を行い、テキスト変換をしたい文章をマイクに向かって読み上げると、音声認識されたテキストが画面に表示されます。音声認識途中(finalフラグがtrueでない)状態のものは文字色がグレーで表示し、確定(finalフラグがtrueになる)状態になったら文字色を黒で表示します。音声認識途中のものと確定状態のものでは変換結果が異なることがあります。通常は文脈を踏まえて変換できる分だけ、確定状態のものの方が変換精度は高い傾向があります。なお、上記画像で読み上げているのは、芥川龍之介の杜子春の冒頭部分です。

https://webspeechapi-example2.netlify.app/

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Web Speech API Example 2</title>
</head>
<body>
    <button id="button" onclick="toggleStartStop()"></button>
    <div style="border:dotted;padding:10px">
      <span id="final_span"></span>
      <span id="interim_span" style="color:grey"></span>
    </div>
  
    <script type="text/javascript">
      let last_content = ""
      let recognizing = false;
      button.innerHTML = "Click to Start";
      
      const recognition = new webkitSpeechRecognition();
      recognition.lang = "ja-JP";
      recognition.continuous = true;
      recognition.interimResults = true;

      const recognition_restart = () => {
        if (recognizing) {
          last_content = final_span.innerHTML
          recognition.start();
          recognizing = true;
          button.innerHTML = "Click to Stop";
        }
      }
      recognition.onend = recognition_restart;
  
      recognition.onresult = (event) => {
        let final = "";
        let interim = "";
        for (let i = 0; i < event.results.length; ++i) {
          if (event.results[i].isFinal) {
            final += event.results[i][0].transcript + "<br>";
          } else {
            interim += event.results[i][0].transcript;
          }
        }
        final_span.innerHTML = last_content + final;
        interim_span.innerHTML = interim;
      }
    
      const toggleStartStop = () => {
        if (recognizing) {
          last_content = final_span.innerHTML
          recognition.stop();
          recognizing = false;
          button.innerHTML = "Click to Speak";         
        } else {
          recognition.start();
          recognizing = true;
          button.innerHTML = "Click to Stop";
          interim_span.innerHTML = "";
        }
      }
  </script>
</body>
</html>

Web Speech APIに向かって短い文章を読み上げる分にはそれほど問題ないのですが、話さないでいると比較的短い時間で音声認識機能が自動停止します。特に、何か別の画面や資料等を見て読み上げしている最中は音声認識機能が自動停止されたことを見落としがちです。私はイベントハンドラーでonEndイベントが意図せずに発生した場合に、強制的に音声認識を再開させる処理を上記のように追加しています。この場合は、Click to Stopボタンを押さない限りは音声認識され続けますが、逆に停止し忘れて音声認識状態が継続されることが懸念されます。

Web Speech APIの音声認識機能に関する所感

音声認識精度

音声認識精度は極めて高いと思います。Chromeについては音声認識エンジンにGoogle Cloud Speech-to-Textと同じ音声認識エンジンを使用しているようです(参考)。一般的な用途においては業界最高水準の音声認識率が出ていると思います。言語モデルのカスタマイズ機能などは提供されていませんので、製品名や業界用語、専門用語などの変換精度が十分でない場面もあるとは思いますが、多くの利用シーンにおいては最適な音声認識エンジンだと思います。

なおWeb Speech APIに限らない話ですが、音声認識APIというのは、入力した音声の品質や話者の発話の明瞭性等でも音声認識精度が大きく変動します。過去にウェブ会議アプリの会議相手が話している音声の出力を入力に変換してWeb Speech APIに認識させる検証をしたことがあります。その際は、ウェブ会議アプリ経由の出力音声は音声品質がかなり抑えられているため、音声認識精度が高くないという結果になりました。マイクでリアルタイムに話している内容を認識させる分には問題ないと思いますが、それ以外のシーンでは音声品質が音声認識精度のネックになることがあると思います。

利用上の考慮点

すべてのブラウザが対応しているわけではないため、利用可能ブラウザの前提を置くか、音声認識機能が使えなくても問題ない範囲の利用に留めることが必要です。また、Web Speech APIはインターネット接続ありが前提で、音声データを音声認識APIに送るという特性上、通信帯域が極端に細かったり、通信料金が従量課金の環境では本格的な利用はためらわれると思います。さらに、音声認識させる内容と音声認識API側でのデータの扱われ方の観点から、個人を特定できる情報や企業の機密情報などを音声認識対象とするかは慎重な判断が必要だと思います。

更新履歴

2024-06-15: 「読み上げた内容をテキスト変換させる」のスクリプトを更新しました。あわせて説明文を修正しました

Discussion