Web 平台已允许 Web 应用捕获当前标签页的视频轨道。它现在附带了 Region Capture,这是一种用于剪裁这些视频轨道的机制。Web 应用将当前标签页的一部分指定为其感兴趣的区域,而浏览器会裁剪该区域以外的所有像素。
以前,Web 应用可以“手动”剪裁视频轨道。也就是说,Web 应用可以直接操控每一帧。这种方法既不可靠,也不性能。“区域拍摄”功能解决了这些缺点。Web 应用现在可以指示浏览器代表浏览器执行相关工作。
关于区域捕获
您已使用 Dynamic ContentTM 创建了一个网站。它是有史以来最好的 Web 应用,经常需要用户协作才能使用它。下一步可以采取的是嵌入虚拟会议功能。你决定去做这件事。您与某个现有视频会议服务提供商合作,将他们的 Web 应用嵌入为跨源 iframe。视频会议 Web 应用会捕获当前标签页作为视频轨道,并将其传输给远程参与者。
不是快得... 您其实并不希望将人们自己的视频传送回他们,是吧?最好剪掉这部分。但如何实现?嵌入式 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 具有一组不同的安全和隐私要求。
安全和隐私设置
区域捕获允许已经观察标签页中所有像素的 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 对本文进行审核。