利用区域拍摄功能更好地分享标签页

François Beaufort
François Beaufort

Web 平台已允许 Web 应用捕获当前标签页的视频轨道。它现在附带区域捕获,这是一种用于剪裁这些视频轨道的机制。Web 应用会将当前标签页的一部分指定为其关注区域,浏览器会裁剪该区域以外的所有像素。

以前,Web 应用可以“手动”剪裁视频轨道。也就是说,Web 应用可以直接操控每一帧。这既不可靠,也不高效。区域捕获解决了这些缺点。现在,Web 应用可以指示浏览器代其执行此操作。

区域捕获简介

您已经创建了一个具有 Dynamic ContentTM 的网站。它是有史以来最好的 Web 应用,人们常常会协作使用它。下一步或许是嵌入虚拟会议功能。你决定就这么干。您需要与现有视频会议服务提供商合作,将他们的 Web 应用作为跨源 iframe 嵌入。视频会议 Web 应用会将当前标签页捕获为视频轨道,并将其传输给远程参与者。

一个浏览器窗口的屏幕截图,其中显示了一个 Web 应用,该应用突出显示了主要内容区域和跨源 iframe。
主要内容区域为蓝色,跨源 iframe 为红色。

不会那么快...你现在肯定不想将其他人的视频传输回他们,对吧?最好将那部分裁掉。但是如何做到呢?嵌入的 iframe 不知道您展示了什么内容以及在何处展示,因此,如果没有一些帮助,它就无法进行剪裁。从理论上讲,您可以传递预期的坐标。但是,如果用户调整窗口大小,会发生什么情况呢?滚动视口?放大或缩小?以会导致布局变化的方式与页面交互?即使您向捕获的 iframe 发送新的坐标,时间问题也仍可能导致一些帧被剪裁错误。

然后,我们使用“区域捕获”您的网页上有 Element(可能是包含主要内容的 <div>)。将其命名为 mainContentArea。您希望视频会议 Web 应用远程截取并共享由此元素的边界框定义的区域。因此,您从 mainContentArea 派生了 CropTarget。您需要将此 CropTarget 传递给视频会议 Web 应用。使用此 CropTarget 剪裁视频轨道后,该轨道上的帧现在仅包含位于 mainContentArea 边界框内的像素。如果 mainContentArea 更改了大小、形状或位置,则视频轨道会跟随一起,而无需来自任一 Web 应用的任何额外输入。

我们再回顾一下这些步骤:

您可以在 Web 应用中定义 CropTarget,方法是调用 CropTarget.fromElement() 并将您选择的元素作为输入。

// In the main web app, associate mainContentArea with a new CropTarget
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

您将 CropTarget 传递给视频会议 Web 应用。

// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);

视频会议 Web 应用要求浏览器按照从主 Web 应用收到的剪裁目标,对自拍视频轨道调用 cropTo(),从而将轨道剪裁为 CropTarget 定义的区域。

// In the embedded video conferencing web app, ask the user for permission
// to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
  preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

// Start cropping the self-capture video track using the CropTarget
// received over window.onmessage.
await track.cropTo(cropTarget);

// Enjoy! Transmit remotely the cropped video track with RTCPeerConnection.

一切就绪!大功告成。

深入解析

功能检测

如需检查 CropTarget.fromElement() 是否受支持,请使用以下命令:

if ("CropTarget" in self && "fromElement" in CropTarget) {
  // Deriving a target is supported.
}

派生 CropTarget

我们来重点了解名为 mainContentArea 的元素。如需从中派生 CropTarget,请调用 CropTarget.fromElement(mainContentArea)。如果成功,返回的 Promise 将使用新的 CropTarget 对象进行解析。否则,如果您创建的 CropTarget 对象数量超出合理范围,则请求会被拒绝。

const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

Element 不同,CropTarget 对象可序列化。例如,可以使用 Window.postMessage() 将其传递给另一个文档。

剪裁

在截取标签页时,视频轨道会实例化为 BrowserCaptureMediaStreamTrack,而后者是 MediaStreamTrack 的子类。该子类提供 cropTo()。调用 track.cropTo(cropTarget) 以开始剪裁为 mainContentArea(即 cropTarget 的派生来源)的轮廓。

