低遅延ライブ配信技術比較分析
WebRTC、LL-HLS、SRTの3種類の低遅延ライブ配信技術の原理、遅延データ、選定アドバイスを詳しく比較します。
続きを読む →ブラウザにネイティブ級の動画処理能力をもたらす
WebAssembly(略称WASM)は、モダンブラウザで実行可能な低レベルアセンブリ言語であり、ネイティブコードに近い実行性能を持っています。C/C++/Rustなどの言語をWASMにコンパイルすることで、開発者はブラウザ内で高性能な計算集約型タスクを実行できます。動画処理はその中でも最も重要な応用シーンの1つです。
WebAssemblyは動画処理分野で幅広い応用シーンがあり、特にユーザーのプライバシーを保護しサーバー負荷を軽減する必要があるシーンで威力を発揮します:
ブラウザ側で動画フォーマット変換を完了できるため、ユーザーは動画をサーバーにアップロードする必要がなく、プライバシーを保護できると同時に帯域幅とサーバーコストも節約できます。MP4、WebM、AVI、MKVなど、さまざまなフォーマット間の変換をサポートしています。
簡単な動画のトリミング、切り取り、結合、回転などの操作はすべてブラウザ側で実行できます。WebCodecs APIやCanvas APIと組み合わせることで、軽量なオンライン動画編集ツールを実現できます。
リアルタイム動画フィルター、美肌処理、エフェクトの重ね合わせなど。FFmpegのフィルターシステムをWASMに移植するか、OpenGL ESをWebGL経由で使用してハードウェアアクセラレーションによる動画エフェクトを実現します。
ブラウザ内で非標準フォーマットの動画をデコードしたり、動画を再エンコードしたりできます。モダンブラウザはすでに多くの動画コーデックをサポートしていますが、特殊なシーンではカスタムエンコード/デコードが必要になる場合があります。
動画のメタ情報の高速抽出、サムネイル生成、字幕抽出など。これらの操作は通常、動画ファイルヘッダーを解析するだけでよく、完全なデコードは不要なため、フロントエンドで実行するのに非常に適しています。
以下は、代表的な動画処理タスクにおけるWebAssemblyと純JavaScriptのパフォーマンス比較です(1080p動画の場合):
注意点として、WebAssemblyの性能はネイティブに近いものの、それでもローカルのC++プログラムより約20~50%低速です。主な原因はブラウザのサンドボックス機構とSIMDサポートの制限によるものです。
FFmpegは最も人気のあるオープンソースの動画処理ツールです。これをWebAssemblyにコンパイルすることで、ブラウザ内で直接FFmpegの強力な機能を使用できます。ffmpeg.wasmは現在最も成熟したFFmpeg WASMプロジェクトです。
// ffmpeg.wasm の導入
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({ log: true });
async function initFFmpeg() {
await ffmpeg.load();
}
async function convertVideo(inputFile) {
// ファイルを FFmpeg 仮想ファイルシステムに書き込み
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(inputFile));
// FFmpeg コマンドを実行
await ffmpeg.run('-i', 'input.mp4', '-c:v', 'libvpx', '-crf', '30', 'output.webm');
// 出力ファイルを読み込み
const data = ffmpeg.FS('readFile', 'output.webm');
// ダウンロードリンクを作成
const url = URL.createObjectURL(
new Blob([data.buffer], { type: 'video/webm' })
);
return url;
}
async function extractThumbnail(videoFile, time = '00:00:01') {
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(videoFile));
await ffmpeg.run(
'-i', 'input.mp4',
'-ss', time,
'-vframes', '1',
'-s', '320x180',
'thumb.jpg'
);
const data = ffmpeg.FS('readFile', 'thumb.jpg');
return URL.createObjectURL(
new Blob([data.buffer], { type: 'image/jpeg' })
);
}
async function videoToGif(videoFile) {
ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(videoFile));
await ffmpeg.run(
'-i', 'input.mp4',
'-t', '5',
'-vf', 'fps=10,scale=320:-1',
'output.gif'
);
const data = ffmpeg.FS('readFile', 'output.gif');
return URL.createObjectURL(
new Blob([data.buffer], { type: 'image/gif' })
);
}
ffmpeg.wasmは機能が豊富ですが、純粋なソフトウェアエンコード/デコードの性能には限界があります。実際のアプリケーションでは、ブラウザのネイティブ機能を組み合わせて性能を向上させることができます:
WebCodecs APIはブラウザが提供する低レベルの音声・動画エンコード/デコードAPIで、ハードウェアエンコーダー/デコーダーに直接アクセスできます。一般的なコーデック(H.264、VP8、VP9、AV1)については、WebCodecsを優先的に使用するのが良いでしょう。性能はWASMのソフトウェアエンコード/デコードよりもはるかに優れています。
// WebCodecs を使用して動画フレームをデコード
const decoder = new VideoDecoder({
output: (frame) => {
// デコード後の動画フレームを処理
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(frame, 0, 0);
frame.close();
},
error: (e) => console.error(e)
});
decoder.configure({
codec: 'avc1.42001E',
codedWidth: 1920,
codedHeight: 1080
});
// 1フレームをデコード
decoder.decode(new EncodedVideoChunk({
type: 'key',
timestamp: 0,
data: chunkData
}));
ベストプラクティスはハイブリッドソリューションを採用することです:フォーマット解析と非標準コーデックにはWASMを使用し、主流コーデックのエンコード/デコードにはWebCodecsを使用し、動画エフェクトとレンダリングにはWebGL/Canvasを使用します。それぞれの長所を活かして最適なパフォーマンスを達成します。
動画フィルターはWebAssemblyのもう1つの重要な応用シーンです。以下のいくつかの方法で実装できます:
FFmpegのフィルターシステムを利用すると、ぼかし、シャープ化、色彩調整、ウォーターマーク重ね合わせなど、数百種類の動画フィルターエフェクトを実現できます。メリットは機能が豊富なこと、デメリットは性能が低くリアルタイム処理には適さないことです。
リアルタイム動画フィルターには、WebGL Shaderを使用するのがより良い選択肢です。GPUの並列計算特性により、ピクセル単位の操作が非常に効率的で、60fpsのリアルタイムフィルターエフェクトを実現できます。
顔認識や画像セグメンテーションなどの複雑なアルゴリズムの場合、まずCanvasでピクセルデータを取得し、次にWASMで計算を行い、最後に結果をCanvasに描画し直す方法があります。
FFmpeg WASMファイルは通常比較的大きく(数十MB)、ページの読み込み速度に影響します。推奨事項:
WebAssemblyのメモリは事前に割り当てる必要があり、高解像度動画を処理する場合はメモリ消費量が非常に大きくなります:
モダンブラウザはすべてWebAssemblyをサポートしていますが、以下の点に注意が必要です:
WebAssemblyはブラウザ側での動画処理に新たな扉を開き、本来サーバーで行う必要があったタスクをユーザーのローカルで効率的に実行できるようにしました。ffmpeg.wasmなどのプロジェクトにより、FFmpegの強力な機能をブラウザで直接使用できるようになり、WebCodecsやWebGLなどのネイティブAPIと組み合わせることで、優れたパフォーマンスを持つ純フロントエンドの動画処理アプリケーションを構築できます。
実際の開発では、具体的なシーンに応じて適切な技術ソリューションを選択し、ブラウザのネイティブ機能を最大限に活用し、WASMはネイティブ機能がカバーできない部分で使用するのが良いでしょう。同時にファイルサイズ、メモリ管理、ユーザー体験にも注意を払い、Webアプリケーションにネイティブに近い動画処理能力をもたらしましょう。
ブラウザ側での動画処理の魅力を体験してみませんか?M3U8→MP4ツールと動画圧縮ツールをお試しください。すべての処理はブラウザのローカルで完了し、安全かつ迅速です。