動画の超解像はサーバーGPUで処理する構成が一般的ですが、動画のアップロード時間やプライバシー、GPUコストが課題になります。
Timeline Studio では、NanoVSR・ONNX Runtime Web・WebGPU・FFmpeg.wasmを組み合わせ、動画の4倍高画質化をブラウザ内で完結させています。
処理パイプライン
全体の流れは次のとおりです。
動画を読み込む
↓
12fpsでフレームを抽出
↓
5フレーム単位でNanoVSRへ入力
↓
WebGPUで4倍超解像
↓
PNGフレームを生成
↓
FFmpeg.wasmでH.264/AACのMP4に再構成
素材は端末内で処理され、動画フレームをサーバーへ送信しません。
1枚ずつではなく、5フレームをまとめて処理する
画像用モデルは1フレームを入力しますが、動画用モデルは5フレームの時系列ウィンドウを使用します。
| 用途 | 入力 | 出力 |
|---|---|---|
| 画像 | [1, 1, 3, 180, 320] |
[1, 1, 3, 720, 1280] |
| 動画 | [1, 5, 3, 180, 320] |
[1, 5, 3, 720, 1280] |
単純な1フレーム超解像では、髪や細線などの生成結果がフレームごとに変わり、再生時にちらつきやすくなります。隣接する5フレームを同時に参照することで、時間方向の一貫性を改善します。
実装では動画全体を一度にGPUへ渡さず、5フレームずつ処理します。これにより、GPUメモリのピークを抑え、キャンセルにも比較的早く反応できます。
Web Workerで推論を分離する
ONNX推論をUIスレッドで実行すると、Reactの描画やタイムライン操作が重くなります。そのため推論処理は専用のWeb Workerへ分離しています。
const session = await ort.InferenceSession.create(model, {
executionProviders: ["webgpu"],
graphOptimizationLevel: "all",
});
メインスレッドからは ImageBitmap をTransferableとして送信し、余分なピクセルコピーを避けます。処理後はBitmapとONNX Tensorを明示的に解放します。
bitmap.close?.();
result.sr.dispose?.();
ブラウザ動画処理では、モデルだけでなくBitmap、Canvas、GPU Bufferの解放も重要です。
アスペクト比を維持する
モデル入力は320×180固定ですが、実際の素材には縦動画や正方形動画もあります。
Timeline Studioでは元画像を引き伸ばさず、320×180へcontain配置します。推論後の1280×720画像から有効領域だけを切り出すことで、元のアスペクト比を維持しています。
また、入力素材がすでにモデルの有効出力より大きい場合は、原画像の解像度を保護し、AI結果と元画像のディテールを保守的に合成します。
モデルは固定Revisionでキャッシュする
モデルはHugging FaceとModelScopeの両方から取得でき、中国語環境ではModelScopeを優先します。
ただしキャッシュキーは配信元URLではなく、リポジトリ・Revision・モデルパスから生成します。ミラーが切り替わっても同じモデルを再ダウンロードしません。
const cacheKey =
"/__model-cache__/haixin/timeline-studio-onnx-models/" +
MODEL_REVISION + "/" + modelPath;
本番環境では main ではなく不変のコミットRevisionへ固定しています。ONNX SessionもWorker内で再利用するため、2回目以降の実行ではダウンロードと初期化を繰り返しません。
元の音声を残してMP4を生成する
超解像モデルが返すのは画像フレームです。そこで生成したPNGをFFmpeg.wasmへ渡し、H.264動画としてエンコードします。
元動画に音声があれば、クリップの開始位置と長さに合わせて音声を切り出し、AAC 192kbpsで再結合します。
最終的な出力は次の構成です。
- H.264 / CRF 18
- AAC 192kbps
- yuv420p
- faststart MP4
- 処理フレームレートは12fps
これにより、Canvas上のプレビューだけでなく、音声付きのMP4として編集タイムラインへ戻せます。
現在の制約
現在の実装には次の制約があります。
- WebGPU対応ブラウザが必要
- 処理フレームレートは12fps
- モデル入力は320×180固定
- PNG中間フレームとFFmpeg.wasmが長尺動画でメモリを消費する
今後は VideoFrame → WebGPU → WebCodecs のストリーミング構成に移行することで、PNG中間ファイルを減らし、より長い動画に対応できます。
まとめ
ブラウザ動画超解像では、モデルを動かすだけでなく、フレーム抽出、時系列処理、リソース解放、モデルキャッシュ、音声保持、再エンコードまで一つのパイプラインとして設計する必要があります。
Timeline Studioでは、この一連の処理をローカルファーストな動画編集機能として実装しています。WebGPUやブラウザAIに興味があれば、ぜひリポジトリをチェックしてください。
Top comments (0)