我可以通过 getDisplayMedia 捕获单个 HTML div 吗?

问题描述 投票:0回答:2

我正在研究屏幕捕获 API,并为此创建了一些小项目。 我的问题是,我可以捕获自定义 HTML div 而不是捕获选项卡、窗口或屏幕吗?

这是我用于捕获屏幕的代码部分。

    captureStream = await navigator.mediaDevices.getDisplayMedia();
    const video = document.createElement("video");
    video.id = "vid";
    addVideoStream(video, captureStream);

谢谢!

javascript node.js webrtc screen-capture
2个回答
2
投票

我不认为有这个选择,但我认为你可以通过这样做来实现这一点:

  1. 获取视频流
  2. 获取元素在 DOM 中的位置和尺寸。
  3. 仅将视频的一部分渲染到
    <canvas>
    ,裁剪为步骤 1 和 2 中的值:
    ctx.drawImage(video, domX, domY, domWidth, domHeight, 0, 0, domWidth, domHeight);

您应该能够使用像素值,但如果视频流被下采样,以百分比计算值可能会具有优势,尽管我认为没有任何浏览器会这样做。

您需要与用户沟通如何选择要捕获的正确选项卡。如果您希望它们捕获您的网页,但最终捕获了整个屏幕或不同的选项卡,您将得到意想不到的结果。


0
投票

这里的技巧是放置一个具有绝对位置的按钮,与 iframe 位于同一 div 内,因此它将具有相同的起始 x 和 y 坐标。您可以将按钮移动到其他位置并将位移添加到drawImage。

因此,当您单击此按钮时,事件会告诉您 iframe x 和 y 坐标是什么,然后您相应地调用 drawImage :

let button = document.querySelector("#screenshotButton");
let iframe = document.querySelector("#screenshotIframe");

button.addEventListener("mouseup", async(event) => {
  const buttonRect = button.getBoundingClientRect();
  const iFrameRect = iframe.getBoundingClientRect();

  // compute where do we click inside the button
  const diffX = event.clientX - buttonRect.x;
  const diffY = event.clientY - buttonRect.y;

  // Determine the fixed screen iframe coordinates
  const iFrameScreenX = event.screenX - diffX;
  const iFrameScreenY = event.screenY - diffY;

  // Create our temporary media elements
  const video = document.createElement("video");
  video.width = iFrameRect.width;
  video.height = iFrameRect.height;

  const canvas = document.createElement("canvas");
  canvas.width = iFrameRect.width;
  canvas.height = iFrameRect.height;

  const context = canvas.getContext("2d");
  if (!context) return;

  // Ratio between device pixels and css pixels
  const ratio = window.devicePixelRatio;

  try {
    const captureStream = await navigator.mediaDevices.getDisplayMedia();
    video.srcObject = captureStream;
    video.onloadeddata = () => {
      context.drawImage(
        video,
        iFrameScreenX * ratio - window.screenX * ratio,
        iFrameScreenY * ratio - window.screenY * ratio,
        iFrameRect.width * ratio,
        iFrameRect.height * ratio,
        0,
        0,
        iFrameRect.width,
        iFrameRect.height,
      );
      captureStream.getTracks().forEach((track) => track.stop());

      canvas.toBlob((blob) => {
        // save your blob here
        // const formData = new FormData();
        // formData.append("file", blob ?? "");
        console.log(blob);
      }, "image/jpeg");
    };
  } catch (err) {
    console.error("Error during screenshot : " + err);
  }
});
<div>
  <button style="position: absolute;" id="screenshotButton">
    Shot
  </button>
  <iframe title="screenshotIframe" id="screenshotIframe" src="https://www.orpha.net" width="100%" height="100%"></iframe>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.