Web 平台已经允许 Web 应用程序捕获当前选项卡的视频轨道。它现在附带 Region Capture,这是一种裁剪这些视频轨道的机制。Web 应用程序将当前选项卡的一部分指定为其感兴趣的区域,并且浏览器会裁剪该区域之外的所有像素。
Web 应用程序以前可以“手动”裁剪视频轨道。也就是说,Web 应用程序可以直接操作每一帧。这既不稳健也不高效。区域捕获解决了这些缺点。Web 应用程序现在可以指示浏览器代表它完成工作。
关于区域捕获
因此,您已经使用 Dynamic Content™ 创建了一个网站。这是有史以来最好的网络应用程序,人们经常合作使用它,无法停止使用它。下一步可能是嵌入虚拟会议功能。你决定这样做。您与现有的视频会议服务提供商合作,将他们的 Web 应用程序嵌入为跨域 iframe。视频会议 Web 应用程序将当前选项卡捕获为视频轨道并将其传输给远程参与者。
没那么快……你不会真的想把人们自己的视频传回给他们吧,是吗?最好把那部分剪掉。但是怎么做?嵌入的 iframe 不知道您公开了哪些内容以及在哪里公开,因此在没有帮助的情况下无法裁剪。理论上,您可以传递预期的坐标。但是如果用户调整窗口大小会发生什么?滚动视口?放大还是缩小?以产生布局更改的方式与页面交互?即使您将新坐标发送到捕获 iframe,时间问题仍可能导致一些错误的帧。
那么让我们使用区域捕获。Element
您的页面上有一个,可能是一个<div>
,其中包含主要内容。让我们称之为mainContentArea
。您希望视频会议 Web 应用程序远程捕获和共享此元素的边界框定义的区域。所以你CropTarget
从mainContentArea
. 您将其传递CropTarget
给视频会议 Web 应用程序。使用 this 裁剪视频轨道后CropTarget
,该轨道上的帧现在仅包含落在边界框内的像素mainContentArea
。如果mainContentArea
大小、形状或位置发生变化,视频轨道会随之发生变化,而无需来自任一 Web 应用程序的任何额外输入。
让我们再次回顾一下这些步骤:
您可以通过使用您选择的元素作为输入CropTarget
调用来在 Web 应用程序中定义 a 。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 应用程序要求浏览器CropTarget
通过调用cropTo()
自捕获视频轨道和从主 Web 应用程序接收到的裁剪目标来将轨道裁剪到由定义的区域。
// 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
。要从中派生 a CropTarget
,请调用CropTarget.fromElement(mainContentArea)
。如果成功,返回的 Promise 将使用新CropTarget
对象解析。否则将被拒绝,如果:
mainContentArea
不支持for 的类型。(在撰写本文时,Chrome 仅实现了对<div>
iframe 的支持。作为一种解决方法,将元素放在 a 中<div>
。在Chrome 105HTMLElement
中,您可以通过启用about:flags/#region-capture-experimental-subtypes
标志来打开对所有 s 的实验性支持。)- 您铸造了数量不合理的
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 将被拒绝。这将在以下情况下发生:
CropTarget
是在另一个标签中铸造的。(现在 - 请继续关注。)CropTarget
是从不再存在的元素派生的。- 轨道有克隆。
- 当前轨道不是自抓视频轨道;见下文。
该cropTo()
方法暴露在任何标签捕获视频轨道上,而不仅仅是用于自我捕获。因此,建议在尝试裁剪轨道之前检查用户是否选择了当前选项卡。这可以使用Capture Handle来完成。也可以要求浏览器使用preferCurrentTab
.
// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);
要恢复到未裁剪状态,请cropTo()
使用调用null
。
// Stop cropping.
await track.cropTo(null);
遮挡和被遮挡的内容
对于区域捕获,只有目标的位置和大小很重要,而不是z-index。将捕获遮挡目标的像素。目标的被遮挡部分将不会被捕获。
这是区域捕获本质上是裁剪的必然结果。一种替代方案,它自己的未来 API,是 Element-level Capture;也就是说,只捕获与目标相关的像素,而不考虑遮挡。这样的 API 具有与简单裁剪不同的一组安全和隐私要求。
安全和隐私
区域捕获允许已经观察标签中所有像素的 Web 应用程序自愿删除其中一些像素。它显然是安全的,因为无法获得新信息。
区域捕获可用于限制发送给远程参与者的信息。例如,也许您想分享一些幻灯片,但不想分享您的演讲者笔记。
请注意,在本地,Region Capture 不会添加任何安全保证。将轨道移交给另一个文档时,接收文档仍然可以取消裁剪轨道并访问所有捕获的选项卡的像素。
Chrome 会在捕获的选项卡边缘绘制蓝色边框。裁剪时,Chrome 一般会在裁剪后的目标周围绘制蓝色边框。
演示
您可以通过在 Glitch 上运行演示来玩 Region Capture 。请务必查看源代码。
浏览器支持
在撰写本文时,Region Capture 在桌面版 Chrome 104 中可用。
下一步是什么
以下是在不久的将来会改进网络屏幕共享的预期内容:
反馈
Chrome 团队和网络标准社区希望了解您对 Region Capture 的体验。
告诉我们设计
Region Capture 是否有一些不符合您预期的地方?还是缺少实现想法所需的方法或属性?对安全模型有疑问或意见?
- 在GitHub 存储库上提交规范问题,或将您的想法添加到现有问题中。
实施有问题?
您是否发现 Chrome 的实现存在错误?还是实现与规范不同?
- 在https://new.crbug.com提交错误。确保包含尽可能多的细节,以及简单的复制说明。Glitch非常适合分享快速和简单的重现。
显示支持
您打算使用区域捕获吗?您的公开支持有助于 Chrome 团队优先考虑功能,并向其他浏览器供应商展示支持它们的重要性。
向@ChromiumDev发送推文,让我们知道您在哪里以及如何使用它。