ブラウザでテキストを読み上げる Web Speech API で読み上げ位置を取得します。
Web Speech API
語学学習に音声合成が使えないかとクラウドサービスを調べましたが、契約が必要で課金が気になります。
Amazon Pollyの初回利用から12カ月間は、500万字/月まで無料。500万字なら、音声の長さで100時間超は使える計算となるので、試しに使ってみるには十分です。
最近のブラウザでは API として実装されていることを知りました。これなら契約しなくても利用できます。
概要は次の記事に詳しいです。
- Webページでブラウザの音声合成機能を使おう - Web Speech API Speech Synthesis
- Web Speech APIの実装 - Speech Synthesis API | CodeGrid
詳細はこれらに譲り、要点をサンプルで示します。
設定
音声の再生は環境に依存します。Chrome や Chromium Edge はデフォルトでオンラインのエンジンが利用できます。その他の環境では以下を参照してください。
読み上げ
主に 2 つのインターフェイスを使います。
API がサポートされているブラウザでは speechSynthesis
というインスタンスがデフォルトで存在します。読み上げは SpeechSynthesisUtterance
のインスタンスで言語を指定して speechSynthesis.speak()
に渡します。読み上げの中止は speechSynthesis.cancel()
です。
実装例を示します。API が使える環境かどうかは speechSynthesis
の存在をチェックします。
See the Pen Web Speech API のテスト (1) by 七誌 (@7shi) on CodePen.
↑ エラーになる場合は一度 CodePen を開いてから、この記事をリロードしてください。
音声の指定
使用できる音声が複数ある場合、それらを選択できるようにします。音声をローカルにインストールしていなくても、Chromium 系のブラウザではオンラインのエンジンが使えるものもあります。
音声一覧は speechSynthesis.getVoices()
で取得できます。注意点として初回の呼び出しで空の配列が返って来る環境があります。その場合は裏で準備が進んでいるため、しばらくして再度呼べば取得できます。取得のタイミングは onvoiceschanged
イベントで通知されます。
SpeechSynthesisUtterance に選択した voice を設定します。Android の Chrome では lang の設定も必要なため、voice から lang を取得して設定します。
u.voice = opt[0].voice;
u.lang = u.voice.lang;
それらの仕様を踏まえた実装例です。取得に失敗した場合、コールバックで再度取得します。
See the Pen Web Speech API のテスト (2) by 七誌 (@7shi) on CodePen.
読み上げ位置を取得
今どこを読み上げているかという情報は onboundary
イベントで通知されます。
※ エンジンによってはサポートされていません。Chrome では、PC 版で使えるオンラインエンジン(Google 日本語)や Android の Google テキスト読み上げではイベントが発生しないようです。
実装例を示します。最後に onend
イベントで選択を解除します。
See the Pen Web Speech API のテスト (3) by 七誌 (@7shi) on CodePen.
読み上げの際に形態素解析が行われているのが垣間見えて面白いです。
SSML
仕様には onmark
イベントがあります。これが使えれば細かい状況が把握できそうです。
発話された utterance が SSML (音声合成マークアップ言語) の "mark" タグに達した時に発火します。
しかし現状では SSML はサポートされていない環境が多いようです。
仕様上、text にプレーンテキストのほかに SSML を指定できるのですが、現在、一部の Voice でしか対応していないようです。
実際に試してみました。タグは無視されるか、テキストとして読み上げの対象になるかで、まだ使える段階ではないようです。
関連記事
Promise や async/await と組み合わせる方法を説明した記事です。
Promise と組み合わせて読み上げをキャンセルする方法を説明した記事です。
自分の勉強を兼ねてブログで語学記事を執筆することを計画しており、テンプレートを作成中です。対訳を記述しやすくするなどの利便性に注力しています。