SpeechSynthesis使ってブラウザに喋らせてみた。

最近はもっぱらGoを書いてるkubotakです。

弊社ではSlackチャンネルにて分報を行う文化が一部あります(任意)

ちなみに私は分報はやってないのですが、ふと他のメンバーの分報を覗いた際にこんな呟きを見つけました。

現在アイスタイルでは新卒エンジニア・デザイナに対して技術的な研修を行なっています。Linuxの基礎知識やGit、インフラ・ネットワーク、静的型付け言語での開発などを覚えてもらいます。
そんな彼ら・彼女らの日報は毎日に成長と気づきがあり、我々にも良い影響を与えてくれます。

話が少しそれましたが、そんな日報を声に出して読みたくなるのも共感しますよね。でも、自分が喋るのは面倒だ。

「よし、ブラウザに喋らせよう」

で、完成品がこちら
https://kubotak-is.github.io/katarite/dist/index.html

技術的にはVueCLIを利用してTypeScriptでサクッと作ったものなのであまり語る部分はありません。
今回はSpeechSynthesisというブラウザに実装されているWeb Speech APIの利用についての内容です。

IE以外にはだいたい対応しているようです。
このAPIは文字列を渡し、言語指定をすることでその文字列を合成音声で読み上げてくれるというものです。
使い方は簡単です。

使い方

window.speechSynthesis.getVoices();

これでブラウザに実装されている言語一覧が取得できます。

const utter = new SpeechSynthesisUtterance("読み上げたい文字列");
const voice = window.speechSynthesis.getVoices()[0];
utter.voice = voice;

読み上げたい文字列を SpeechSynthesisUtterance に渡してインスタンス生成を行い、 .voice に先ほどの一覧から言語を選んで(ここでは0番目になってます)セットします。

window.speechSynthesis.speak(utter);

あとは speechSynthesis APIのspeakメソッドに先ほどのオブジェクトを与えることで読み上げを行なってくれます。

注意点

使い方は至って簡単ですが、いくつか注意点があります。

ChromeでVoiceリストが取得できない

Google Chromeで動作確認を行なっていたんですが、 speechSynthesis.getVoices() この関数が空配列を返していました。
対処法としては一度空のspeakを行うと実行できるらしいのですが、以下の方法でも解決できます。

window.speechSynthesis.onvoiceschanged = () => {
  this.voices = window.speechSynthesis.getVoices();
};

onvoiceschanged はVoiceリストに変更がある場合に発火されるトリガーとなっているようで、Chromeの場合は画面の初期表示ではVoiceリストがセットされていないようです。

長い文章は途切れる

時間制限か文字数かは検証してませんが、長い文章は途中で読み上げが中断されてしまいます。
回避方法として今回私が実装したものでは改行で文字列を分割し、SpeechSynthesisUtterance を分割した分だけ生成する方法を行いました。
暫定的な対処法ですが、改行さえしておけば大体全部読み上げられるかと思います。(他にも句読点で区切るなど対処方法はあるかと思います)

また、各ブラウザでこのAPIに対する実装が違う様なので扱う際にはよく調べる必要がありそうです。

さいごに

ブラウザには便利で面白いAPIが沢山あるのでぜひみなさんも遊んで見てはいかがでしょうか!

おまけ。
Ubuntu DesktopのVivaldiにはAPIの実装はありましたがVoiceリストがなかったので利用できませんでした。また、Ubuntu Desktopのfirefoxでも漢字の読み上げは挙動がおかしいです。MacとWinは未検証です。

アイスタイルのヘアカラー担当 元デザイナーの中途4年目です PHP, JavaScript, Golang, Scala, etc