読み上げ機能を自作する
概要
- Chrome が読み上げてくれないページがある
- 読み上げのブラウザ拡張を作ってみようか
- 作り始めたけど課題がいろいろあるな
- なんとかできた
- 実は Edge で便利に読み上げができることがわかったので今後はそっちを使うだろう
背景と始動
前回書いたように、ウェブ記事を Chrome の読み上げ機能でよく聞いている。ただ、ログインが必要なサイトは Chrome は読み上げてくれない。また、一部ログインが不要でもなぜか読み上げてくれないページがある。そして最近 NHK のサイトが大幅に変わって、 Chrome が読み上げてくれなくなった。日々の情報収集において多少の不便となっており、なんとかならんかなと思って解決手段を自作できないかと思案し始めた。Text-to-Speech API エンドポイント叩くだけならそんなに難しくないやろと思って Firefox 用の拡張を自作することにした(10/19 開始)。
最初の構想とプロトタイピング
最初は、Text-to-Speech API とのやり取りを司る公開サーバーを 1 個用意して、ブラウザ拡張から何らかの認証情報とウェブページの内容を表示することでブラウザ上で音声読み上げができるのではないかと考えた。
ブラウザ拡張の作成
ブラウザ拡張をこれまで作ったことなかったので 9 割 vibe coding した。WebExtensions APIs は一切わからなかったし今もわからないけど画面上に表示できたし目的のエンドポイントに POST を投げられるようになった。
バックエンドの作成
遊びで作る小規模なサーバーは最近はすべて Google の edge function 系のサービスを使っている。以前は Cloud Functions というものだったが今は Cloud Run というサービスに吸収された。Cloud Run は Docker image をそのままビルドしてホストする感じなので専用 SDK も不要となりかなり簡単に開発・デプロイできる。そして今回は Cloud Run でホストするエンドポイントを Hono で作ってみた。Hono の感想は後ほど。
実際に試験的に Google の Text-to-Speech API を叩いてみたところ、低スペックの音声モデルでも 8 分ほどの音声の生成に十数秒かかる1ことがわかり、その間にブラウザタブを切り替えたりするとレスポンスが失われることがわかったので別の方法を考える必要が出てきた。
別の方法
音声の生成と取得を非同期で行う方法として思いついたのが下記の 2 通り。
- Web worker か何かを使ってブラウザ拡張のバックグラウンドでレスポンスを待機させてレスポンスが返ってきたらローカルストレージに保存してブラウザ拡張上で音声を再生する
- 非同期で音声を生成するバックエンドをもう一つ用意して、音声データをクラウドストレージに保存して、別途ストレージから音声を返すエンドポイントを作成する
1 つ目は本当に空想で、web worker が何なのかよくわかっていないしブラウザ拡張でそういうことができるのか全くわからなかったので 2 つ目のやり方でやることにした。はじめに想定していたよりもパーツが多くなってしまうが致し方ない。
完成
数週間が過ぎてなんとか出来上がった。下が全体のフローを表した図。
そして再生を行うフロントエンドはこんな感じ。

ソースコードを公開することも考えたけど、サーバー間通信で指定するサービスアカウントの情報とかを全部環境変数にいれるのが面倒くさくなって一部ベタ書きになってしまっているので公開はしない。
Edge の読み上げ機能
今日午前中に最終調整が終わって、実際に使ってご満悦だったのだが、もしかして Edge に読み上げ機能あったりしないかなと思いつきで Edge をインストールして使ってみたら見事に存在するし、どんなページも読み上げてくれるし、しかも Chrome よりも人間に近い声で良い感じだったので今後は Edge でウェブページを読み上げてもらうと思う。(終)
全体的な感想
実作業時間は 40 時間くらいだと思う。Gemini と GitHub Copilot と頻繁にやり取りしながら作った。LLM のおかげで明らかに開発スピードが上がっている。正直ブラウザ拡張にあまり興味がないのでそのあたり調べるのも面倒だなと思っていた(思っている)が、そういうのを全部 LLM に書いてもらえるのでかなり開発が楽しい。