如何通过captureStream和MediaRecorder导出高质量Fabric.js Canvas视频
解决Fabric.js Canvas导出视频画质模糊/像素化问题
你遇到的核心问题是MediaRecorder默认采用高压缩编码,加上canvas的渲染尺寸与录制尺寸不匹配,导致导出视频画质损失。以下是针对性的解决方法:
1. 强制设置MediaRecorder高比特率编码参数
MediaRecorder默认的视频比特率极低,直接导致画质被过度压缩。创建MediaRecorder时传入自定义编码配置,提升比特率:
var canvasStatic = document.getElementById('canvas'); const chunks = []; const stream = canvasStatic.captureStream(30); // 自定义编码配置,设置高比特率(数值越高画质越好,文件体积越大) const recorderOptions = { mimeType: 'video/mp4', videoBitsPerSecond: 5000000 // 5Mbps,可根据需求调整 }; const rec = new MediaRecorder(stream, recorderOptions); rec.ondataavailable = e => chunks.push(e.data); rec.onstop = e => exportBlob(chunks); rec.start(); setTimeout(()=>rec.stop(), duration); function exportBlob(chunks) { let blob = new Blob(chunks, {type: 'video/mp4'}); const vid = document.createElement('video'); vid.src = URL.createObjectURL(blob); vid.controls = true; vid.autoplay = true; let a = document.createElement('a'); a.download = 'title.mp4'; a.href = vid.src; a.click(); // 补充触发下载的逻辑 }
2. 确保Canvas渲染尺寸与显示尺寸一致
浏览器中canvas的width/height是实际绘制像素,CSS的width/height是显示尺寸,若两者不匹配(尤其是高清屏),录制时会出现缩放像素化。给canvas设置正确的像素尺寸:
// 适配高清屏的设备像素比 const dpr = window.devicePixelRatio || 1; const canvas = document.getElementById('canvas'); // 设置canvas实际绘制尺寸为显示尺寸 × 设备像素比 canvas.width = canvas.offsetWidth * dpr; canvas.height = canvas.offsetHeight * dpr; // 调整画布上下文的缩放比例 canvas.getContext('2d').scale(dpr, dpr); // 初始化Fabric.js时开启Retina缩放支持 const fabricCanvas = new fabric.Canvas(canvas, { enableRetinaScaling: true });
3. 优化Fabric.js渲染细节
- 禁用对象缓存,避免Fabric.js生成低分辨率的缓存对象:
// 对所有Fabric对象设置 fabricObject.set('objectCaching', false); - 导出前关闭状态缓存,确保每一帧都是实时渲染:
fabricCanvas.statefulCache = false;
4. 手动逐帧捕获(极端情况备选)
如果captureStream的画质仍达不到要求,可以尝试手动捕获每一帧canvas内容,再通过第三方库(如whammy、FFmpeg.js)合成视频:
// 示例:手动捕获30fps的帧 const frames = []; const captureInterval = setInterval(() => { const dataUrl = canvasStatic.toDataURL('image/png'); frames.push(dataUrl); }, 1000/30); setTimeout(() => { clearInterval(captureInterval); // 调用第三方库将frames数组合成视频 }, duration);
内容的提问来源于stack exchange,提问作者DigitalFrame
相关产品推荐
相关产品推荐

