video标签在移动端使用过程中问题小结
之前一次项目中用到video,个了这么久才想到记一下坑
- 一些常用且需要重点关注的<video>事件
event | iOS | Android |
---|---|---|
play | 只是要播放视频,响应的是video.play()方法,并不代表已经开始播放 | 和iOS一样,仅是响应video.play()方法 |
durationchange | 会执行一次,一定会获取到视频的duration | 可能会执行多次,只有最后一次才能获取到真实的duration,前面的duration都是0;但低版本Android可能获取到的duration是0或1;(本文提到的低版本Android大部分是4.1以下) |
canplay | 可以认为是视频元素没有问题,可以运行,没有更多含义了,基本用不上 | 同iOS |
canplaythrough | 会有明确的缓冲,表示可以流畅播放了; | 没有什么用,视频仍然会卡住,数据可能还没有开始加载; |
playing | 明确表示播放开始了; | 依然没有用,视频可能并没有开始播放; |
progress | 有明确的下载,可以获取到当前的buffer,并且全部下载完毕后不在触发; | 不一定有明确的数据下载,并且全部下载完毕后依然继续触发; |
timeupdate | 会有明确的进度变化,可以获取到currentTime; | 进度不一定变化,currentTime可能总是0,但是第一次有currentTime变化的timeupdate事件一定代表了视频开始播放了; |
error | iOS中会有明确的错误抛出; | Android中某些浏览器会莫名其妙的抛出error; |
stalled | 网络状况不佳,导致视频下载中断; | 在没有play之前,也可能会抛出该事件。 |
- 属性差异
attributes | IOS | android |
---|---|---|
poster | 支持,但是加载速度明显比在<img>中要慢 | 不一定支持(浏览器厂商的实现标准不统一); |
preload | iPhone不支持 | |
autoplay | iPhone Safari中不支持,但在webview中可能被开启;iOS开发文档明确说明蜂窝网络下不允许autoplay | 可能支持 |
loop | 支持 | 可能支持 |
controls | 支持,但是需要开始播放了才显示 | 基本都支持显示或者不显示 |
width和height | 一定给出明确的属性设置,切不能为0; | 如果不设置,仅仅通过CSS样式去控制视频大小,可能会导致标签失效 |
video标签在移动端使用中遇到的问题
-
autoplay自动播放不生效
在Android下无法通过设置autoplay,在IOS上,除非是无声音,否则无法自动播放,必须通过事件触发 -
poster属性在很多手机浏览器不生效
通常把video隐藏,用一张图片作为封面。最好不要用{display: none}或者{width:0;height:0;}隐藏video,视频元素会处于未激活的状态,给后续的处理带来麻烦。最佳的方式是将视频设置成1×1像素大小。
<video width="1" height="1" controls loop="loop" src=""></video>
- video播放时自动全屏
iPhone、x5内核可以增加playsinline属性,让video内联播放,Android不可以,而且不同浏览器的表现不同
<video class="video-source"
width="100%"
height="240px"
controls /*这个属性规定浏览器为该视频提供播放控件*/
style="object-fit:fill" /*加这个style会让 Android / web 的视频在微信里的视频全屏,如果是在手机上预览,会让视频的封面同视频一样大小*/
webkit-playsinline="true" /*这个属性是ios 10中设置可以让视频在小窗内播放*/
x-webkit-airplay="true" /*支持Airplay的设备(如:音箱、Apple TV)播放*/
playsinline="true" /*IOS微信浏览器支持小窗内播放*/
x5-video-player-type="h5" /*启用H5播放器,是wechat安卓版特性*/
x5-video-orientation="h5" /*播放器支付的方向,landscape横屏,portraint竖屏,默认值为竖屏默认值portraint。无论是直播还是全屏H5一般都是竖屏播放,但是这个属性需要x5-video-player-type开启H5模式*/
x5-video-player-fullscreen="true" /*全屏设置,设置为 true 是防止横屏*/
x5-playsinline
preload="auto"
</video>
x5-video-player-type:启用同层H5播放器,就是在视频全屏的时候,div可以呈现在视频层上,也是WeChat安卓版特有的属性。同层播放别名也叫做沉浸式播放,播放的时候看似全屏,但是已经除去了control和微信的导航栏,只留下"X"和"<"两键。目前的同层播放器只在Android(包括微信)上生效,暂时不支持iOS。笔者想过为什么同层播放只对安卓开放,因为安卓不能像ISO一样局域播放,默认的全屏会使得一些界面操作被阻拦,如果是全屏H5还好,但是做直播的话,诸如弹幕那样的功能就无法实现了,所以这时候同层播放的概念就解决了这个问题。不过笔者在测试的过程中发现,不同版本的ISO和安卓效果略有不同。
webkit-playsinline playsinline:视频播放时局域播放,不脱离文档流 。但是这个属性比较特别, 需要嵌入网页的APP比如WeChat中UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES,才能生效。换句话说,如果APP不设置,你页面中加了这标签也无效,这也就是为什么安卓手机WeChat 播放视频总是全屏,因为APP不支持playsinline,而ISO的WeChat却支持。
- jsmpeg,可以将视频格式转化成ts格式,可以解决自动播放、全频播放的问题,但是IOS自动播放会没有声音
player.audioOut.unlock(function(){
player.volume = 1;
})