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

弗朗索瓦·博福
François Beaufort
伊拉德·阿隆
Elad Alon

Web 平台已允许 Web 应用捕获当前标签页的视频轨道。它现在附带了 Region Capture,这是一种用于剪裁这些视频轨道的机制。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 具有一组不同的安全和隐私要求。

Region Capture 和 Element-level Capture API 的不同结果的图片。
区域捕获在遮盖内容时的行为。

安全和隐私设置

区域捕获允许已经观察标签页中所有像素的 Web 应用主动移除其中一些像素。它非常安全,因为它无法获得新信息。

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

包含幻灯片和演讲者备注的浏览器窗口的屏幕截图。
一款包含幻灯片和演讲者备注的 Web 应用。
强烈建议您不要远程分享备注。提示区域捕获。

请注意,区域捕获不会在本地添加任何安全保证。将轨道交给其他文档时,接收方文档仍然可以取消剪裁轨道,并获取对所拍摄标签页的所有像素的访问权限。

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

演示

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

浏览器支持

浏览器支持

  • 104
  • 104
  • x
  • x

只有桌面版 Chrome 104 中提供了区域捕获功能。

后续步骤

下文简要介绍了即将在不久的将来改进网络屏幕共享功能的功能:

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

反馈

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

请告诉我们设计情况

是否存在区域拍摄功能无法按预期运行的功能?或者是否缺少一些您需要的方法或属性来实现您的想法?对安全模型有疑问或意见?

  • GitHub 代码库上提交规范问题,或将您的想法添加到现有问题中。

实施时遇到了问题?

您是否发现了 Chrome 实现方面的错误?或者,实现方式是否不同于规范?

  • 请访问 https://new.crbug.com 提交 bug。请务必提供尽可能详细的信息,和简单的重现说明。Glitch 非常适合用于快速轻松地重现问题。

显示支持

您是否打算使用区域捕获?您公开提供的支持可帮助 Chrome 团队确定各项功能的优先级,并向其他浏览器供应商说明支持这些功能的重要性。

请向 @ChromiumDev 发送 Twitter 微博,告诉我们您在哪里以及如何使用它。

致谢

感谢 Joe Medley 对本文进行审核。