利用捕获句柄改善标签页共享体验

François Beaufort
François Beaufort

浏览器支持

  • Chrome:102。
  • Edge:102.
  • Firefox:不受支持。
  • Safari:不受支持。

Web 平台现在附带了 Capture Handle,这是一种机制,可帮助捕获应用与被捕获的 Web 应用之间进行协作。借助截取手柄,截取 Web 应用可以以符合人体工学的方式自信地识别被截取的 Web 应用(如果被截取的 Web 应用已选择启用)。

我们通过几个例子来说明这样做的好处。

示例 1:如果视频会议 Web 应用截取的是演示文稿 Web 应用的呈现方式,那么视频会议 Web 应用可以向用户提供在幻灯片之间导航的控件。由于控件直接嵌入在视频会议 Web 应用中,因此用户无需在视频会议标签页和演示标签页之间反复切换。这样一来,用户便可以更加专注地进行演示。

示例 2:当拍摄的 Surface 呈现回被拍摄的位置时,就会出现“镜厅”效果。值得注意的是,如果用户选择截取正在进行视频会议通话的标签页,并且视频会议 Web 应用呈现本地预览,就会出现这种令人恐惧的效果。使用 Capture Handle,可以检测和防范自拍;例如,通过 Web 应用抑制本地预览。

镜厅效果的插图

关于拍摄手柄

捕获手柄由两个互补的部分组成:

  • 被捕获的 Web 应用可以选择使用 navigator.mediaDevices.setCaptureHandleConfig() 向某些来源公开特定信息。
  • 然后,捕获的 Web 应用可以使用 getCaptureHandle()MediaStreamTrack 对象读取该信息。

捕获端

Web 应用可能会向要捕获信息的 Web 应用泄露信息。它通过使用由以下成员组成的可选对象调用 navigator.mediaDevices.setCaptureHandleConfig() 来实现此目的:

  • handle:可以是任何字符串,最多 1024 个字符。
  • exposeOrigin:如果为 true,则被截取的 Web 应用的来源可能会向截取 Web 应用公开。
  • permittedOrigins:有效值包括:(i) 空数组、(ii) 包含单个项 "*" 的数组,或 (iii) 来源数组。如果 permittedOrigins 仅包含单个项 "*",则所有捕获 Web 应用都可以观察到 CaptureHandle。否则,只能捕获来源位于 permittedOrigins 的 Web 应用。

以下示例展示了如何将随机生成的 UUID 作为句柄公开,并向任何捕获的 Web 应用公开源站。

const config = {
  handle: crypto.randomUUID(),
  exposeOrigin: true,
  permittedOrigins: ['*'],
};
navigator.mediaDevices.setCaptureHandleConfig(config);

请注意,被捕获的 Web 应用不知道自己是否正在被捕获。除非捕获网页应用使用 CaptureHandle 信息与被捕获的网页应用建立通信(例如,通过 worker 或共享云基础架构发送消息)。

捕获端

捕获网应用会保留视频 MediaStreamTrack,并且可以通过对该 MediaStreamTrack 调用 getCaptureHandle() 来读取捕获句柄信息。如果没有可用的捕获句柄,或者捕获 Web 应用不允许读取它,此调用会返回 null。如果有捕获句柄,并且捕获的 Web 应用已添加到 permittedOrigins,此调用将返回包含以下成员的对象:

  • handle:被捕获的 Web 应用使用 navigator.mediaDevices.setCaptureHandleConfig() 设置的字符串值。
  • origin:如果 exposeOrigin 设置为 true,则为所捕获 Web 应用的来源。否则,则未定义。

以下示例展示了如何从视频轨读取捕获句柄信息。

// Prompt the user to capture their display (screen, window, tab).
const stream = await navigator.mediaDevices.getDisplayMedia();

// Check if the video track is exposing information.
const [videoTrack] = stream.getVideoTracks();
const captureHandle = videoTrack.getCaptureHandle();
if (captureHandle) {
  // Use captureHandle.origin and captureHandle.handle...
}

通过监听 MediaStreamTrack 对象上的 "capturehandlechange" 事件来监控 CaptureHandle 更改。以下情况会导致发生变化:

  • 捕获的 Web 应用会调用 navigator.mediaDevices.setCaptureHandleConfig()
  • 在捕获的 Web 应用中发生跨文档导航
videoTrack.addEventListener('capturehandlechange', event => {
  captureHandle = event.target.getCaptureHandle();
  // Consume new capture handle...
});

安全和隐私设置

目前,在理论上,捕获的网站应用与捕获的网站应用之间可以协作,例如,在被捕获的网站应用中嵌入“魔法像素”或在视频流中嵌入二维码。捕获句柄提供了一种更简单、更可靠且更安全的机制。它还允许捕获的 Web 应用选择受众群体,即选择来源或整个网络。

请注意,navigator.mediaDevices.setCaptureHandleConfig() 仅适用于安全浏览环境(仅限 HTTPS)中的顶级主框架。

示例

您可以通过在 Glitch 上运行示例来使用捕获手柄。请务必查看源代码

演示

您可以访问以下网址查看一些演示:

功能检测

如需检查是否支持 getCaptureHandle(),请使用以下命令:

if ('getCaptureHandle' in MediaStreamTrack.prototype) {
  // getCaptureHandle() is supported.
}

如需检查是否支持 navigator.mediaDevices.setCaptureHandleConfig(),请使用以下命令:

if ('setCaptureHandleConfig' in navigator.mediaDevices) {
  // navigator.mediaDevices.setCaptureHandleConfig() is supported.
}

后续步骤

下面简要介绍了我们即将推出的一系列功能,它们将改进网页上的屏幕共享体验:

  • 区域截图可用于剪裁从当前标签页的显示屏截图派生的视频轨道。
  • 有条件的焦点可让捕获的 Web 应用指示浏览器将焦点切换到捕获的显示屏表面,或避免进行此类焦点更改。

反馈

Chrome 团队和网络标准社区希望了解您使用“捕获句柄”的体验。

请说明设计

捕获手柄的某些方面是否未按预期运行?或者,您是否缺少实现想法所需的方法或属性?对安全模型有疑问或意见?

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

实现方面存在问题?

您是否发现了 Chrome 实现中的 bug?或者实现与规范不同?

  • 请访问 https://new.crbug.com 提交 bug。请务必提供尽可能详细的信息,并附上简单的重现说明。故障非常适合分享快速简便的重现步骤。

表达支持

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

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

致谢

感谢 Joe Medley 审核本文。