動画に字幕を付けるツール OpenSubs を作っています(AGPL-3.0 のオープンソース)。サーバーを使わず、文字起こしから MP4 への焼き込みまで全部ブラウザのタブの中で完結させています。この記事では、その処理の流れと、つまずいたところを紹介します。
利益相関:筆者は OpenSubs の開発に関わっています。
全体の流れ
- 動画ファイルをブラウザで読み込む(object URL。アップロード用のエンドポイントはそもそも存在しません)
- 音声を取り出し、VAD で「人が話している区間」を判定
- Whisper で文字起こし
- よくある幻覚フレーズを除去
- 字幕を編集・翻訳・スタイル設定
- libass(WebAssembly)で描画し、WebCodecs で MP4 にエンコード
Whisper をブラウザで動かす
transformers.js で ONNX 版の Whisper を読み込みます。WebGPU が使える環境では GPU、無ければ WebAssembly で CPU 実行です。
モデルは 3 種類から選べます。
| モデル | サイズ | 備考 |
|---|---|---|
| Tiny | 約 40 MB | 英語のみ |
| Base | 約 80 MB | 多言語 |
| Small | 約 250 MB | 多言語、精度重視 |
モデルは Hugging Face から一度だけダウンロードされ、以後はブラウザにキャッシュされます。ネットワークに出ていくのはモデルの取得だけで、音声は出ていきません。
言語は自動判定もできますが、話されている言語を指定したほうが確実に精度が上がります。候補から他の言語を外せるからです。
幻覚対策:VAD と定型句の除去
Whisper は無音や BGM の区間で、実際には話されていない文を出力することがあります。日本語だと「ご視聴ありがとうございました」が典型です。
対策は 2 段構えです。
- Whisper の前に Silero VAD を通す。人の声が無い区間はそもそも Whisper に渡しません。
- それでも出てきた定型句を後処理で消す。「ご視聴ありがとうございました」「チャンネル登録お願いします」のような、学習データ由来と思われるフレーズをリストで除去しています。
副作用として、VAD にとって歌は「話し声」ではありません。音楽だけの動画では「人の声が見つからない」と表示されます(ボタンを押せばそのまま生成することもできます)。
焼き込み:libass を WebAssembly で
字幕の描画には libass(ffmpeg が使っているのと同じレンダラー)を WebAssembly にコンパイルしたものを使い、WebCodecs で MP4 にエンコードし直しています。プレビューで見えている字幕がそのままピクセルになり、音声はそのままコピーです。
日本語や中国語は、英語のようにスペースで改行できません。縦長(9:16)の動画だと一行が画面からはみ出すので、画面幅に合わせて文字の間で改行を入れる処理を ASS の書き出し側に入れました。日本語・中国語用のフォントも同梱しているので、焼き込んだ字幕が四角(豆腐)になることもありません。
使ってみる
https://opensubs.app で動画をドロップするだけです。アカウント登録は不要で、手元で動く機能はすべて無料です。有料なのはサーバー側でのクラウド翻訳だけです(1,000 クレジット 5 ドル)。翻訳は Chrome 内蔵の翻訳で端末内でも無料で使えます。
制約もあります。受け付けるのは動画ファイルのみで、音声だけのファイルは読み込めません。字幕のタイミングはまだ編集できません。現在のビルドはリリース候補版です。