想边刷微博边追剧?想边聊微信边看球赛?从浏览器支持扩展功能开始,人们就一直有这样的需求:

Chrome看视频,有没有可以弹出视频窗口的插件?

各个国产壳子浏览器也争相内置“视频弹窗播放”的功能,比如当年的火狐中国版:

这么多年过去了,正统浏览器们终于要内置这个功能了,而且还有配套的 API 给开发者使用。

WICG,全名为 Web Incubator Community Group(Web 孵化器社区小组),主要成员为 Chrome 的工程师们,他们从一年前开始标准化这个能让视频弹窗播放的特性,起名为 Picture-in-Picture(画中画),缩写为 PiP。

Chrome 从今年年初开始着手实现,到本文撰稿时,已经实现的差不多了。这篇文章将主要讲两方面:Chrome 当前实现的 PiP 交互是怎么样的,以及有哪些 API 让我们开发者使用。

Chrome 中的 PiP 交互

Chrome 官方提供了一个 demo 页面 Picture-in-Picture Sample,我用这个 demo 录了一个简单的演示视频:

从视频中可以看到,Chrome 在原生的 video 控件中提供了开启画中画模式的菜单项,一旦开启画中画模式,原本页面中内联(inline)展现的那个 video 还占据着原来的位置,各种控件也都在,但最重要的视频画面已经被无缝的转移到了新的弹出窗口中了,只剩下一张 poster 图片和一层灰色的遮罩。

我们把弹出的那个视频窗口叫做 PiP 窗口,PiP 窗口只有视频画面,没有标题栏和地址栏(chrome-less),这一点和用 window.open()打开的弹窗不一样。同时,PiP 窗口也没有完整的视频控件,只有开始/暂停/关闭按钮三个,时间、进度条、音量这些控件都没有。PiP 窗口还支持拖拽改变大小(不能大于一个象限),以及支持拖拽到任意位置(录屏里没有体现,因为在本文撰写时还不支持)。还有最重要的一点是,PiP 窗口在所有窗口中是置顶的(always on top),正如我在录屏里演示的,当焦点切换到 Safari 后,Chrome 中打开的 PiP 窗口仍然是在最上层的。

另外一个没有在录屏里体现出来的交互是,“同一时刻只能有一个 PiP 窗口”。同一个页面里如果为多个视频开启画中画模式,前面开启的那个会自动退出画中画模式,同一个浏览器窗口下的多个 Tab 里的视频亦如此,同一个浏览器打开的多个浏览器窗口亦如此(在本文撰稿时,Chrome 还没有实现最后一种情况,即多个浏览器窗口可以同时开启多个 PiP 窗口,已确认是 bug 不是 feature)。

PiP 相关 API

1. video 元素新增的方法 requestPictureInPicture()

请求让该 video 元素进入画中画模式,返回一个 promise,如果没有异常,这个 promise 包的值会是一个 PictureInPictureWindow对象,这个对象就代表弹出的那个 PiP 窗口,后面会单独讲它的 API。

async function openPiP(video) {try {const pipWindow = await video.requestPictureInPicture() // 进入画中画模式...} catch (e) {console.error(e) // 处理异常}
})

哪些情况下进入画中画模式会失败?一共有 5 种情况:

  1. 操作系统不支持、或者用户通过浏览器选项禁用了此功能,此时 document.pictureInPictureEnabled 属性会返回 false
  2. 视频文件错误、或者没有视频流只有音频流
  3. 此次请求不是由用户操作触发的,比如用户没有点击任何按钮,页面自动执行该方法,会被当做恶意行为拦截掉
  4. 当前页面通过 feature-policy 禁用了画中画特性,此时 document.pictureInPictureEnabled属性也会返回 false
  5. 当前 video 元素通过 disablePictureInPicture 属性(HTML 属性和 DOM 属性均可)禁用了画中画特性

2. video 元素新增的属性 disablePictureInPicture

