videoPictureInPicture,视频画中画播放初探
简介
在触发画中画之后视频会始终在右下角悬浮,不论是否在当前标签页或者是浏览器是否最小化。
可以在chrome内看任意视频时点击控制条的画中画按钮即可。
API
文档:https://w3c.github.io/picture-in-picture/#request-pip
- 开始画中画
videoElement.requestPictureInPicture(); - 退出画中画
document.exitPictureInPicture() - 当前画中画元素
document.pictureInPictureElement 值为null或dom元素
已知问题
我尝试通过 IntersectionObserver
来判断视频是否在视口内来自动进行画中画切换时触发了以下报错。
Failed to execute 'requestPictureInPicture' on 'HTMLVideoElement': Must be handling a user gesture if there isn't already an element in Picture-in-Picture.
研究发现这个行为只能通过用户手动行为触发(例如点击事件就可以正常切换,滚动事件不是可信的用户事件),不能通过其他方式来触发,要实现类似效果还是只能通过改变元素位置来模拟。
Demo
<!DOCTYPE html>
<html lang=""><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>video画中画</title><style>html,body {height: 5000px;}video {width: 500px;}</style>
</head><body><video src="./assets/media/0519-tl-m.mp4" controls></video><br><button>切换画中画</button><script>const video = document.querySelector('video');/* 特征检测 */if ('pictureInPictureEnabled' in document == false) {console.log('当前浏览器不支持视频画中画。');} else {video.oncanplay = ()=> {let observer = new IntersectionObserver((entries) => {var _this = entries[0];if (_this.isIntersecting) {document.pictureInPictureElement && document.exitPictureInPicture()} else {document.pictureInPictureElement !== video && video.requestPictureInPicture();}})observer.observe(video);}document.querySelector('button').onclick = () =>{if(document.pictureInPictureElement !== video){video.requestPictureInPicture();} else {document.exitPictureInPicture()}}video.addEventListener('enterpictureinpicture', function (event) {console.log('> 视频已进入Picture-in-Picture模式');console.log('> 视频窗体尺寸为:' + event.pictureInPictureWindow.width + ' x ' + event.pictureInPictureWindow.height);});// 退出画中画模式时候video.addEventListener('leavepictureinpicture', function (event) {console.log('> 视频已退出Picture-in-Picture模式');});}</script>
</body></html>