Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What is going on with this article?
@7shi

Web Speech API で読み上げ位置を取得

ブラウザでテキストを読み上げる Web Speech API で読み上げ位置を取得します。

Web Speech API

語学学習に音声合成が使えないかとクラウドサービスを調べましたが、契約が必要で課金が気になります。

Amazon Pollyの初回利用から12カ月間は、500万字/月まで無料。500万字なら、音声の長さで100時間超は使える計算となるので、試しに使ってみるには十分です。

最近のブラウザでは API として実装されていることを知りました。これなら契約しなくても利用できます。

概要は次の記事に詳しいです。

詳細はこれらに譲り、要点をサンプルで示します。

設定

音声の再生は環境に依存します。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 と組み合わせて読み上げをキャンセルする方法を説明した記事です。

自分の勉強を兼ねてブログで語学記事を執筆することを計画しており、テンプレートを作成中です。対訳を記述しやすくするなどの利便性に注力しています。

6
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
7shi

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
6
Help us understand the problem. What is going on with this article?