Screen Capture API自动截图生成白色Base64问题排查
问题原因及解决方案
你的代码中,自动捕获出现空白画面的核心问题是错误地直接执行了resolve函数,而非将其绑定到onplaying事件的回调逻辑中,导致Promise在视频还未完成画面渲染时就提前完成,此时调用takeScreenshot()无法捕获到有效帧。
具体问题分析
原代码中这一行存在逻辑错误:
return new Promise(resolve => video.onplaying = resolve(captureStream));
这里直接执行了resolve(captureStream),并将执行结果(undefined)赋值给video.onplaying,相当于Promise立刻进入resolved状态,此时视频元素还没完成媒体流的加载和第一帧的渲染,自然只能捕获到空白画面。而手动点击按钮时,已经过了足够时间让视频完成渲染,所以能正常工作。
修正后的代码
const video = document.getElementById("video"); const canvas = document.getElementById("canvas"); const text = document.getElementById("text"); const startButton = document.getElementById("startButton"); const captureButton = document.getElementById("captureButton"); const context = canvas.getContext("2d"); captureButton.addEventListener("click", function() { try { navigator.mediaDevices.getDisplayMedia({ audio: false }).then(captureStream => { video.srcObject = captureStream; // 关键修正:将resolve放入onplaying的回调函数中,等待事件触发再执行 return new Promise(resolve => video.onplaying = () => resolve(captureStream)); }).then((captureStream) => { takeScreenshot(); }) } catch (err) { console.error("Error: " + err); } }); startButton.addEventListener("click", function() { takeScreenshot(); }); function takeScreenshot() { // 复用已获取的context,无需重复调用getContext context.drawImage(video, 0, 0, 300, 150); const frame = canvas.toDataURL("image/png"); text.innerHTML = frame; }
额外优化说明
- 将
takeScreenshot声明为标准函数,避免隐式全局变量 - 复用提前获取的
context对象,减少不必要的DOM API调用 - 如果需要更精准地捕获第一帧,也可以考虑使用
video.onloadeddata事件,该事件会在视频的第一帧加载完成后触发
内容的提问来源于stack exchange,提问作者luuksen
相关产品推荐
相关产品推荐

