如何在浏览器实现画中画观看视频

简介: 画中画(PiP)允许用户在浮动窗口中观看视频(总是在其他窗口的顶部),这样他们就可以在与其他站点或应用程序交互时密切关注他们正在观看的内容。

原文作者:Arnaud Lewis

译者:UC 国际研发 桥川


画中画(PiP)允许用户在浮动窗口中观看视频(总是在其他窗口的顶部),这样他们就可以在与其他站点或应用程序交互时密切关注他们正在观看的内容。

使用新的画中画Web API,您可以在网站上启动和控制视频元素的画中画。 如果你还不知道什么是画中画,可以看看上面的视频效果。

背景

2016年9月,macOS Sierra中的Safari支持了Picture-in-Picture API。 六个月后,在Android O上的Chrome通过使用原生Android API,实现在移动设备上播放画中画视频。 六个月后,我们宣布了构建和标准化Web API的意图,该功能与Safari兼容,允许Web开发者创建和控制围绕画中画的完整体验。我们来了!

一起看看代码实现

进入画中画

让我们从video元素及用户与其交互的方式(例如按钮元素)开始。

<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>

仅请求画中画以响应用户手势,并且永远不要videoElement.play()返回的promise中响应。 这是因为promises尚未传播用户手势。而是在
pipButtonElement上的单击处理程序中调用requestPictureInPicture(),如下所示。 如果用户点击两次,您有责任处理会发生的情况。

pipButtonElement.addEventListener('click', async function() {
  pipButtonElement.disabled = true;

  await videoElement.requestPictureInPicture();

  pipButtonElement.disabled = false;
});

当promise resolves,Chrome会将视频缩小为一个小窗口,用户可以在其中移动并定位在其他窗口上。

你完成了。 很好! 你可以停止阅读,享受你当之无愧的假期。可悲的是,情况并非总是如此。 promise可能因以下任何原因而拒绝:

  • 系统不支持画中画。
  • 由于限制性功能策略,不允许文档使用画中画。
  • 视频元数据尚未加载(videoElement.readyState === 0)。
  • 视频文件仅有音频。
  • 新的disablePictureInPicture属性出现在视频元素上。

该调用不是在用户手势事件处理程序中进行的(例如:点击按钮)。

本文后面“特性支持部分”将告诉你如何根据这些限制启用/禁用按钮。

让我们添加一个try...catch块来捕获这些潜在的错误,让用户知道发生了什么。

pipButtonElement.addEventListener('click', async function() {
  pipButtonElement.disabled = true;

  try {
    await videoElement.requestPictureInPicture();
  }
  catch(error) {
    // TODO: Show error message to user.
  }
  finally {
    pipButtonElement.disabled = false;
  }
})

无论是否在画中画中,视频元素的行为都相同:触发事件并调用方法。 它反映了画中画窗口中的状态变化(例如播放,暂停,搜索等),并且还可以在JavaScript中以编程方式更改状态。

退出画中画

现在,让我们让按钮可以切换进入和退出画中画。 我们首先要检查只读对象document.pictureInPictureElement是否是我们的video元素。如果不是,我们发送请求以如上所述输入画中画。否则,我们要求通过调用document.exitPictureInPicture()离开,这意味着视频将显示在原始选项卡中。 请注意,此方法也会返回一个promise。

...
try {
if (videoElement !== document.pictureInPictureElement) {

await videoElement.requestPictureInPicture();

} else {

await document.exitPictureInPicture();

}
}
...

监听Picture-in-Picture事件

操作系统通常将Picture-in-Picture限制在一个窗口,因此Chrome的实现遵循这种模式。这意味着用户一次只能播放一个画中画视频。您应该期望用户即使您没有要求也退出Picture-in-Picture。

新的enterpictureinpicture和leavepictureinpicture事件处理程序让我们为用户量身定制体验。它可以是浏览视频目录,也可以是直播聊天。

videoElement.addEventListener('enterpictureinpicture', function(event) {
  // Video entered Picture-in-Picture.
});

videoElement.addEventListener('leavepictureinpicture', function(event) {
  // Video left Picture-in-Picture.
  // User may have played a Picture-in-Picture video from a different page.
});

获取画中画窗口大小

如果要在视频进入和离开画中画时调整视频质量,则需要知道画中画窗口大小,并在用户手动调整窗口大小时收到通知。

下面的示例显示了如何在创建或调整画板大小时获取画中画窗口的宽度和高度。

let pipWindow;

videoElement.addEventListener('enterpictureinpicture', function(event) {
  pipWindow = event.pictureInPictureWindow;
  console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
  pipWindow.addEventListener('resize', onPipWindowResize);
});

