WebCodecs API 實戰:瀏覽器端低延遲音視訊編解碼
技术架构(更新於 2026年6月14日)
瀏覽器音視訊處理的演進
| 方案 | 延遲 | 幀級控制 | 編解碼 | 適用場景 |
|---|---|---|---|---|
<video> + MSE |
2-5s | ❌ | 封裝格式 | 播放、串流媒體 |
| FFmpeg.wasm | 1-3s | ✅ | 完整 | 轉碼(但體積大 30MB+) |
| WebCodecs | <100ms | ✅ | 原生 | 即時處理、低延遲轉碼 |
WebCodecs 提供對瀏覽器內建編解碼器的直接存取,無需 WASM 封裝,延遲降低 10-50 倍。
核心物件概覽
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();
實戰:視訊格式轉碼管線
工具庫 視訊轉換 的核心轉碼流程:
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 60s 視訊做 H.264→H.265 轉碼:
| 方案 | 轉碼耗時 | 輸出體積 | 延遲 |
|---|---|---|---|
| FFmpeg.wasm | 180s | 12MB | 3s(WASM 初始化) |
| WebCodecs | 45s | 12MB | <100ms |
WebCodecs 利用瀏覽器原生編解碼器,速度提升 4 倍,且無需下載 30MB+ 的 WASM。
常見問題
WebCodecs 支援哪些容器格式?
WebCodecs 只處理裸編解碼資料(raw chunks),不處理容器封裝。需要搭配 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#低延迟