新方法requestPictureInPicture()实现画中画(PIP)
画中画就是使视频脱离页面,在新窗口展示的效果。
现在已经有不少画中画效果的应用,例如淘宝的宝贝介绍、各个播放器和广告等,这些基本都是通过对video标签的操作来实现的,讲道理,用canvas也可以实现。本文要说的是一个新的方法requestPictureInPicture(),直接把你的视频“拖”出来。
demo展示:

运行环境:
chrome浏览器:首先要在chrome://flags/下开启以下功能权限
- Experimental Web Platform features
- Enable Picture-in-Picture
- Enable the use of SurfaceLayer objects for videos
如下图:

然后重启浏览器,打开demo地址可查看。
demo:https://codepen.io/wenjing8/full/pQGmJj
最新版的chrome已经默认支持画中画(版本70以后)
主要代码片段:
html
<video id="videoElement" controls="controls" src="//oxyi0vk1f.bkt.clouddn.com/evn4.mp4" class="videoEle"></video>
<button id="pipButtonElement">进入 Picture-in-Picture</button>
<button id="exitPictureInPicture">退出</button>js
let exitPictureInPicture = document.getElementById("exitPictureInPicture");
let pipButtonElement = document.getElementById("pipButtonElement");
let exitPictureInPicture = document.getElementById("exitPictureInPicture");
// 进入画中画
pipButtonElement.addEventListener('click', async function() { //change、onload、mousedown
pipButtonElement.disabled = true;
try {
await videoElement.requestPictureInPicture();
} catch(error) {
} finally {
pipButtonElement.disabled = false;
}
});
// 退出画中画
exitPictureInPicture.addEventListener('click',()=>{
document.exitPictureInPicture();
})
// 监听画中画
videoElement.addEventListener('enterpictureinpicture', (event) => {
//可获取画中画窗口的一些数据,如宽高等
pipvideoHeight = event.srcElement.videoHeight;
pipvideoWidth = event.srcElement.videoWidth;
console.log("pipvideoHeight:", pipvideoHeight, ",pipvideoWidth:", pipvideoWidth)
});
videoElement.addEventListener('leavepictureinpicture', (event) => {
console.log('退出 Picture-in-Picture');
});方法解析:
1、浏览器需支持requestPictureInPicture()方法才可实现,可以使用document.pictureInPictureEnabled来进行检测浏览器是否支持
2、进入画中画:video.requestPictureInPicture();
3、退出画中画:document . exitPictureInPicture();
4、禁止画中画:在video标签添加disablePictureInPicture;
5、监听画中画的进入和退出状态:enterpictureinpicture、leavepictureinpicture;监听画中画时可获取画中画窗口的一些数据,如宽高等
结论:
1、现有浏览器默认都不支持requestPictureInPicture()方法,暂时不能运用开发新的功能。
2、requestPictureInPicture()目前仅适用于视频元素在画中画窗口,且一个页面只支持出现一个画中画窗口。
3、画中画窗口暂时没有完整的视频控件,只有开始/暂停/关闭三个按钮;画中画窗口始终在屏幕最上层(包括切换页面、应用),且支持拖拽改变位置和尺寸。
4、页面自动执行该方法会被当做恶意行为拦截掉,不出现画中画效果。目前只支持必须是用户手势请求的动作,但是touchstart、touchmove不可以。
- 自执行事件:html触发mouseover、mousemove、mouseout等事件;js触发click、scroll、onload等事件
- 用户手势事件:click、dblclick、mousedown、mouseup(点击弹起时)、change、touchend等事件
5、requestPictureInPicture()与window.open、window.showModalDialog()同是弹出新窗口,但有所不同。
- window.open可通过window.opener与父窗口通信(参考:www.runoob.com/jsref/prop-…
- window.showModalDialog()可传参控制子窗口,子窗口可通过window.returnValue给父窗口返回信息;(参考:blog.csdn.net/u010033129/…
- 画中画子窗口和父窗口无通信API,只能监听是否已进入画中画,且requestPictureInPicture()弹出的窗口无导航条,目前可控性还比较弱。
以上为本人调研的结果,如有什么问题,还请大家多多指教。