为 Web 应用自动进入画中画模式

François Beaufort
François Beaufort

随着 Document Picture-in-Picture API近期推出(甚至在之前),Web 开发者越来越希望能够在用户从当前标签页切换焦点时自动打开画中画窗口。这对于视频会议 Web 应用尤为有用。借助该应用,演示者可以在展示文档或使用其他标签页或窗口时实时查看参与者并与之互动。

当用户切换标签页时,画中画窗口自动打开和关闭。

自动进入画中画模式

为了支持这些视频会议用例,从 Chrome 120 开始,桌面版 Web 应用可以自动进入画中画模式,但为了确保良好的用户体验,我们对此施加了一些限制。Web 应用只有在满足以下所有条件时,才能使用自动画中画功能:

  • 它已为 "enterpictureinpicture" 操作注册了媒体会话操作处理脚本。

  • 系统正在通过 getUserMedia 主动捕获摄像头或麦克风。

  • 用户通过默认启用的浏览器设置允许“自动进入画中画模式”。

Chrome 浏览器网站信息窗格中自动进入画中画模式设置的屏幕截图。
Chrome 浏览器网站信息窗格中的自动画中画设置。

如果某个 Web 应用符合条件,当用户将焦点切换到其他标签页时,系统会触发 "enterpictureinpicture" 操作的媒体会话操作处理脚本回调函数,以便该应用无需用户手势即可打开画中画窗口。

Web 开发者可以使用适用于 <video> 的画中画 API 通过 HTML <video> 元素打开画中画窗口,也可以使用文档画中画 API 打开始终位于顶部的窗口,以填充任意 HTML 内容。画中画窗口在打开时没有聚焦,并且在网页可见性再次变为可见时自动关闭。

以下示例展示了如何请求访问用户的相机。然后,使用用于打开画中画窗口的回调函数,为 "enterpictureinpicture" 操作安全地注册媒体会话操作处理脚本。此窗口包含用户的相机视频流,以及适用于 <video> 的画中画 API。

const video = document.querySelector("video");
// Request access to the user's camera.
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
  video.srcObject = stream;
});

try {
  // Request video to automatically enter picture-in-picture when eligible.
  navigator.mediaSession.setActionHandler("enterpictureinpicture", () => {
    video.requestPictureInPicture();
  });
} catch (error) {
  console.log("The enterpictureinpicture action is not yet supported.");
}

试用视频会议媒体会话示例。

通过浏览器媒体控制进入画中画模式

当用户想要使用 Chrome 浏览器界面中的媒体控件进入画中画模式时,"enterpictureinpicture" 媒体会话操作也非常有用。

Chrome 浏览器中媒体控件的屏幕截图,其中光标位于画中画用户控件上。
Chrome 浏览器中的媒体控件,光标位于画中画用户控件上。

如果没有任何 HTML <video> 元素在播放,而只有音频在播放,为 "enterpictureinpicture" 注册媒体会话操作处理脚本会告知浏览器,该 Web 应用知道如何处理它,并会自行打开画中画窗口。

当 Web 应用想要使用 Document Picture-in-Picture API 打开画中画窗口时,而不是让浏览器使用 <video> 的 Picture-in-Picture API 来处理该窗口时,这也很有用。

以下示例演示了如何为 "enterpictureinpicture" 操作安全地注册媒体会话操作处理脚本。当用户使用 Chrome 浏览器界面中的媒体控件进入画中画模式时,回调函数会使用 Document Picture-in-Picture API 打开画中画窗口。

try {
  // Use the Document Picture-in-Picture API when entering
  // picture-in-picture from browser media control.
  navigator.mediaSession.setActionHandler("enterpictureinpicture", async () => {
    const pipWindow = await documentPictureInPicture.requestWindow();
    // Populate HTML content and handle closing window...
  });
} catch (error) {
  console.log("The enterpictureinpicture action is not yet supported.");
}

试用 Document Picture-in-Picture API VideoJS 播放器演示Video Media Session 示例

互动和分享反馈

如果您有任何反馈或遇到任何问题,可以访问 crbug.com 与我们分享。

资源

致谢

感谢 Tommy Steimel、Ryan Flores、Shimi Rahim、Frank Liberato 和 Rachel Andrew 对他们的评价。