WebCodecs API
WebCodecs API ——这是一个 现代 Web 平台的低级媒体处理 API,用于高性能视频/音频编解码,为像游戏流、视频编辑器、实时通信等应用场景提供原生性能级别的能力。
🧠 什么是 WebCodecs API?
WebCodecs API 是一组 JavaScript 接口,允许开发者直接访问浏览器中的音视频编解码器(Codec),以高性能处理原始媒体数据,而不需要走传统的 <video>、MediaStream、Canvas 等更高级抽象层。
📌 它是低延迟、高效率处理媒体数据的工具,适合需要“精细控制”的场景。
📦 核心用途
- 硬件加速的视频/音频编解码
- 用于流式视频处理(如 WebRTC、直播转码)
- 用于录屏、游戏流媒体、虚拟会议等高性能需求场景
- 替代
MediaRecorder等较高级别API,获得更高性能与灵活性
🧱 关键组成组件
WebCodecs 主要提供了以下接口:
| 接口 | 作用 |
|---|---|
VideoDecoder | 解码压缩的视频帧(如 H.264)为原始帧 |
VideoEncoder | 编码原始帧为压缩的视频 |
AudioDecoder | 解码音频 |
AudioEncoder | 编码音频 |
VideoFrame | 表示一帧原始视频(可从 Canvas 或 ImageBitmap 创建) |
EncodedVideoChunk / EncodedAudioChunk | 表示压缩音视频块 |
🔧 使用示例:视频解码
以下是一个简化示例,展示如何用 VideoDecoder 解码一段视频数据:
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 推送进去:
// 假设 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 结构
<canvas id="myCanvas" width="640" height="480"></canvas>✅ 2. JavaScript 编码核心代码
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:
<canvas id="videoCanvas" width="640" height="480"></canvas>✅ JavaScript 解码核心逻辑
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?
告诉我你的目标,我可以给你定制代码!