videoElement.addEventListener('leavepictureinpicture', function(event) {
  pipWindow.removeEventListener('resize', onPipWindowResize);
});

function onPipWindowResize(event) {
  console.log(`> Window size changed to ${pipWindow.width}x${pipWindow.height}`);
  // TODO: Change video quality based on Picture-in-Picture window size.
}

我建议不要直接绑定到resize事件,因为对画中画窗口大小进行的每个小改动都会触发一个单独的事件,如果你在每次调整大小时都做了昂贵的操作,可能会导致性能问题。换句话说,调整大小操作将反复触发事件。我建议使用常用技术,如使用throttling(节流阀) 和 debouncing(防抖动)来解决这个问题。

特性支持

可能你的浏览器不支持画中画Web API,因此您必须进行特性检测以提供渐进增强功能。即使支持它,它也可能被用户关闭或被功能策略禁用。幸运的是,您可以使用document.pictureInPictureEnabled来进行检测。

if (!('pictureInPictureEnabled' in document)) {
  console.log('The Picture-in-Picture Web API is not available.');
}
else if (!document.pictureInPictureEnabled) {
  console.log('The Picture-in-Picture Web API is disabled.');
}

应用于视频的特定按钮元素,这是您可能想要处理画中画按钮可见性的方式。

if ('pictureInPictureEnabled' in document) {
  // Set button ability depending on whether Picture-in-Picture can be used.
  setPipButton();
  videoElement.addEventListener('loadedmetadata', setPipButton);
  videoElement.addEventListener('emptied', setPipButton);
} else {
  // Hide button if Picture-in-Picture is not supported.
  pipButtonElement.hidden = true;
}

function setPipButton() {
  pipButtonElement.disabled = (videoElement.readyState === 0) ||
                              !document.pictureInPictureEnabled ||
                              videoElement.disablePictureInPicture;
}

你可以通过以下链接获得Ddemo和代码:
https://googlechrome.github.io/samples/picture-in-picture/

还有哪些新东西?

首先,查看支持状态页面,了解目前在Chrome和其他浏览器中API支持的情况。

以下是您在不久的将来可以看到的内容:

  • Chrome OS和Android O将支持画中画。
  • MediaDevices.getUserMedia()的MediaStreams将与Picture-in-Picture一起使用。
  • Web开发人员将能够添加自定义Picture-in-Picture控件。

英文原文:

https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture

目录
相关文章
|
6月前
|
JavaScript 前端开发 小程序
js 实现浏览器下载视频2种方法
js 实现浏览器下载视频2种方法
921 0
|
Web App开发 移动开发 JavaScript
【前端用法】HTML5 Video标签如何屏蔽右键视频另存为的js代码以及如何禁用浏览器控件,Video 禁止鼠标右键下载
【前端用法】HTML5 Video标签如何屏蔽右键视频另存为的js代码以及如何禁用浏览器控件,Video 禁止鼠标右键下载
345 0
|
Web App开发 编解码 安全
在高版本谷歌Chrome浏览器中用VLC播放海康、大华RTSP实时视频完全方案
随着互联网基础设施的完善以及4G、5G等技术的大规模商用,在Chrome、Firefox、Edge等浏览器播放RTSP视频流也慢慢成为了信息化系统的行业标准。早些年还可用VLC播放器在网页中播放RTSP视频流,好景不长,2015年Chrome、Firefox等浏览器取消了对 NPAPI插件的支持,导致在高版本的Chrome等网页中播放海康威视、大华等摄像头RTSP视频流也成了奢望。
2377 0
|
3月前
|
存储 API 网络架构
【Azure 存储服务】MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以正常播放却无法拖拽视频的进度
【Azure 存储服务】MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以正常播放却无法拖拽视频的进度
|
6月前
|
XML Android开发 数据格式
使用默认闪电浏览器 全屏播放视频时有黑边
使用默认闪电浏览器 全屏播放视频时有黑边
89 5
|
6月前
|
Web App开发
将B站视频设置为浏览器背景,你确定不试试?
将B站视频设置为浏览器背景,你确定不试试?
93 0
|
编解码 Cloud Native 前端开发
H.265 视频在浏览器中的播放问题探究
H.265 视频在浏览器中的播放问题探究
290 0
|
Web App开发 Python Windows
一键下载视频,这个浏览器插件YYDS。
一键下载视频,这个浏览器插件YYDS。
|
移动开发 前端开发 HTML5
web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题
web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题
235 0
web页面实现全背景视频功能方案:使用bideo.js来处理object-fit在ie浏览器下不兼容问题