随着2016年macOS Sierra的发布,画中画在Safari浏览器中首次出现在网络上。它使用户可以将视频弹出到一个小的浮动窗口中,该窗口始终位于其他窗口之上,这样他们就可以在做其他事情时继续观看视频。这个想法来自于电视,例如,当你在浏览指南甚至其他频道时,你可能想继续观看热门体育赛事。
不久之后,安卓8.0发布了,它通过本地API提供了对画中画的支持。安卓版的chrome能够通过这个API以画中画的模式播放视频,尽管它的桌面版无法做到这一点。
这导致起草了一个画中画Web API的标准,使得网站有可能发起和控制这种行为。
在写这篇文章的时候,只有Chrome(70+版本)和Edge(76+版本)支持这个新特性。Firefox,Safari和Opera均使用专用的API进行实现。
这份浏览器支持数据来自Caniuse,它包含了更多信息。数字表示浏览器支持这个功能的版本及更高版本。
如何使用Picture-In-Picture API
让我们通过将视频添加到网页开始。
<video controls src="video.mp4"></video>
在Chrome浏览器中,将会存在一个用于进入和退出画中画模式的开关。
要测试Firefox的实现,你需要先在about:config
中启用media.videocontrols.picture-in-picture.enabled
标志,然后右键单击视频以找到画中画选项。
Firefox开启画中画模式视频
虽然这是可行的,但在许多情况下,你希望你的视频控件在各个浏览器中保持一致,并且可能希望控制哪些视频可以输入画中画模式,哪些不能。
我们可以使用我们自己的方法,用picture-in-picture 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,当状态变为resolved后,在默认情况下,会将视频放置在屏幕右下角的迷你窗口中,尽管用户可以移动它。
if ('pictureInPictureEnabled' in document) {
pipButton.classList.remove('hidden')
pipButton.disabled = false;
pipButton.addEventListener('click', () => {
video.requestPictureInPicture();
});
}
我们无法按原样保留上面的代码,因为requestPictureInPicture()
返回一个promise,并且这个promise有可能会拒绝,例如,如果尚未加载视频元数据或视频上存在disablePictureInPicture
属性。
让我们添加一个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应用程序设置为画中画模式可受益于此。
这里有一个demo
在视频中禁用画中画
<video disablePictureInPicture controls src="video.mp4>"></video>
结束
这就是现在你需要了解的关于画中画Web API的所有内容!目前,该API只支持<video>
元素,但它也可以扩展到其他元素。
尽管目前浏览器对它的支持很少,但是你仍然可以使用它来逐步增强网站上的视频体验。
进一步阅读
- Picture-in-Picture API Specification
- Watch video using Picture-in-Picture
- Picture-in-Picture Sample (Google Chrome on GitHub)
原文链接:https://css-tricks.com/an-introduction-to-the-picture-in-picture-web-api/