puppeteer で ChromeのSpeechRecognitionAPI を使用する


はじめに

みなさんこちらの記事は読んでいただけたでしょうか?
.NET Frameworkで音声認識をしてzoomのビデオ画面に字幕を出す

Zoomの自分の動画スペースに字幕を表示する方法なんですが、
先日とあるオンラインMeetUpイベントで使用してみたところ、
Webカメラに字幕を重ねて表示して配信することができました!!!実用的!

何言ってるかわからない問題

前回の記事にも載せましたが、.NET Frameworkの音声認識は
精度が良いとは言えたものではなく、とてもガバガバな認識結果を返してきます。

すると「え、それは何を表示してるの?」と、しゃべっている内容と表示文字列が
リンクしていると認識されない現象が発生します。致命的!

ほかの方法を試す

というわけで、違う方法を試してみることにします。今回、配信界隈を調査する中で
ゆかりねっと」という音声合成ソフトがあることを知りました。
調べるとどうも内部的に Google Chrome を使用しているそうです。

はて、GoogleChrome?と思って調べたところ SpeechRecognition API なるインタフェースが策定されていることを知りました。

SpeechRecognition - Web API | MDN

それは試さない手はない、ということで試してみました。

実現方法

字幕制御を nodejs で実装したので、同じく nodejs でいきます。

  • OS: Windows 10 64bit
  • ブラウザ: Google Chrome 81
  • node: v12.16.2

puppeteer の導入

今回はChromeを使用する予定なので puppeteer-core で。

npm install --save puppeteer-core

実装

調べれば2, 3秒でわかる内容なんですが、今回学びがあったので備忘録程度に。

ブラウザとの双方向通信

puppeteer を使用して、ブラウザとデータのやり取りをする場合

  • puppeteer → page : page.evaluate
  • page → puppeteer : page.exposeFunction

というのを使用すると良いです。

await page.exposeFunction("functionA", result => {
  console.log(result);
});

とあらかじめしておくことで、

await page.evaluate( () => {
  window.functionA("result from browser");
});

このように、ブラウザ側で functionA が呼び出せるようになります。

headless でSpeechRecognition APIが使用できない

puppeteer.launch のときに headless:true とすることで、
ヘッドレス Chromeが使用でき、無駄にWindowが表示されないなど便利なのですが、
今回は start イベントが発生せず、どうも使用不可っぽいので、画面サイズ0でお茶を濁しました。

「マイクを使用する」ダイアログを表示させない

これですね。これツールを起動するたびに出ても仕方ないのでスキップするオプション
--use-fake-ui-for-media-stream を使用します。

ソース

というわけでソースコード載せておきます。ほぼ MDN のまんま。

ただただ認識した文字列をコンソールに出力するだけです。

実行結果

前回記事でも試した

  • zoomに字幕を表示しています
  • 字幕のテストだよ
  • 字幕なんだけど、ちゃんと音声認識されてるんですかね

の3つを試しました。

良い感じですね。さすが!!

感想

結果は劇的に向上しました。が、1つ注意点として挙げられるのが
「オフライン実行できない」ということです。

Chromeの音声認識はサーバーに音声データを挙げて、サーバー側で結果を出力します。
なので、プライバシー問題もありますし、ネットワークの状況によっては使用不可だったり、レスポンスがめちゃくちゃ遅くなることも考えられます。

なので、今回は「クラウドサービスを使用したら音声認識精度が劇的に上がった」程度に捉えておくのがいいのかな、と思います。
サクッと効果が実感できるソリューションなのは間違いないですが。

終わりに

なぜか puppeteer で制御したけど意味あったのか・・・?

参考URL