Voicyアドベントカレンダー2021 12日目の記事です。
はじめに
こんにちは、学生インターンとしてVoicyのWebフロントエンド開発をしている、きーくん(komura-c)です。
みなさんは、手を使わず音声でブラウザを操作したいなと思ったことはありませんか?僕はあります。それを実現する手段の一つとして、音声認識があります。この記事は、現状のWeb技術においての音声認識で、自分でもできそうな技術を使ってみようといった趣旨の記事です。
Webブラウザ上での音声認識について調べてみるとTensorflow.jsか、Web Speech APIが出てきます。今回は、機械学習のモデルを用意せずとも日本語で音声認識ができるWeb Speech APIを使ってみました。
Web Speech APIとは
Web Speech APIは、音声合成(Text-to-Speech)と非同期音声認識(Asynchronous Speech Recognition)の2つをウェブアプリに組み込むことを可能にするブラウザのAPIです。
このAPIは、Web技術の標準化団体W3Cのコミュニティグループの一つであるWICGが策定しており、現在はドラフトの段階で実験的な機能となっています。
各ブラウザの対応状況は、以下の通りです。
https://caniuse.com/speech-recognition
自分で試した環境では、GoogleChrome(MacOS)とSafari(MacOS, iOS)で動きました。
Web Speech APIを使ってみる
今回は、音声認識の方を使い、実際に以下のコードを書いてみました。 (TypeScriptで書きたかったため若干型が書いてありますが、ネイティブのJavaScriptでも変わりません)
https://github.com/komura-c/web-voice-recognizer/blob/main/src/scripts/index.ts
// ブラウザAPIのインターフェースを取得 const Recognition = window.SpeechRecognition || window.webkitSpeechRecognition; const recognizer = new Recognition(); // 言語設定を日本語に recognizer.lang = 'ja-JP'; // 解析中の結果を表示する recognizer.interimResults = true; // 認識のたびに継続的に結果を返す recognizer.continuous = true; ... // 結果表示用のHTML要素を取得 const resultDiv = document.getElementById('js-result'); let prevResultText: string; recognizer.onresult = function (event) { const results = event.results; // 中でも最終的な確実性の高い結果を取得 const resultText = results[results.length - 1][0].transcript.trim(); // interimResults, continuousをtrueにすると素早く多くの結果が返ってくるため、一つ前と同じテキストは弾いている if (prevResultText === resultText) { return; } prevResultText = resultText; console.log(resultText); resultDiv.textContent = resultText; actionByResult(resultText); startRecognizer(); } ...
やっていることは単純で、SpeechRecognitionという用意された音声認識サービス用の制御インターフェイスを利用して、startやstop、各イベント後の処理を書いています。
SpeechRecognition - Web API | MDN
音声ボタンを再度クリックして止めるまで認識し続けたかったため、認識完了後も再度認識させるようにしています。
公開したWebページは以下です。
https://komura-c.github.io/web-voice-recognizer/
初めは音声認識をトリガーにして何らかの動作を行うこと、例えば、ブラウザを操作できたら良いなと考えていたのですが、音声認識により受け取った文字を正しくハンドルすること、解析することが結構難しいなと考え、文字起こしだけのページになりました。この辺は、形態素解析など自然言語処理と組み合わせて一緒に使ってみるともっとできることは増えそうだと思いました。
一応GoogleChromeの拡張機能も作ってみました。
拡張機能のボタンを押すことで、上、下という音声を認識してブラウザ上でスクロールを行うことができます。
拡張機能として公開してはいないのですが、以下のコードをダウンロードし、extention
フォルダをchrome://extensions/
にあるパッケージ化されていない拡張機能を読み込む
で指定すると、使ってみることができます。自分なりに色々カスタムして遊んでみると面白いかもしれません。
Web Speech APIのさらに深い仕様については、以下の仕様書が公開されています。
https://wicg.github.io/speech-api/
終わりに
Webブラウザ標準のAPIで音に関するものは多くあるので、今後も追って試していきたいと思いました。
おまけ
今回、Chrome拡張機能の作成も視野に入れていたため、React, Vue, AngularなどのSPAフレームワークをあえて使わずに、実行環境を整えるためにParcelを使いました。
Parcelは設定不要なWebアプリケーションバンドラーを謳っており、Webpackなどと違い設定ファイルが不要ですぐに開発環境が用意できます。 以前Parcelを使ったことはあったのですが、こういった複雑なアプリケーションではない使用用途にはとても体験が良かったです。