Skip to content

WebCodecs API

WebCodecs API ——这是一个 现代 Web 平台的低级媒体处理 API,用于高性能视频/音频编解码,为像游戏流、视频编辑器、实时通信等应用场景提供原生性能级别的能力。


🧠 什么是 WebCodecs API?

WebCodecs API 是一组 JavaScript 接口,允许开发者直接访问浏览器中的音视频编解码器(Codec),以高性能处理原始媒体数据,而不需要走传统的 <video>MediaStreamCanvas 等更高级抽象层。

📌 它是低延迟、高效率处理媒体数据的工具,适合需要“精细控制”的场景。


📦 核心用途

  • 硬件加速的视频/音频编解码
  • 用于流式视频处理(如 WebRTC、直播转码)
  • 用于录屏、游戏流媒体、虚拟会议等高性能需求场景
  • 替代 MediaRecorder 等较高级别API,获得更高性能与灵活性

🧱 关键组成组件

WebCodecs 主要提供了以下接口:

接口作用
VideoDecoder解码压缩的视频帧(如 H.264)为原始帧
VideoEncoder编码原始帧为压缩的视频
AudioDecoder解码音频
AudioEncoder编码音频
VideoFrame表示一帧原始视频(可从 Canvas 或 ImageBitmap 创建)
EncodedVideoChunk / EncodedAudioChunk表示压缩音视频块

🔧 使用示例:视频解码

以下是一个简化示例,展示如何用 VideoDecoder 解码一段视频数据:

js
const decoder = new VideoDecoder({
  output: frame => {
    // 这里你可以处理每一帧,比如渲染到 canvas
    canvasContext.drawImage(frame, 0, 0);
    frame.close();
  },
  error: e => console.error('解码失败', e)
});

decoder.configure({
  codec: 'vp8', // 或 'h264'
  hardwareAcceleration: 'prefer-hardware',
});

然后你可以将 EncodedVideoChunk 推送进去:

js
// 假设 chunk 是已获取的视频数据块(EncodedVideoChunk)
decoder.decode(chunk);

💡 与其他 API 的比较

API特点用途
MediaRecorder简单封装,适合录制音视频低门槛,控制较少
MediaStream + Canvas可组合,性能中等通常用于摄像头捕获或实时渲染
WebCodecs低级别 API,原始数据控制高性能编码/解码、低延迟需求
WebAssembly + FFmpeg编解码灵活但性能远不如 WebCodecs(需用 JS 处理字节流)

🛠 使用环境支持

✅ WebCodecs 目前在以下浏览器中受支持(截至 2024 年):

浏览器支持情况
Chrome (>=94)✅ 支持完整
Edge✅ 支持
Firefox❌ 尚不支持
Safari🔸 部分支持(实验性)

可在 Can I Use - WebCodecs 查看最新支持情况。


✅ 使用场景推荐

场景推荐使用 WebCodecs 吗?
实时视频编辑、特效、合成✅ 是
虚拟会议、直播推流、低延迟传输✅ 是
简单录屏或摄像头捕获❌ 不一定(可用 MediaRecorder)
全平台兼容需求强❌ 不适用(部分浏览器不支持)

📚 参考资料


如果你想看具体的编码或解码例子(比如将 Canvas 输出编码为 H.264 或将 MP4 解码成帧并渲染),我可以为你写完整代码示例。

下面我为你展示两个真实示例,分别展示如何使用 WebCodecs API:


🧪 示例 1:将 Canvas 内容编码为 H.264 视频(使用 VideoEncoder

这个例子模拟:你有一段动画画在 <canvas> 上,想将其编码为视频帧(例如用于流或录制)

✅ 1. HTML 结构

html
<canvas id="myCanvas" width="640" height="480"></canvas>

✅ 2. JavaScript 编码核心代码

js
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 创建视频编码器
const encoder = new VideoEncoder({
  output: (chunk, metadata) => {
    console.log("已编码一帧:", chunk);
    // 你可以将 chunk 发送给服务器或保存为文件
  },
  error: e => console.error("编码器错误", e)
});

encoder.configure({
  codec: 'vp8', // 或 'avc1.42E01E'(H.264)
  width: canvas.width,
  height: canvas.height,
  framerate: 30,
});

let frameCount = 0;
function drawAndEncode() {
  ctx.fillStyle = `hsl(${frameCount % 360}, 100%, 50%)`;
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // 将 canvas 转为 VideoFrame
  const bitmap = await createImageBitmap(canvas);
  const frame = new VideoFrame(bitmap, {timestamp: frameCount * 33333}); // 30fps ≈ 33333μs
  encoder.encode(frame);
  frame.close();

  frameCount++;
  if (frameCount < 60) requestAnimationFrame(drawAndEncode); // 编码60帧
}
drawAndEncode();

✅ 如果你使用 avc1(H.264)作为 codec,要确保浏览器支持且可能需要使用 .mp4 封装器处理输出块。


🧪 示例 2:解码视频数据并渲染到 canvas(使用 VideoDecoder

假设你有一段视频(或其字节流),我们要将它解析为帧,并显示在 canvas 上。

✅ HTML:

html
<canvas id="videoCanvas" width="640" height="480"></canvas>

✅ JavaScript 解码核心逻辑

js
const canvas = document.getElementById('videoCanvas');
const ctx = canvas.getContext('2d');

const decoder = new VideoDecoder({
  output: frame => {
    ctx.drawImage(frame, 0, 0);
    frame.close();
  },
  error: e => console.error("解码器错误", e)
});

decoder.configure({
  codec: 'vp8', // 或 'avc1.42E01E' (H.264)
});

// 假设你通过 fetch 拿到 WebM 或 MP4 流数据,并解析为 EncodedVideoChunk
async function fetchAndDecode() {
  const response = await fetch('sample-video.webm');
  const buffer = await response.arrayBuffer();

  // 实际使用时你需要将 ArrayBuffer 拆成帧(这需要 demuxer,如 mp4box.js)
  // 这里我们简化:假设你已经有 encodedChunks
  const fakeChunk = new EncodedVideoChunk({
    type: "key", // 或 "delta"
    timestamp: 0,
    data: new Uint8Array(buffer),
  });

  decoder.decode(fakeChunk);
}
fetchAndDecode();

⚠️ 真实项目中你需要“解封装器”(demuxer)如 mp4box.js 或 FFmpeg.wasm 把 MP4/WebM 拆成单帧数据喂给 VideoDecoder


🔄 需要封装器/打包器?

WebCodecs 本身只负责编码/解码原始帧不处理封装(如MP4/WebM文件结构)。要实现“文件保存”或“播放完整视频”的功能,你可以:

  • 编码输出后,使用 WebMWriter 之类的工具包装数据块
  • 或使用 WASM 版 ffmpeg.js 对编码后的块封装成完整视频文件

✅ 如果你需要:

  • 📹 从摄像头采集并编码
  • 📼 实时推送到 WebRTC 服务器
  • 📂 将编码结果保存为 mp4/webm
  • 🧱 自定义音视频混流 + 编解码

我可以提供完整的工程级代码结构,甚至用 ffmpeg.js 配合 WebCodecs 实现完整“录制+压缩+下载”。

是否你有某个具体场景想实现?比如:

  • 在线录屏 + H.264 压缩?
  • 视频流特效编辑?
  • 网页端视频实时解码播放?
  • 推流 WebRTC?

告诉我你的目标,我可以给你定制代码!

Released under the MIT License.