随着 HTML5 的普及,越来越多视频网站使用 <video></video> 标签播放直播、点播内容(如下图所示)。使用 <video> 的好处,主要以下两点。
- 可以直接在页面中播放,也就是所谓的“区域播放”,上半屏是视频播放,下半屏是其他内容,可以一边播放,一边看其他内容。
- 某些应用如微信朋友圈的 Webview 限制外部打开视频,这样要在微信推广的话,区域播放就迫切需要了。
尽管有以上好处,但是旧有的点解链接调用外部播放器打开视频的功能还是有其价值的,因为:
- HTML5 Video 兼容性问题,对 <video> 不一定完整支持。这时,调用外部播放器作为一种向下兼容(fallback/polyfills)方案出现,在不支持的情况下,提示用户选择。
- 提示使用客户端打开(引导用户使用客户端)。
播放器功能
HTML5 播放器是页面的播放器,通过浏览器提供的接口调用其功能。相当于客户端封装的播放器而言页面播放器的功能不算强大,但基本的播放需求还是可以满足的。
- width/height:高度、宽度,可设置百分比的相对单位进行页面自适应,兼容横、竖屏幕的切换。
- poster:设置视频封面,可设置海报或截图(不过图片尺寸不好控制)。
- autoplay/preload: 如果出现该属性,则视频在就绪后马上播放。对于免费的内容。可以立刻播放。否则用户点击了播放就跳到“订购”。如果自动播放会占用用户的流量 。
- loop: 如果出现该属性,则当媒介文件完成播放后再次开始播放。
- controls:如果出现该属性,则向用户显示控件,比如播放按钮、全屏。如果需要自定义播放器样式,可以设置该属性不去显示默认控件。利用浏览器 JavaScript 接口实现相应的功能。
<video> 元素提供的方法如下(参见W3C School)。
<video> 元素提供的属性如下。
<video> 元素提供的事件如下。
兼容性测试
关于浏览器自带播放器的兼容问题,详细可参见《基于web网页视频播放常见问题》,文中分析主要的原因如下。
为什么有些安卓手机无法播放视频? ……我们知道安卓播放跟厂商支持情况有关,其实前端 JS 这边对 <video> 标签的解析和 H264 的解码做不了什么实质的事情,我们只能尽量使用 HTML5 的 API 接口找到 hack 各种设备的方案,但关键还是看厂商支持情况,所以要在前端实现适配难度很大。
……
安卓由于严重的系统碎片化问题,导致不同的厂商、不同的浏览器对上述两种条件的支持各不相同,所以安卓没法简单的说到底是否支持 HTML5 播放,甚至同一个厂商的不同机型,其特点都不一样,我们遇到过单独支持 flash 的,单独支持 html5 的,或者二者都支持的,甚至还有都不支持的,另外还有明明实际上能使用 HTML5 播放但 API 又返回说不支持播放的。对此我们针对不同的 Android 设备和浏览器做了些矫正和强制判断,许多问题需要 Case by Case 去解决。
当前我们不但希望使用 <video> 播放,而且需要可以半屏内区域播放,最好还是在不修改源情下进行。首先我测试结果如下表。
机型 |
是否支持区域播放 |
直播格式 |
点播格式 |
|||
视频格式 |
rtsp |
m3u8 |
3gp |
mp4 |
|
|
Android
2.2
4
|
No |
Yes |
No |
Yes |
Yes |
|
Android
2.3
5
|
No |
Yes |
No |
Yes |
Yes |
|
Android 4.0 |
Yes |
Yes |
Yes |
Yes |
Yes |
|
Android 4.1 |
Yes |
Yes |
Yes |
Yes |
Yes |
|
Android 4.2 |
Yes |
Yes |
Yes |
Yes |
Yes |
|
Android 4.3 |
Yes |
Yes |
Yes |
Yes |
Yes |
|
Android 4.4 |
Yes |
Yes |
Yes |
Yes |
Yes |
|
iOS 6 |
No |
No |
Yes |
Yes |
Yes |
|
iOS 7 |
No |
No |
Yes |
Yes |
Yes |
|
iOS 8 |
No |
No |
Yes |
Yes |
Yes |
|
No |
No |
No |
Yes |
Yes |
|
|
WP 8.1
8
|
Yes |
No |
No |
Yes |
Yes |
|
这里根据上表,尝试总结如下几个方面。
- 视频格式方面:一般安卓机型都支持 rtsp 格式,而m3u8 的话 Android 3.0 以后都支持。m3u8 是苹果推荐的格式,所以 iOS 都支持。点播的话,mp4 一般都支持(H264压缩算法)。
- 关于区域内播放视频,Android 2.2 不支持, Android 2.3 以后的版本支持。iPad 可以区域播放 iPhone 却不行。iPhone 有一种情况可以区域播放,就是在 Webview 中打开这个特性,仅限应用内的 Webview 使用,——这也就是朋友圈能够区域播放的原因。
- 对于实在不支持 <video> 的浏览器,可以在开始标签和结束标签之间放置文本内容,这样老的浏览器就可以显示出不支持该标签的信息。
一般来讲,Android 版本越高,问题越少。即使浏览器可以使用 <video> 播放,在细节上也会遇到各种问题。下面具体说明。
具体障碍
以上讨论的是浏览器自带浏览器。实际使用过程中,使用国产的第三方 Webkit浏览器可能性会大一些,例如 UC、QQ浏览器等等——因此又可以把兼容性问题划分为自带浏览器的和第三方浏览器的。开发过程中遇到的具体如下。
- 渲染问题,例如 QQ 浏览器,直播播放器播放时滚动会遮盖导航,UC 浏览器 <video>标签总是在前,设置 z-index 无效。
- 华为机器不能播放标清内容(RTSP 流)
- QQ X5 内核浏览器需要直接写 m3u8,不能跳转方式指定。
- 小米1 video 标签失效(Android 4.1 默认浏览器),属于兼容性问题。
- 播放源地址,如果经过 HTTP 302 重定向跳转的话,低于 Android 4.4 的机器可能不能最终获取 m3u8/mp3/3gp 源地址。尤其对于直播的地址,因为需要鉴权、获取手机号码等流程,中间需要经过多次跳转,所以旧版的浏览器就不能播放了1。试比较以下 HTML 代码的写法:
<!-- 通过 jsp 返回 m3u8 地址,这是间接的方式 --> <video src="http://server/getLive.jsp"/> <!-- 直接写出 m3u8 地址 --> <video src="http://server/live.m3u8"/>
对此,我们暂时暴露最终源地址给前端 <video> 标签。不过这样带来潜在的一个问题(见下一点)。
- 因为源地址直接暴露了,所以对防盗链方面来说是有害而无利的。之所以之前的跳转获取源地址相对是安全点的,是因为那获取过程是间接的。——当然无论间接还是直接,终端还是晓得源地址的。
- poster="img.jpg" 设置图片,不能 100% 自适应宽度。进而使用 video.background CSS 属性,但会有播放时背景不会消失的问题(Android 上)
- iOS 7 Safari 不能使用 onclick 登记单击事件; iOS 8 无此问题
- iOS 8 下如果设置播放源 src="" 为空的话,会向用户提示“不可播放”的图标;iOS 7 不会。这个情况是说用户没有权限播放的时候才会设置 src=“”。
- 综上三点问题所述,采用一层 <img /> 遮罩的做法,播放的时候才显示 video 标签。这步需要相关的 JavaScript 的编码。