从Chrome 70版本开始video元素开始支持画中画播放,简单写个demo体验一下
简介
在触发画中画之后视频会始终在右下角悬浮,不论是否在当前标签页或者是浏览器是否最小化。
可以在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>