WebCodecs API実践:ブラウザ側低遅延音声動画エンコード・デコード

技术架构(更新: 2026年6月14日)

ブラウザ音声動画処理の進化

手法 遅延 フレームレベル制御 コーデックアクセス 適用場面
<video> + MSE 2-5s コンテナ形式 再生、ストリーミング
FFmpeg.wasm 1-3s 完全 トランスコード(ただし30MB+)
WebCodecs <100ms ネイティブ リアルタイム処理、低遅延トランスコード

WebCodecsはブラウザ内蔵コーデックへの直接アクセスを提供。WASMラッパー不要で遅延を10-50分の1に削減。


コアオブジェクト概要

VideoFrame  ←→  VideoEncoder  ←→  EncodedVideoChunk
                                    ↓ ネットワーク / ストレージ
AudioData   ←→  AudioEncoder  ←→  EncodedAudioChunk
                                    ↓
VideoFrame  ←→  VideoDecoder  ←→  EncodedVideoChunk
AudioData   ←→  AudioDecoder  ←→  EncodedAudioChunk

VideoFrame:ゼロコピーフレーム操作

const frame = new VideoFrame(canvas, { timestamp: performance.now() * 1000 });

const bitmap = await createImageBitmap(videoElement);
const frame2 = new VideoFrame(bitmap, { timestamp: 0 });

console.log(frame.width, frame.height, frame.duration, frame.timestamp);

frame.close();

重要:VideoFrameはGPUテクスチャ参照を保持します。close()を呼んで解放しないとGPUメモリリークが発生します。


VideoEncoder:動画エンコード

const encoder = new VideoEncoder({
  output: (chunk, metadata) => {
    const data = new Uint8Array(chunk.byteLength);
    chunk.copyTo(data);
    handleEncodedChunk(chunk.type, data, chunk.timestamp, metadata);
  },
  error: (e) => console.error('エンコードエラー:', e),
});

encoder.configure({
  codec: 'avc1.64001E',
  width: 1920,
  height: 1080,
  bitrate: 5_000_000,
  framerate: 30,
});

encoder.encode(frame, { keyFrame: true });
frame.close();

サポートコーデック

コーデック codec文字列 特徴
H.264 avc1.64001E 最も広い互換性
H.265 hev1.1.6.L93.B0 圧縮率40%向上、互換性制限
VP8 vp8 WebM形式
VP9 vp9 YouTubeデフォルト
AV1 av01.0.01M.08 次世代、最高圧縮率

VideoDecoder:動画デコード

const decoder = new VideoDecoder({
  output: (frame) => {
    ctx.drawImage(frame, 0, 0);
    frame.close();
  },
  error: (e) => console.error('デコードエラー:', e),
});

decoder.configure({
  codec: 'avc1.64001E',
  codedWidth: 1920,
  codedHeight: 1080,
});

const chunk = new EncodedVideoChunk({
  type: isKeyFrame ? 'key' : 'delta',
  timestamp: timestamp,
  data: encodedData,
});
decoder.decode(chunk);

AudioEncoder / AudioDecoder

const audioEncoder = new AudioEncoder({
  output: (chunk) => {
    const data = new Uint8Array(chunk.byteLength);
    chunk.copyTo(data);
    handleAudioChunk(data, chunk.timestamp);
  },
  error: (e) => console.error(e),
});

audioEncoder.configure({
  codec: 'aac',
  sampleRate: 48000,
  numberOfChannels: 2,
  bitrate: 128000,
});

const audioData = new AudioData({
  format: 'f32-planar',
  sampleRate: 48000,
  numberOfFrames: 1024,
  numberOfChannels: 2,
  timestamp: 0,
  data: float32Array,
});
audioEncoder.encode(audioData);
audioData.close();

実践:動画形式トランスコードパイプライン

ToolsKuの動画変換のコアトランスコードフロー:

async function transcodeVideo(inputChunks: EncodedVideoChunk[], config: TranscodeConfig) {
  const decodedFrames: VideoFrame[] = [];

  const decoder = new VideoDecoder({
    output: (frame) => decodedFrames.push(frame),
    error: (e) => { throw e; },
  });
  decoder.configure(inputConfig);

  for (const chunk of inputChunks) {
    decoder.decode(chunk);
  }
  await decoder.flush();

  const encoder = new VideoEncoder({
    output: (chunk) => muxer.addChunk(chunk),
    error: (e) => { throw e; },
  });
  encoder.configure(config.outputCodec);

  for (const frame of decodedFrames) {
    encoder.encode(frame);
    frame.close();
  }
  await encoder.flush();

  return muxer.finalize();
}

MSEとの比較:低遅延シナリオ

指標 MSE (MediaSource) WebCodecs
初フレーム遅延 2-5s(バッファリング戦略) <100ms
フレームレベル制御 ❌ appendBufferのみ ✅ フレーム単位エンコード/デコード
リアルタイム処理 ❌ 追加ミュクシング必要 ✅ ネイティブサポート
メモリ使用量 高(バッファキュー) 低(フレーム単位処理)
適用 動画再生 リアルタイム通信、トランスコード、解析

パフォーマンス実測:動画圧縮シナリオ

1080p 30fps 60秒動画のH.264→H.265トランスコード:

手法 トランスコード時間 出力サイズ 遅延
FFmpeg.wasm 180s 12MB 3s(WASM初期化)
WebCodecs 45s 12MB <100ms

WebCodecsはブラウザネイティブコーデックを活用—4倍高速、30MB+のWASMダウンロード不要。


よくある質問

WebCodecsはどのコンテナ形式をサポートするか?

WebCodecsは生のエンコードチャンクのみを処理し、コンテナミュクシングは行いません。mp4-muxerやwebm-muxer等のライブラリでMP4/WebMにパッケージ化する必要があります。

動画ファイルからエンコードデータを取得する方法?

MP4 demuxer(mp4box.js等)でMP4ファイルを分離し、EncodedVideoChunkを抽出してDecoderに入力します。

VideoFrameはWorker間で転送可能か?

可能です。VideoFrameはTransferableを実装しており、postMessage(frame, [frame])でゼロコピー転送してWorkerで処理できます。


まとめ

WebCodecs APIはブラウザに音声動画コーデックへの直接アクセスを提供し、ゼロコピーフレーム処理と<100ms遅延のエンコード/デコードを実現します。VideoEncoder/Decoderが動画、AudioEncoder/Decoderが音声、VideoFrame/AudioDataがフレームレベル操作を担います。demuxer/muxerライブラリと組み合わせることで、ブラウザ側で完全な低遅延動画トランスコードパイプラインを構築できます。

ブラウザローカルツールを無料で試す →

#WebCodecs#视频编解码#AudioData#VideoFrame#低延迟