通过该属性可以禁用 video 元素的画中画特性,右键菜单中的“画中画”选项会被禁用。

通过 HTML 属性:

<video src="..." disablePictureInPicture>

通过 DOM 属性:

video.disablePictureInPicture = true

3. video 元素新增的事件 enterpictureinpicture 和 leavepictureinpicture

video.addEventListener('enterpictureinpicture', function(pipWindow) {// 进入了画中画模式,可以拿到 pipWindow 对象
})video.addEventListener('leavepictureinpicture', function() {// 退出了画中画模式
})

4. document 上新增的方法 exitPictureInPicture()

因为一个页面只能打开一个 PiP 窗口,所以让 video 元素退出画中画模式的方法不在 video 元素自己身上,而在 document 上。

这个方法也返回一个 promise,不过 promise 包的值是个 undefined

5. document 上新增的属性 pictureInPictureElement和 pictureInPictureEnabled

类似于document.pointerLockElement和 document.fullscreenElement, document.pictureInPictureElement 会返回当前页面中处于画中画模式的 video 元素,如果没有的话,返回 null

document.pictureInPictureEnabled上面已经提到过了,在当前页面不支持或被禁用画中画模式的情况下会返回 false,否则返回 true

这两个属性都是只读的。

6. PictureInPictureWindow对象的 API

requestPictureInPicture()方法的返回值和 enterpictureinpicture事件的回调参数中可以拿到 pipWindow 对象,该对象有两个属性 widthheight,还支持一个resize事件,在用户改变 PiP 窗口大小时会触发。

async function openPiP(video) {const pipWindow = await video.requestPictureInPicture()console.log(pipWindow.width, pipWindow.height) // 打印了默认的窗口大小pipWindow.addEventListener('resize', function() {console.log(pipWindow.width, pipWindow.height) // 用户改变 PiP 窗口大小时触发})
}

注意这里的 widthheight是只读的,你不能通过给他们赋值来改变窗口大小。

杂项

1. Safari 中已有的画中画 API

Safari 在两年前就支持了画中画模式,还有一套带前缀的配套 API,叫 Presentation Mode。好消息是这个新规范也有 Safari 的人参与了制定,事实上目前为止四大浏览器厂商只剩 Edge 还没表示支持。

2. 画中画这个名字的由来

“画中画”这东西是十几年前电视机上的一个功能,我自己去年看到这个规范的时候也觉的它这个名字比较误导人,现在规范 issue 里也有个人在问,希望你没把它理解成是嵌套的 <img>

3. Chrome 哪个版本支持

现在的 Chrome Canary(69)还没有默认打开这个特性,需要你手动开启

chrome://flags/#enable-experimental-web-platform-features

chrome://flags/#disable-background-video-track

chrome://flags/#enable-picture-in-picture

这三个开关,不用 Canary 的同学老实等两个月。

4. 可不可能弹出 video 以外的元素

规范制定者表示未来有可能

原文发布时间为:2018年06月21日
原文作者:掘金

本文来源: 掘金 如需转载请联系原作者

