数ヶ月前、Webアプリにファイル変換機能を追加する必要がありました。シンプルに、ユーザーがファイルをドロップして異なる形式で返却するだけというものです。最初は「APIを呼べば終わり」と思いました。しかし、ユーザーのファイルをサーバーに送信することは、ストレージコスト、プライバシーの懸念、交通量急増時のキュー発生を意味します。そこで、WebAssemblyを使って完全にクライアント側で処理する方法を検討しました。以下は、その過程で学んだことと、初心者向けチュートリアルには載っていない部分です。
なぜWASMを使うのか
ほとんどのフォーマット変換ロジック(コーデック、コンテナ解析、圧縮)はC/C++またはRustで書かれており、そのエコシステムは成熟しています。これをWASMにコンパイルすることで、ブラウザタブ内でネイティブに近いデコード/エンコード速度を、サーバーへの往復なしで実現できます。多くのフォーマットにおいて、これはリアルタイム利用に十分な速度です。
ここでの最も一般的なビルディングブロックは、FFmpegのWASMビルド(人気のffmpeg.wasm)です。これにより、FFmpegがネイティブでサポートするのと同じコーデックを、Web Worker内で動作させることができます。
問題が発生するポイント
メモリが最初の壁になる
WASMのリニアメモリには上限があり、大規模な動画ファイルはすぐに上限を超えます。入力ファイルを分割処理するか、ストリーミングするか、非常に大きなファイルはブラウザでは動作しないことを受け入れる必要があります。これを回避するきれいな方法はありません。これは単なる設定変更ではなく、本当の上限です。
スレッドは半分しかサポートされていない
マルチスレッドWASMビルドに必要なSharedArrayBufferは、サーバー側で特定のCOOP/COEPレスポンスヘッダーを必要とします。これらのヘッダーを設定し忘れると、アプリはサイレントにシングルスレッドモードにフォールバックし、エラー表示なしに遅くなります。
バンドルサイズは予想以上に重要
WASMのFFmpegビルドは20〜30MBになることがあります。専用変換ツールであれば問題ありませんが、変換がサブ機能であるアプリに追加するのは厳しく、初回読み込み時間に大きな影響が出ます。
フォーマット対応は万能ではない
動画と音声はよく対応しています。一部の独自画像フォーマット(特定のカメラRAWバリアントや古い文書フォーマット)は、オープンなWASMライブラリではサポートされていないか、正しく処理するにはより重いカスタムビルドが必要です。
実際に優れている点
ユーザーが主に一般的なフォーマット(MP3/WAV/AAC音声、標準画像タイプ、一般的な動画コーデック)を変換し、ファイルサイズが中程度であれば、ブラウザ側のWASM変換は堅実でプライバシーに配慮したアプローチです。ファイルがデバイスから出ることはありません。これは実際、ツールの背後にあるのと同じトレードオフです。
自分で構築する場合、上記のメモリとヘッダーの問題に本気で時間を割いてください。これらは、2MBのサンプルではなく実際のファイルでテストするまで表面化しない部分です。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.