You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome中getDisplayMedia+canvas.drawImage截图空白问题求助

Chrome中getDisplayMedia截图空白问题解决

使用getDisplayMedia实现屏幕截图时,Chrome浏览器会生成空白图片,但Firefox可正常工作。原代码如下:

document
  .getElementById("takeScreenshot")
  .addEventListener("click", async () => {
    const canvas = document.createElement("canvas");
    const context = canvas.getContext("2d");
    const video = document.createElement("video");

    try {
      const captureStream = await navigator.mediaDevices.getDisplayMedia();
      video.srcObject = captureStream;
      video.addEventListener("loadedmetadata", (e) => {
        canvas.width = 600; //e.path[0]?.videoWidth; // set its size to the one of the video
        canvas.height = 600; //e.path[0]?.videoHeight; // video.videoHeight;
        context.drawImage(video, 0, 0);
        const frame = canvas.toDataURL("image/png");
        captureStream.getTracks().forEach((track) => track.stop());

        const img = document.createElement("img");
        img.src = frame;
        document.body.append(img);
      });
    } catch (err) {
      console.error("Error: " + err);
    }
  });

问题原因

Chrome中,loadedmetadata事件仅表示视频元数据加载完成,此时视频帧尚未渲染,调用drawImage会因无可用帧得到空白画布。Firefox在该事件触发时已完成帧加载,因此表现正常。此外,固定canvas宽高为600x600也可能导致尺寸不匹配问题。

修复方案

通过以下调整确保视频帧加载完成后再绘制:

document.getElementById("takeScreenshot").addEventListener("click", async () => {
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");
  const video = document.createElement("video");
  // Chrome要求静音才能自动播放,保证帧正常加载
  video.muted = true;
  video.autoplay = true;

  try {
    const captureStream = await navigator.mediaDevices.getDisplayMedia();
    video.srcObject = captureStream;

    const captureFrame = () => {
      // 使用视频实际尺寸设置canvas,避免固定尺寸导致的问题
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      context.drawImage(video, 0, 0);
      const frame = canvas.toDataURL("image/png");
      // 停止捕获流
      captureStream.getTracks().forEach(track => track.stop());

      const img = document.createElement("img");
      img.src = frame;
      document.body.append(img);
      
      // 移除事件监听,防止重复触发
      video.removeEventListener("timeupdate", captureFrame);
    };

    // 监听timeupdate事件,确保视频有可用帧后再绘制
    video.addEventListener("timeupdate", captureFrame);
  } catch (err) {
    console.error("Error: " + err);
  }
});

关键修复点

  • 给video添加muted和autoplay:Chrome限制未静音的媒体自动播放,静音后才能正常加载并播放视频帧。
  • 改用timeupdate事件:该事件在视频播放进度更新时触发,此时已有可绘制的视频帧。
  • 使用视频原生尺寸:通过video.videoWidth和video.videoHeight设置canvas尺寸,保证截图与捕获内容尺寸一致。

内容的提问来源于stack exchange,提问作者coure2011

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:10:26