浏览器中的画中画(Picture-in-Picture)模式及其 API相关推荐

  1. 360浏览器中页面打开如何默认极速模式

    在header中添加以下代码 //默认极速模式 //默认标准模式 http://se.360.cn/v6/help/meta.html 浏览器内核控制标签meta说明

  2. 现代浏览器中的隐私浏览是否真的安全?

    摘要 网络浏览器是通过互联网执行各种活动的最常用工具.除了普通浏览模式,几乎所有现代浏览器都有隐私浏览模式,具体名称因浏览器而异,但隐私模式的目的在每个浏览器中都是类似的.在正常浏览模式下,浏览器会跟 ...

  3. 《JavaScript权威指南第7版》第15章 Web浏览器中的JavaScript 15.1 15.2 15.3

    第15章 Web浏览器中的JavaScript 15.1 网络编程基础 15.1.1 HTML script 标签中的JavaScript 模块 指定脚本类型 脚本运行时:异步和延迟 按需加载脚本 1 ...

  4. iOS画中画Picture in Picture:你需要知道的9个知识点

    iOS9最后给我们带来了每个人期待已久的"多任务",Slider Over.Split View 和画中画(PiP),已经使iPad成为一个比之前更强大.更便利的工具.使你在工作中 ...

  5. 微软新版edge浏览器如何开启画中画模式 (微软新版edge)

    方法一 打开edge,地址栏输入edge://flags并回车,搜索标签Global,然后将全局媒体控制和画中画设置为Enabled,最后重启即可 方法二 添加扩展搜索Picture in Pictu ...

  6. iOS9 画中画 Picture in Picture

    画中画 (Picture in Picture) iOS9系统在iPad上支持多任务分屏和画中画视频播放,画中画视频播放就将视频播放窗口化,然后浮动在屏幕上,此时你可以使用其他APP.但是有限制:1. ...

  7. ajax请求在ie和360兼容模式浏览器中数据不能正常返回

    ajax get请求在ie和360兼容模式浏览器中数据不能正常返回,但debugger后数据在ie和360兼容模式浏览器可以正常返回的. 在网上查了一下资料. 以下是资料内容: 在使用jQuery的A ...

  8. 在Edge浏览器中启用Internet Explorer 模式

    目录 启用IE浏览器 启用Microsoft Edge的Internet Explorer 模式 如何在Edge浏览器打开不适合Edge的网站?这是可以打开lnternet Explorer 模式试一 ...

  9. 在浏览器中直接访问linux服务器中的文件(以图片为例)

    首先必须在服务器中配置tomcat,当在浏览器中输入http://服务器的公网IP:8080/时,能出现tomcat服务器首页时,则配置成功,如下图: 2. 找到tomcat的安装目录中conf文件并 ...

最新文章

  1. 安川g7接线端子图_常用变频器接线端子集锦及接线示意图
  2. influxdb查看数据库命令_influxdb基本命令
  3. WebView实例开发之人人网Oauth2认证
  4. Python程序开发——第七章 模块与包
  5. redis查询key的数量
  6. iphone输入法换行_【每日一技】iPhone输入法不能换行的痛点,用这招0.5秒解决
  7. dojo mobile问题汇总
  8. 最好用的OCR实时翻译工具:Bob for Mac
  9. 小孩终生教育工程(人生管理):有些东西比努力比钱更重要
  10. 群英传内推第001期
  11. 有什么好的降噪蓝牙耳机推荐,公认好用的降噪蓝牙耳机分享
  12. 在线教育巨头多邻国Duolingo入华一周年,中国市场马力全开
  13. IOS APP开发:苹果app从开发到上架教程详解
  14. 5G学习笔记之F1AP
  15. IMEISV码转换成IMEI码
  16. c# 文章分享微信朋友圈自定义标题、摘要、缩略图
  17. 小米6发布会测试手机网速的软件,原来小米6上这个功能真的可以提升网速,你的行吗...
  18. Eclipse使用SVN进行代码提交的步骤
  19. 达梦数据库集群主备节点切换
  20. 一个程序员的诗集【现代诗篇】

热门文章

  1. 2020年10月25日总结
  2. Linux查找文本中的重复项,2在Linux中查找和删除重复文件的有用工具
  3. EPS HSS、HLR、IMS HSS有什么区别?分别用于什么场景
  4. oracle问题诊断,Oracle之常见问题诊断方法
  5. CAD中插入外部参照字体会变繁体_为什么CAD插入相同图框但尺寸却相差很多?
  6. 推荐 macwk 的替代品: minorpatch.com
  7. 【pandas数据分析】pandas概述
  8. Installation of Theano on Windows
  9. DTC(Deep Temporal Clustering--Fully Unsupervised Learning of Time-Domain Features)论文理解
  10. Linux内核之PCI设备