1920x1080 Canvas录制性能优化及MediaRecorder分辨率适配技术问询
嘿,这个问题我刚好踩过坑,给你一套实用的解决方案,完美匹配你的需求:
一、让WebGL Canvas小尺寸运行+大尺寸显示(保性能)
核心思路是把渲染和显示分离:用一个小尺寸的「离屏Canvas」专门跑WebGL(保证渲染性能),再用一个大尺寸的「显示Canvas」负责把离屏内容放大展示,浏览器的2D渲染上下文做缩放的开销极低,完全不会卡。
- 具体步骤:
- 创建一个不挂载到DOM的离屏Canvas,设置为你能保证流畅的小尺寸(比如800x450,是1080p的1/2.25倍),所有WebGL渲染逻辑都在这里执行。
- 创建一个1920x1080的显示Canvas,挂载到页面上,用
drawImage把离屏Canvas的内容自动缩放画到自己上面。
- 代码示例:
// 离屏Canvas:仅用于WebGL渲染,不显示在页面 const offscreenCanvas = document.createElement('canvas'); offscreenCanvas.width = 800; offscreenCanvas.height = 450; const gl = offscreenCanvas.getContext('webgl'); // 显示Canvas:页面上展示的1080p画布 const displayCanvas = document.getElementById('your-display-canvas'); displayCanvas.width = 1920; displayCanvas.height = 1080; const displayCtx = displayCanvas.getContext('2d'); // 开启平滑缩放(可选,提升视觉效果) displayCtx.imageSmoothingEnabled = true; // 渲染循环 function renderLoop() { // 这里执行你的WebGL渲染逻辑 gl.clear(gl.COLOR_BUFFER_BIT); // ... 你的WebGL绘制代码 ... // 把离屏内容缩放画到显示Canvas displayCtx.drawImage(offscreenCanvas, 0, 0, displayCanvas.width, displayCanvas.height); requestAnimationFrame(renderLoop); } renderLoop();
二、用MediaRecorder录制1080p分辨率的视频
既然已经有了1920x1080的显示Canvas,直接从它捕获媒体流即可,录出来的就是标准1080p视频,而且完全不影响WebGL的渲染性能。
- 关键代码:
// 从显示Canvas捕获1080p的媒体流(指定30fps) const stream = displayCanvas.captureStream(30); // 初始化MediaRecorder,调低码率保证录制流畅 const recorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp9', // 推荐vp9编码,文件小兼容性好 videoBitsPerSecond: 1000000 // 1Mbps码率,满足你"画质低也无妨"的需求 }); // 录制逻辑示例 recorder.start(); recorder.ondataavailable = (e) => { const videoBlob = new Blob([e.data], { type: 'video/webm' }); // 这里可以下载视频或者做其他处理 const url = URL.createObjectURL(videoBlob); const a = document.createElement('a'); a.href = url; a.download = 'canvas-recording.webm'; a.click(); };
额外小贴士
- 如果你的WebGL内容本身分辨率很低,放大后可能有锯齿,可以给显示Canvas的
imageSmoothingEnabled设为true,浏览器会自动做平滑插值,开销几乎可以忽略。 - 离屏Canvas的尺寸可以根据你的性能需求调整,比如640x360(1080p的1/4),性能会更好,缩放后的画质也能接受。
内容的提问来源于stack exchange,提问作者B''H Bi'ezras -- Boruch Hashem




