图片画中画于 2016 年 macOS Sierra 发布时首次出现在 Safari 浏览器中。它使用户能够将视频弹出到一个小的浮动窗口中,该窗口始终位于其他窗口之上,以便他们在执行其他操作时可以继续观看。这个想法来自电视,例如,您可能希望在浏览节目指南或其他频道时继续观看您喜欢的体育赛事。
不久之后,Android 8.0 发布,其中包含通过原生 API 支持的图片画中画功能。Android 版 Chrome 能够通过此 API 以图片画中画模式播放视频,尽管其桌面版本无法做到这一点。
这导致了 标准图片画中画 Web API 的起草,它使网站能够启动和控制此行为。
在撰写本文时,只有 Chrome(70 版及以上)和 Edge(76 版及以上)支持此功能。Firefox、Safari 和 Opera 都使用专有 API 来实现其功能。
此浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器在该版本及更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
70 | 132 | 否 | 79 | 13.1 |
移动/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 否 | 14.0-14.4 |
如何使用图片画中画 API
让我们从在网页中添加视频开始。
<video controls src="video.mp4"></video>
在 Chrome 中,已经有一个切换按钮可以进入和退出图片画中画模式。

要测试 Firefox 的实现,您需要先在 about:config
中启用 media.videocontrols.picture-in-picture.enabled
标志,然后右键单击视频以查找图片画中画选项。

虽然这可以工作,但在许多情况下,您希望您的视频控件在不同浏览器之间保持一致,并且您可能希望控制哪些视频可以进入图片画中画模式,哪些视频不能。
我们可以使用 图片画中画 Web API 将浏览器中进入图片画中画模式的默认方法替换为我们自己的方法。例如,让我们添加一个按钮,当单击时,启用它
<button id="pipButton" class="hidden" disabled>Enter Picture-in-Picture mode</button>
然后在 JavaScript 中选择视频和按钮
const video = document.getElementById('video');
const pipButton = document.getElementById('pipButton');
默认情况下,按钮是隐藏和禁用的,因为我们需要知道在用户的浏览器中是否支持和启用了图片画中画 API,然后再显示它。这是一种渐进增强形式,有助于避免在不支持此功能的浏览器中出现错误体验。
我们可以检查 API 是否受支持并启用按钮,如下所示
if ('pictureInPictureEnabled' in document) {
pipButton.classList.remove('hidden')
pipButton.disabled = false;
}
进入图片画中画模式
假设我们的 JavaScript 确定浏览器启用了图片画中画支持。当单击带有 #pipButton
的按钮时,让我们在视频元素上调用 requestPictureInPicture()
。此方法返回一个 Promise,该 Promise 默认情况下将视频放置在屏幕右下角的一个迷你窗口中,尽管用户可以将其移动到其他位置。
if ('pictureInPictureEnabled' in document) {
pipButton.classList.remove('hidden')
pipButton.disabled = false;
pipButton.addEventListener('click', () => {
video.requestPictureInPicture();
});
}
我们不能照原样保留上面的代码,因为 requestPictureInPicture()
返回一个 Promise,并且如果例如视频元数据尚未加载或视频上存在 disablePictureInPicture
属性,则该 Promise 可能被拒绝。
让我们添加一个 catch
块来捕获此潜在错误并让用户知道发生了什么
pipButton.addEventListener('click', () => {
video
.requestPictureInPicture()
.catch(error => {
// Error handling
});
});
退出图片画中画模式
浏览器会在图片画中画窗口中提供一个关闭按钮,单击该按钮可以关闭窗口。但是,我们也可以提供另一种退出图片画中画模式的方法。例如,我们可以使单击我们的 #pipButton
关闭任何活动的图片画中画窗口。
pipButton.addEventListener('click', () => {
if (document.pictureInPictureElement) {
document
.exitPictureInPicture()
.catch(error => {
// Error handling
})
} else {
// Request Picture-in-Picture
}
});
当视频进入全屏模式时,您可能还需要关闭图片画中画窗口。Chrome 已经自动执行此操作,无需编写任何代码。
图片画中画事件
浏览器允许我们检测视频何时进入或离开图片画中画模式。由于图片画中画模式的进入或退出方式有很多种,因此最好依靠事件检测来更新媒体控件。
这些事件是 enterpictureinpicture
和 leavepictureinpicture
,顾名思义,它们分别在视频进入或退出图片画中画模式时触发。
在我们的示例中,我们需要根据视频当前是否处于图片画中画模式来更新 #pipButton
标签。
以下代码可帮助我们实现此目标
video.addEventListener('enterpictureinpicture', () => {
pipButton.textContent = 'Exit Picture-in-Picture mode';
});
video.addEventListener('leavepictureinpicture', () => {
pipButton.textContent = 'Enter Picture-in-Picture mode';
});
这是一个演示
自定义图片画中画窗口
浏览器默认情况下会在图片画中画窗口中显示播放/暂停按钮,除非视频正在播放 MediaStream 对象(由虚拟视频源(如摄像头、视频录制设备、屏幕共享服务或其他硬件源)生成)。
还可以添加控件,直接从图片画中画窗口转到上一曲目或下一曲目
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Go to previous track
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Go to next track
});
在图片画中画窗口中显示网络摄像头画面
视频会议 Web 应用程序可以在用户在应用程序和其他浏览器选项卡或窗口之间切换时,将网络摄像头画面置于图片画中画模式,从而从中受益。
这是一个示例
禁用视频上的图片画中画
如果您不希望视频在图片画中画窗口中弹出,可以向其添加 disablePictureInPicture
属性,如下所示
<video disablePictureInPicture controls src="video.mp4"></video>
总结
目前,这就是您需要了解的关于图片画中画 Web API 的所有内容!目前,该 API 仅支持 <video>
元素,但它也旨在扩展到其他元素。
尽管目前浏览器支持参差不齐,但您仍然可以将其用作逐步增强网站上视频体验的一种方式。
进一步阅读
- 图片画中画 API 规范
- 使用图片画中画观看视频
- 图片画中画示例(GitHub 上的 Google Chrome)
总结得很好,不过作为最终用户,我真的很讨厌这个功能/设计。即使视频不是广告,用浮动元素遮挡文本也很烦人且分散注意力。
你分享了一篇关于Web API的精彩博文。这篇博文提供了关于API非常有用的信息。API对Android应用程序非常有用。
巧合的是,我今天早些时候刚刚使用过这个API来监控我的远程桌面:https://twitter.com/tomayac/status/1199605948295401472。
在Twitter上无法使用。
画中画歌剧