Web 平台已允许 Web 应用捕获当前标签页的视频轨道。它现在附带区域捕获,这是一种用于剪裁这些视频轨道的机制。Web 应用会将当前标签页的一部分指定为其关注区域,浏览器会裁剪该区域以外的所有像素。
以前,Web 应用可以“手动”剪裁视频轨道。也就是说,Web 应用可以直接操控每一帧。这既不可靠,也不高效。区域捕获解决了这些缺点。现在,Web 应用可以指示浏览器代其执行此操作。
区域捕获简介
您已经创建了一个具有 Dynamic ContentTM 的网站。它是有史以来最好的 Web 应用,人们常常会协作使用它。下一步或许是嵌入虚拟会议功能。你决定就这么干。您需要与现有视频会议服务提供商合作,将他们的 Web 应用作为跨源 iframe 嵌入。视频会议 Web 应用会将当前标签页捕获为视频轨道,并将其传输给远程参与者。
<ph type="x-smartling-placeholder">不会那么快...你现在肯定不想将其他人的视频传输回他们,对吧?最好将那部分裁掉。但是如何做到呢?嵌入的 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 具有一组不同的安全性和隐私权要求。
<ph type="x-smartling-placeholder">安全和隐私设置
通过区域捕获,已观察标签页内所有像素的 Web 应用可以主动移除其中一些像素。这从理论上来说是安全的,因为不会再获得任何新信息。
“区域捕获”可用于限制向远程参与者发送哪些信息。例如,您可能想分享一些幻灯片,但不想分享演讲者备注。
<ph type="x-smartling-placeholder">请注意,“区域捕获”功能在本地不会添加任何安全保证。将轨道移交给另一个文档时,接收文档仍可取消剪裁轨道,并获得对已截取标签页的所有像素的访问权限。
Chrome 会在捕获的标签页的边缘绘制蓝色边框。在剪裁时,Chrome 通常会在剪裁后的目标周围绘制蓝色边框。
演示
您可以通过运行 Glitch 上的演示来体验区域拍摄功能。是 请务必查看源代码。
浏览器支持
浏览器支持
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
只有在桌面设备上通过 Chrome 104 提供区域捕获功能。
后续步骤
下面简要介绍了在未来如何改进网络屏幕共享功能,让您先睹为快:
反馈
Chrome 团队和网络标准社区希望了解您使用 Region Capture 的体验。
向我们介绍设计
“区域捕获”是否有什么无法按预期运行?或者,您是否缺少实现自己的想法所需的方法或属性?对安全模型有疑问或意见?
- 在 GitHub 代码库中提交规范问题,或者添加您对现有问题的看法。
实施时遇到问题?
您在 Chrome 的实现过程中是否发现了错误?或者,实现是否与规范不同?
- 访问 https://new.crbug.com 提交 bug。请务必提供尽可能多的细节,并提供关于重现的简单说明。Glitch 非常适用于分享轻松快速的重现问题。
表示支持
您打算使用 Region Capture 吗?您的公开支持有助于 Chrome 团队确定各项功能的优先级,并向其他浏览器供应商展示支持这些功能的重要性。
请向 @ChromiumDev 发送 tweet 消息,告诉我们您在何处以及如何使用它。
实用链接
致谢
感谢 Joe Medley 审核本文。