临时接手一个即将上线的公司项目,纯H5活动页,内容很少,但对还原度和各机型兼容性(尤为是Android机型)有极高要求。涉及的问题不少,这里重点说下在H5中Video的一系列坑。插个技术选型问题,不复杂的活动页建议使用jquery技术栈,而不是使用vue和reactjs等。后者的优势在于组件系统,可复用度高,适合大型项目。活动页通常UI改动频繁,动效多,适合jquery插件生态,添加也方便。笔者半道接替该vue项目,中间要加一些新特性,还得看看有没有对应的vue轮子,十分麻烦。html
效果请戳:H5 Video(在移动端模式查看)vue
poster:视频未播放前的代替图片,若是未设置该属性,默认使用视频第一帧(但小部分机型兼容性很差)。建议添加react
muted: 静音. 建议添加jquery
webkit-playsinline/playsinline: 视频播放时局域播放,不脱离文档流 。基本保证iphone手机在H5页面内播放。个别不支持能够引入第三方库iphone-inline-video。建议添加android
x5-video-player-type="h5"/x5-playsinline: 启用同层H5播放器,保证anroid手机在H5页面内播放,但在各android机型下表现不一。建议添加ios
<video ref="video" :poster="startSource" muted x-webkit-airplay="allow" x5-video-player-type="h5" x5-playsinline webkit-playsinline playsinline>
<source :src="videoSource" type="video/mp4" />
</video>
复制代码
先说结论:若是须要微信/网易云音乐/微博/QQ/浏览器等各平台完美自动播放,不行。正确的解决方案:让视觉设计引导用户点击屏幕,进行播放视频。或者若是产品能接受,只要用户接触屏幕就开始播放(监听touchstart事件)。错误方式:video标签autoplay 、js执行video.play、load完成后执行play()git
只在微信端传播。微信浏览器是通过特殊处理的,能够经过回调WeixinJSBridgeReady解决,适用于iPhone和android。注意自动播放的视频要无音轨或者手动muted。见示例代码:github
<!-- 必须加在微信api资源 -->
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
let that = this
if (window.WeixinJSBridge) {
WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
video.play()
}, false);
} else {
document.addEventListener("WeixinJSBridgeReady", function () {
WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
video.play()
});
}, false);
}
复制代码
部分android机型点击播放视频时,会出现短暂1~2s的黑屏。该问题出现多是还没请求完成可顺利播放的视频。web
解决方案:在视频上叠加一个div,把它的背景图换成首帧图。监听timeupdate事件,有视频播放时移除该div。api
<div @click="play">
<video ref="video" :class="{'playing': playing}" :poster="startSource" x-webkit-airplay="allow" x5-video-player-type="h5" x5-playsinline webkit-playsinline playsinline>
<source :src="videoSource" type="video/mp4" />
</video>
<div :class="['cover-start']" v-if="!playing"></div>
</div>
复制代码
this.videoNode.addEventListener('timeupdate', () => {
// 当视频的currentTime大于0.1时表示黑屏时间已过,已有视频画面,能够移除浮层
if (this.videoNode.currentTime > 0.1 && !this.playing) {
this.playing = true
}
}, false)
复制代码
有些android在微信或浏览器,播放视频会跳到x5 player播放器中。这种video位于页面最顶层,没法被遮盖,说不定播完会推送腾讯视频信息,并且不会自动关掉。
解决方案:利用timeupdate事件,当视频快要结束时,手动remove掉整个视频。
this.videoNode.addEventListener('timeupdate', () => {
// 兼容Android X5在浏览器行为.时间为视频时长
if (this.videoNode.currentTime > 56.9) {
this.isShowVideo = false
}
}, false)
复制代码
换了引导用户的视频方案后,前面有个loading页面。产品但愿视频加载好后,loading消失并视频可点击。可是ios下canplay和canplaythrough事件都不会执行回调。ios是点击播放后才会去加载视频流。android下会执行canplay事件回调,但视频流也是边下边播。因此没法准确得到视频可加载时间点
总结:H5如今视频标准不完善,除了timeupdate、ended事件外,其余事件慎用。
一般状况在meta的viewport中设置user-scalable=no便可。可是IOS 10之后的safari中,apple为了提升Safari中网站的辅助功能,即便网站在视口中设置该属性,用户也能够手动缩放。
解决方案:
// IOS10 Safari不识别meta,故须要js hack
document.documentElement.addEventListener('touchstart', function (event) {
if (event.touches && event.touches.length > 1) {
event.preventDefault()
}
}, false)
复制代码