> 文章列表 > videoPictureInPicture,视频画中画播放初探

videoPictureInPicture,视频画中画播放初探

videoPictureInPicture,视频画中画播放初探

从Chrome 70版本开始video元素开始支持画中画播放,简单写个demo体验一下

简介

在触发画中画之后视频会始终在右下角悬浮,不论是否在当前标签页或者是浏览器是否最小化。
可以在chrome内看任意视频时点击控制条的画中画按钮即可。
videoPictureInPicture,视频画中画播放初探

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('&gt; 视频已进入Picture-in-Picture模式');console.log('&gt; 视频窗体尺寸为:' + event.pictureInPictureWindow.width + ' x ' + event.pictureInPictureWindow.height);});// 退出画中画模式时候video.addEventListener('leavepictureinpicture', function (event) {console.log('&gt; 视频已退出Picture-in-Picture模式');});}</script>
</body></html>