MediaRecorder 本身不支持直接生成 MP4,仅原生支持 WebM 或 OGG;需用 ffmpeg.wasm 前端转码或后端 FFmpeg 处理才能获得标准 MP4(H.264+AAC),而 Canvas 逐帧动画录制成视频完全可行——通过 captureStream() 获取媒体流,MediaRecorder 录制为 WebM,再按需转换。

MediaRecorder 本身不支持直接生成 MP4 容器(如 .mp4),它在大多数浏览器中仅原生支持 WebM(VP8/VP9 + Opus/Vorbis)或 OGG 格式。想得到标准 MP4(H.264 + AAC),需借助编码库(如 ffmpeg.wasm)在前端转封装或重编码,或后端处理。但“Canvas 逐帧动画录制成视频”这个目标完全可行——关键在于正确捕获 Canvas 帧、构造 MediaStream,并用 MediaRecorder 录制为浏览器兼容的视频格式(通常是 WebM)。
1. 创建可录制的 Canvas 媒体流
Canvas 本身不是媒体源,需通过 captureStream() 方法将其转为实时媒体流(MediaStream)。该方法返回一个包含视频轨道的流,帧率可指定(如 60 fps):
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 启动捕获流(60fps)
const stream = canvas.captureStream(60);
const mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm; codecs=vp9' // 或 'vp8', 推荐 vp9 获得更好压缩
});
注意:captureStream() 在 Chrome、Edge、Firefox 中支持良好;Safari 目前不支持该 API(截至 Safari 17),若需兼容 Safari,必须改用离线渲染 + ImageBitmap + 构造 VideoFrame + WritableStream 编码(复杂度高,暂不展开)。
2. 控制逐帧动画与录制时机
不要用 requestAnimationFrame 直接绘图后立刻调用 mediaRecorder.requestData() —— 这会导致帧率失控、音画不同步。正确做法是:
立即学习“前端免费学习笔记(深入)”;
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 让动画逻辑与 Canvas 绘制解耦,确保每帧都按时绘制(例如固定 16ms 间隔)
- 在开始录制前启动动画循环,录制期间保持 canvas 持续刷新
- 用
mediaRecorder.start()启动录制,stop()结束,由 MediaRecorder 自动按流帧率采样
示例动画循环:
let animationId;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制你的逐帧内容(如 sprite 移动、路径动画等)
drawFrame(Date.now());
animationId = requestAnimationFrame(animate);
}
// 开始录制时:
mediaRecorder.start();
animate(); // 确保流持续有帧
// 结束录制:
mediaRecorder.stop();
cancelAnimationFrame(animationId);
3. 获取并导出视频 Blob(WebM)
MediaRecorder 会触发 dataavailable 事件,每次返回一段视频数据(Blob)。建议累积所有片段再合并,避免分段丢失:
const chunks = [];
mediaRecorder.ondataavailable = event => {
if (event.data.size > 0) chunks.push(event.data);
};
mediaRecorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
// 下载或播放
const a = document.createElement('a');
a.href = url;
a.download = 'animation.webm';
a.click();
};
4. 如何获得真正的 MP4?(需额外处理)
若业务强依赖 MP4(如微信内嵌、某些 CMS 系统),有两种实用路径:
- 前端转码(轻量场景):使用 ffmpeg.wasm 将 WebM Blob 转为 MP4(H.264/AAC)。注意性能开销大,适合短动画(≤10秒)、现代设备。
-
后端合成(推荐):将 WebM Blob 上传至服务端(如 Node.js + fluent-ffmpeg),用 FFmpeg 转封装或重编码:
ffmpeg -i input.webm -c:v libx264 -c:a aac -movflags +faststart output.mp4
不建议在前端强行模拟 MP4 容器——MP4 是复杂二进制格式,无标准 JS API 支持直接构造,硬写易出错且不可靠。


















