为了监控移动端视频播放的状况,研究了一下 html5 <video>
标签的属性与事件触发,及其在各系统和各个浏览器的兼容状况javascript
理解清楚属性和事件,才能更好的使用 video ,达到预期的效果,更好的检测视频播放的情况来作出分析和调整,这里仅列举了解到且大体理解的,更多相关后续补充html
<video>
标签嵌入到HTML文档中html5
<video src="" type="video/mp4" autoplay="autoplay" controls="" poster="" preload="none"></video>
初始化 <video>
标签时主要设置的属性java
src:要嵌到页面的视频的URL。可选;你也可使用video块内的 <source>
元素来指定须要嵌到页面的视频android
autoplay:布尔属性;指定后,视频会立刻自动开始播放,不会停下来等着数据载入结束ios
controls:加上这个属性,Gecko 会提供用户控制,容许用户控制视频的播放,包括音量,跨帧,暂停/恢复播放web
poster:一个海报帧的URL,用于在用户播放或者跳帧以前展现。若是属性未指定,那么在第一帧可用以前什么都不会展现;以后第一帧就像海报帧同样展现canvas
preload:该枚举属性旨在告诉浏览器做者认为达到最佳的用户体验的方式是什么。多是下列值之一:api
none:提示做者认为用户不须要查看该视频,服务器也想要最小化访问流量;换句话说就是提示浏览器该视频不须要缓存跨域
metadata:提示尽管做者认为用户不须要查看该视频,不过抓取元数据(好比:长度)仍是很合理的
auto:用户须要这个视频优先加载;换句话说就是提示:若是须要的话,能够下载整个视频,即便用户并不必定会用它
空字符串:也就代指 auto 值
buffered:这个属性能够读取到哪段时间范围内的媒体被缓存了。该属性包含了一个 TimeRanges 对象
played:一个 TimeRanges 对象,指明了视频已经播放的全部范围
loop:布尔属性;指定后,会在视频结尾的地方,自动返回视频开始的地方
muted:布尔属性,指明了视频里的音频的默认设置。设置后,音频会初始化为静音。默认值是 false ,意味着视频播放的时候音频也会播放
height:视频展现区域的高度,单位是 CSS 像素
width:视频显示区域的宽度,单位是 CSS 像素
crossorigin:该枚举属性指明抓取相关图片是否必须用到CORS(跨域资源共享)。 支持CORS的资源 可在 <canvas>
元素中被重用,而不会被污染。容许的值以下:
anonymous:跨域请求会被执行,可是不发送凭证。
use-credentials:跨域请求A cross-origin request会被执行,且凭证会被发送。
TimeRanges 对象表示事件段,好比,视频快进的时间段,有一个 length 属性,表示时间段的个数,有两个方法 start() 和 end() ,分别返回时间段开始的时间点和结束的时间点
事件交互中主要使用的属性
currentTime:播放进行到的时间点,单位为秒
duration:视频总时长,单位为秒
还有更多事件api,这里只列举了试过的
playing:在媒体开始播放时触发(不管是初次播放、在暂停后恢复、或是在结束后从新开始)
ended:播放结束时触发
pause:播放暂停时触发
waiting:在一个待执行的操做(如回放)因等待另外一个操做(如跳跃或下载)被延迟时触发
timeupdate:元素的 currentTime 属性表示的时间已经改变
seeking: 在跳跃操做开始时触发
seeked:在跳跃操做完成时触发
error:在发生错误时触发。元素的 error 属性会包含更多信息
loadeddata: 媒体的第一帧已经加载完毕
播放:start:1(首次播放)2(重播)
播放:end:1
播放暂停:pause:1
播放停止:pause:1
快进/快退:jump:1(快进)2(快退)
错误:fail: 1(取回过程);2( 当下载时发生错误);3( 当解码时发生错误);4( 不支持音频/视频)
播放等待: wait:1
播放时长:totaltime:秒(包含重播)
其中1,2,3,5,6,7都很好监控,对相应事件进行监听就能够了,这里主要讲下是怎么监控播放停止和播放时长的
具体场景是移动端浏览器切换tab致使的隐藏和用户按home键退出浏览器
html5 提供了 Page Visibility API 来支持监听tab切换,与之对应新增了
document.hidden 属性,它显示页面是否为用户当前观看的页面,值为 ture 或 false
document.visibilityState 属性, visible 表示页面被展示, hidden 表示页面未被展示, prerender 表示页面在从新生成,用户不可见
visibilitychange 事件,监听页面在 visible 与 hidden 之间的切换
visibilitychange事件的具体使用
var hidden; var visibilityChange; if (typeof document.hidden !== 'undefined') { hidden = 'hidden'; visibilityChange = 'visibilitychange'; } else if (typeof document.mozHidden !== 'undefined') { hidden = 'mozHidden'; visibilityChange = 'mozvisibilitychange'; } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } document.addEventListener(visibilityChange, function () { if (document[hidden]) { // do something... } }, false);
关于 visibilitychange 事件的兼容性,测试了两部手机,华为mt7 和 iphone6 ,兼容状况以下
华为mt7
qq浏览器:tab切换触发,home键退出触发
uc浏览器:tab切换触发,home键退出触发(退出后进程继续在跑,其它浏览器进程被暂停)
手机百度:tab切换不触发,home键退出不触发
iphone6
uc浏览器:tab切换触发,home键不触发
百度浏览器:同上
手机百度:同上
Safari:tab切换触发,home键退出触发
因为兼容问题,且各系统的各个浏览器基本在tab切换触发,home键退出触发的状况下触发pause事件,因此播放停止的日志依旧打印pause,若是后面没有继续操做则把这个pause日志当作播放停止
页面刷新和浏览器tab被关闭的时候会触发 window.onunload ,也能够作为补充场景
起初的思路是获取到开始播放到中止播放的事件差,记下时间点使用了 currentTime 属性,主要实如今两方面
playing 时记下时间点startT, pause 和 ended 和 seeked 时记下时间点endT,endT - startT 即播放时长
seeked 时记下时间点startT, seeking 时记下时间点endT,endT - startT 即播放时长
这个思路在 ios 下是看似没有问题的,可是 android 下确实不行,主要缘由是 seeking 事件的监听没理解到位,seeking 事件触发点是用户目标跳跃到的位置,好比:视频播放在 0 秒点时,用户点击到了 60 秒点处,这是取到的 currentTime 就是 60 ,原本觉得会是 0 , ios 下看似没有问题是由于它的全屏播放模式下,进度条是要拖拽的,不能直接点击到某个点
因而,使用 timeupdate 来获取 seeking 触发前的时间点,就能够获取到相对准确的播放时长了
ios 下的qq浏览器和uc浏览器里播放 html5 video 会启用浏览器本身的播放窗口,qq浏览器什么事件都监听不到,uc浏览器监听不到 seeking 和 seeked
没有 <source>
元素且 src 元素为空时播放会触发 error 事件,状态码为4
播放播放结束也会触发暂停
播放结束后重播会触发 seeking 和 seeked ,通常浏览器触发一次, android 下uc浏览器触发4次
ios 下uc浏览器和 android 下的一些浏览器不会触发 seeking 和 seeked ,所以须要在 timeupdate 里来分析猜想用户行为
欲先善其事必先利其器,遇到没搞过的技术,必定要先测试一遍 api ,否则太浪费时间,学习内容来源
但愿能多提宝贵建议,帮助笔者继续优化
文章转载自笔者我的博客 Gaoxuefeng's Blog