如果成功,当可以保证所有后续视频帧都包含位于 mainContentArea 的边界框内的像素时,系统就会解析 Promise。

如果不成功,promise 将被拒绝。如果出现以下情况,则会发生这种情况:

  • CropTarget是在另一个标签页中铸造的。(目前,敬请关注。)
  • CropTarget 派生自已不存在的元素。
  • 该轨道具有克隆。(请参阅问题 1509418)。
  • 当前曲目不是自拍视频轨道;请参见下文。

cropTo() 方法会在所有标签页拍摄视频轨道中公开,而不仅仅是用于自拍。因此,在尝试剪裁轨道之前,建议先检查用户是否选择了当前标签页。这可以使用捕获句柄来实现。您还可以使用 preferCurrentTab 请求浏览器引导用户进行自拍。

// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);

如需还原为未剪裁状态,请使用 null 调用 cropTo()

// Stop cropping.
await track.cropTo(null);

遮挡和被遮挡的内容

对于区域捕获,只有目标的位置和大小会产生影响,Z-index 则无关。系统将拍摄遮挡目标的像素。系统不会截取目标的遮挡部分。

这是“区域拍摄”实质上是剪裁的推论。一种替代方案是元素级捕获,未来将是它自己的 API;也就是说,只捕获与目标相关联的像素,而不考虑遮挡。与简单剪裁相比,此类 API 具有一组不同的安全性和隐私权要求。

区域捕获 API 和元素级捕获 API 不同结果的图片。
区域捕获对遮挡内容的行为。

安全和隐私设置

通过区域捕获,已观察标签页内所有像素的 Web 应用可以主动移除其中一些像素。这从理论上来说是安全的,因为不会再获得任何新信息。

“区域捕获”可用于限制向远程参与者发送哪些信息。例如,您可能想分享一些幻灯片,但不想分享演讲者备注。

包含幻灯片和演讲者备注的浏览器窗口的屏幕截图。
包含幻灯片和演讲者备注的 Web 应用。
我们非常不希望远程共享备注。提示区域捕获。

请注意,“区域捕获”功能在本地不会添加任何安全保证。将轨道移交给另一个文档时,接收文档仍可取消剪裁轨道,并获得对已截取标签页的所有像素的访问权限。

Chrome 会在捕获的标签页的边缘绘制蓝色边框。在剪裁时,Chrome 通常会在剪裁的目标周围绘制蓝色边框。

演示

您可以通过运行 Glitch 上的演示来体验区域拍摄功能。是 请务必查看源代码

浏览器支持

浏览器支持

  • 104
  • 104
  • x
  • x

只有在桌面设备上通过 Chrome 104 提供区域捕获功能。

后续步骤

下面简要介绍了在未来如何改进网络屏幕共享功能,让您先睹为快:

  • “区域捕获”将支持对其他标签页进行捕获。
  • 条件聚焦:允许捕获的 Web 应用指示浏览器将焦点切换到捕获的显示 Surface,或避免此类焦点更改。
  • 可能会提供元素级捕获 API

反馈

Chrome 团队和网络标准社区希望了解您使用 Region Capture 的体验。

向我们介绍设计

“区域捕获”是否有什么无法按预期运行?或者,您是否缺少实现自己的想法所需的方法或属性?对安全模型有疑问或意见?

  • GitHub 代码库中提交规范问题,或者添加您对现有问题的看法。

实施时遇到问题?

您在 Chrome 的实现过程中是否发现了错误?或者,实现是否与规范不同?

  • 访问 https://new.crbug.com 提交 bug。请务必提供尽可能多的细节,并提供关于重现的简单说明。Glitch 非常适用于分享轻松快速的重现问题。

表示支持

您打算使用 Region Capture 吗?您的公开支持有助于 Chrome 团队确定各项功能的优先级,并向其他浏览器供应商展示支持这些功能的重要性。

请向 @ChromiumDev 发送 tweet 消息,告诉我们您在何处以及如何使用它。

致谢

感谢 Joe Medley 审核本文。