构建画中画(Picture-in-Picture)效果的悬浮窗视频播放器
主要内容
- 什么是画中画;
- 查看是否支持画中画效果;
- 实现画中画视频效果;
- 画中画事件;
- 获取画中画播放器的宽度和高度;
- 小型项目。
画中画
Picture-in-Picture (PiP)
可以让用户通过悬浮窗口(始终在其他窗口顶部)观看视频,便于用户在浏览其他网站或使用其他应用时继续观看视频。
也就是说,即使用户切换了正在播放视频的标签,仍然能看到视频元素,并且可以在屏幕上随意拖动该视频元素。
查看是否支持画中画
使用 document.pictureInPictureEnabled
布尔值确定是否已启用 PiP
。
let isPiPSupported = 'pictureInPictureEnabled' in document,
isPiPEnabled = document.pictureInPictureEnabled;
if (!isPiPSupported) {
console.log('The Picture-in-Picture Web API is not available.');
}
else if (!isPiPEnabled) {
console.log('The Picture-in-Picture Web API is disabled.');
} else {
console.log("PiP supported");
}
实现画中画视频效果
我们有视频元素和一个按键,用户单击按键,就可以启用悬浮窗视频效果。
<video id="videoElement" controls="true" src="video_url"> </video>
<button id="PiP"> Enable Floating Video </button>
启用 PiP
需要在视频元素上调用 requestPictureInPicture()
,该方法会返回一个 promise
。
解析 promise
后,视频元素会移动到右下角,我们可以将视频元素拖动至任何位置。
另外,我们可以使用 document.pictureInPictureElement
查看是否已有 PiP
视频正在播放,document.pictureInPictureElement
中包含处于 PiP
模式的 video
元素。
<html>
<head>
</head>
<body>
<button id="PiP"> Enable Floating Video </button>
<script>
let video = document.getElementById('videoElement');
let toggleBtn = document.getElementById('PiP');
toggleBtn.addEventListener('click', togglePiPMode);
async function togglePiPMode(event) {
toggleBtn.disabled = true; //disable btn ,so that no multiple request are made
try {
if (video !== document.pictureInPictureElement) {
await video.requestPictureInPicture();
toggleBtn.textContent = "Exit Pip Mode";
}
// If already playing exit mide
else {
await document.exitPictureInPicture();
toggleBtn.textContent = "Enable Pip Mode";
}
} catch (error) {
console.log(error);
} finally {
toggleBtn.disabled = false; //enable toggle at last
}
}
</script>
</body>
</html>
粘贴上述代码可以创建一个基础版 PiP
视频播放器。
画中画事件
PiP
视频状态有下列两个事件:
enterpictureinpicture
→ 启用PiP
模式后触发。- leavepictureinpicture → 退出
PiP
模式时触发,退出原因可能是:
- 视频离开了画中画;
- 用户在其他页面播放了画中画视频。
video.addEventListener('enterpictureinpicture', (event)=> {
toggleBtn.textContent = "Exit Pip Mode";
});
video.addEventListener('leavepictureinpicture', (event) => {
toggleBtn.textContent = " Enter PiP Mode";
});
获取画中画播放器的宽度和高度
用户进入 PiP
模式后,我们就可以得到 PiP
播放器的宽度和高度。
宽度和高度存储在 enterpictureinpicture
事件对象的 pictureInPictureWindow
特性中。
var pipWindow;
video.addEventListener('enterpictureinpicture', function(event) {
pipWindow = event.pictureInPictureWindow;
console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
pipWindow.addEventListener('resize', onPipWindowResize);
});
video.addEventListener('leavepictureinpicture', function(event) {
pipWindow.removeEventListener('resize', onPipWindowResize);
});
function onPipWindowResize(event) {
console.log(`> Window size changed to ${pipWindow.width}x${pipWindow.height}`);
// Change video quality based on Picture-in-Picture window size.
}
两个小项目
下面我们用 PiP
做两个有趣的小项目:
1. 在画中画窗口中显示用户的网络摄像头
我们将使用 navigator
对象的 mediaDevices
特性中的 getUserMedia
方法访问用户的网络摄像头。
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
video.play()
video.requestPictureInPicture();
2. 在画中画窗口中显示用户的显示屏
我们将使用 navigator
对象的 mediaDevices
特性中的 getDisplay
方法访问用户的显示屏。
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({ video: true });
video.play();
video.requestPictureInPicture();
感谢大家的阅读,欢迎在文章下方评论!
请参阅:https://googlechrome.github.io/samples/picture-in-picture/
原文作者:Javascript Jeep
原文链接:https://medium.com/javascript-in-plain-english/implementing-floating-video-player-picture-in-picture-in-javascript-f4b7c540723b