
本文介绍一种不依赖屏幕共享 api 的纯前端方案:通过 canvas 截取目标 div 的实时渲染画面并转为媒体流,再结合 recordrtc 实现精准区域录制,避免用户手动选择窗口的交互负担。
本文介绍一种不依赖屏幕共享 api 的纯前端方案:通过 canvas 截取目标 div 的实时渲染画面并转为媒体流,再结合 recordrtc 实现精准区域录制,避免用户手动选择窗口的交互负担。
在 Web 开发中,若需录制页面中某个特定区域(例如一个动态图表、演示卡片或交互式组件),直接调用 navigator.mediaDevices.getDisplayMedia() 会触发系统级屏幕选择弹窗,不仅体验割裂,更无法保证只捕获目标
真正可控的解决方案是将目标 DOM 元素“绘制”到 。该方法绕过浏览器权限限制,完全由 JS 控制录制范围,且无需用户授权屏幕共享。
✅ 核心实现步骤
- 获取目标 元素(确保其已渲染且无跨域 iframe 或 canvas 内容);
- 创建等尺寸
- 调用 canvas.captureStream() 生成持续更新的视频流(注意:需启用 requestAnimationFrame 循环重绘以支持动态内容);
- 将流传入 RecordRTCPromisesHandler 进行录制。
以下是完整、可运行的增强版代码(含动态刷新与错误处理):
async function startRecording() { const recorderBtn = document.getElementById('recorder'); // 假设按钮 ID 为 'recorder' const targetDiv = document.getElementById('divToRecord'); // 替换为你的 div ID if (!targetDiv) { console.error('目标 div 未找到,请检查 ID 是否正确'); return; } recorderBtn.innerHTML = 'Stop recording'; // 创建 canvas 并设置尺寸(适配设备像素比,提升清晰度) const canvas = document.createElement('canvas'); const dpr = window.devicePixelRatio || 1; canvas.width = targetDiv.clientWidth * dpr; canvas.height = targetDiv.clientHeight * dpr; const ctx = canvas.getContext('2d'); ctx.scale(dpr, dpr); // 缩放上下文以匹配高清屏 // 每帧绘制(支持动画/实时更新内容) let animationId; const drawFrame = () => { ctx.clearRect(0, 0, targetDiv.clientWidth, targetDiv.clientHeight); ctx.drawImage(targetDiv, 0, 0); animationId = requestAnimationFrame(drawFrame); }; // 启动绘制循环 drawFrame(); // 从 canvas 创建媒体流(默认 30fps) const stream = canvas.captureStream(30); try { const recorder = new RecordRTCPromisesHandler(stream, { type: 'video', mimeType: 'video/webm;codecs=vp9' // 可选:指定编码格式 }); await recorder.startRecording(); // 示例:3 秒后停止(实际项目中应由用户点击控制) setTimeout(async () => { await recorder.stopRecording(); const blob = await recorder.getBlob(); // 下载录制结果 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'recorded-div.webm'; a.click(); URL.revokeObjectURL(url); // 清理资源 cancelAnimationFrame(animationId); recorderBtn.innerHTML = 'Start recording'; }, 3000); } catch (error) { console.error('录制失败:', error); cancelAnimationFrame(animationId); recorderBtn.innerHTML = 'Start recording'; } }⚠️ 关键注意事项
- CSS 渲染限制:drawImage() 仅捕获元素的当前渲染像素,不支持 CSS transform、filter(如 blur)、clip-path 等部分高级样式;建议用 getComputedStyle 预处理或改用 html2canvas(但性能较低);
-
跨域资源:若 内含跨域图片或
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










