背景:
最近开发了一个需求,要求是在进入微信H5页面后,自动开始播放视频,同时视频上有悬浮的跳转页面按钮,等视频播放完后则隐藏视频显示一个结果页。
困难及方案:
需求看起来非常简单,也非常正常,没有任何刁钻的能力要求。但真实现起来坑就多了,主要还是因为微信本身有很多限制。
根据期望的需求点,我们来看看问题都在哪:
1.自动播放
需求期望在进入页面后即自动开始播放视频,我们理所应当的加上了autoplay属性,然而在微信里它的功能更在于增加代码可读性等。不过微信提供了一个WeixinJSBridgeReady事件,在这个事件中我们可以通过JS让其开始播放
document.addEventListener(
'WeixinJSBridgeReady',
function() {
video.play();
},
false
);
然而并没有那么简单,在安卓机中,至少在我的小米8SE中,视频依然不能自动被播放。网上有人说是因为播放的时候视频还没加载,弄个计时器反复抢救就行了,可是我的手机始终处于抢救失败的处境。那么结果是什么呢?我们的视频停留在了未播放的预览状态,中间则是一个播放按钮
这个时候其实有一些解决思路,比如做一张针对这种情况的UI图当预览,诱导用户去点击中间播放等,但不管怎么说,通用性的自动播放已经流产了。所以在妥协后,我们改成了刚进来的时候,全屏显示一个诱导用户点击的图片遮挡视频,点击后显示并开始播放视频,注意不是点击video后播放视频,而是点击任意我们诱导用户点击的东西即可,因为只要存在用户交互,我们就可以在事件中播放
// 点击诱导图开始播放
cover.addEventListener('touchstart', playVideo, true);
但这里需要注意,因为在这个方案中我们采用了先隐藏video,播放时再显示的方案,依然是在安卓环境下,如果有人和我一样发现有时候视频自动黑屏暂停,通过video.currentTime获取的时间卡在0.001,计时器抢救也无效,如果用户不点播放,就会一直卡在这里反射出用户的那张迷茫的大脸
那么大概率是违背了一个原则导致的,即视频在隐藏状态下播放会被停止,比如我们没有放弃WeixinJSBridgeReady的自动播放能力,在视频隐藏阶段依然尝试去播放了一下,或者我们为了让视频第一时间缓存,在刚进入页面就让视频先播放再暂停等,只要是这种在视频隐藏状态下去调用play(),在安卓上就很可能进入这种状态
2.非全屏播放
需求期望的是在指定区域播放视频,这本身并不是什么问题,微信默认行为也是局部播放的,但值得注意的是,安卓微信的局部video播放是采用一个独立的悬浮Native View来实现的,并且这个View本身层级非常高,完全在webview之上,也就意味着我们的代码比如z-index什么的将完全无法对其产生任何影响或覆盖,当然如果你的需求并没有要求在视频上飘着什么的话,对其默认的样式风格也能接受的话,这样也没什么不好。网上传说的播放完后插广告的行为我倒是没有试出来,但因为我们必须要那个悬浮按钮,故而就放弃了安卓的局部播放。
3.视频上悬浮html按钮
局部播放和悬浮按钮在安卓微信上是冲突的,不过网上其实是有一些案例啪啪啪在打我的脸,不过仔细观察会发现,那些打脸的视频地址基本都是腾讯自己的,故而我也选择相信传说中的微信视频白名单,即针对白名单下的视频,安卓微信就不会再对其进行花式魔改,给予其保留质朴功能的慈悲。
如果不说白名单的话,那在安卓环境下,局部播放和悬浮按钮就是两个冲突的要求,必须妥协一个,我们选择了在安卓环境下全屏播放同时悬浮按钮。要开启视频全屏其实非常简单,核心的属性是x5-video-player-type="h5",只要这个属性在就会开启全屏了,不过建议也把x5-video-player-fullscreen="true"加上确保兼容性。注意就算加上这些属性,在iOS下也依然是局部播放的,但因为iOS没被魔改过,故而不用担心那些蛋疼的问题,最多就是两端体验不太一致。
另外退出全屏可以使用一种特定的方式
// 退出全屏
if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
不过全屏也有全屏的问题,在有的机型,全屏后最上层会自动悬浮<(退出)和···(更多)两个图标按钮,这两个按钮可是在视频的区域上的,很可能会和咱们自己的悬浮按钮叠到一块,故而可能需要针对安卓调整悬浮按钮的位置。
另外那三个点的按钮点开后,会有一个分享功能,这个分享不会被KNB.configShare预设,也没有找到可以设置的API,通过它分享出去的链接虽然也能用,但将会非常直接,比如对于我们这个项目来说就是
我们是已经讲过KNB调用微信的接口预设过的,在其他场景下分享也是标准的气泡形式,但在安卓全屏视频右上角那三个点的分享中,就变成了这个样子。已经反馈给KNB的同学了,不过看样子没什么人在乎,目前还没有找到解决方案
4.隐藏控制条
控制条自然是能隐藏就隐藏的,我们理所应当的删掉了controls属性,但事情并没有那么简单。在iOS微信中,不使用该属性是符合预期的,但在安卓中(为什么又是安卓?),将可能会导致视频无法播放的问题,故而我采取的策略是,天然自带controls属性,当判定是iOS后删除该属性。其实还有另一种思路来解决,就是通过制作较长的视频,把控制条放在视野外藏起来,然后不让滚动就好,路子是野了点,但至少也是路子嘛
5.禁用全局滑动
页面本身可以上下滑动也是非常另人不爽的,网上说的禁用方式有很多,但不一定都能奏效,我使用的是
body {
overflow: hidden;
height: 100%;
width: 100%;
position: fixed;
top: 0;
bottom: 0;
user-select: none;
background-color: #FFF;
}
6.视频适配不同手机比例
视频长宽比是固定的,但手机屏幕比例不同,在我们这种全屏视频的情况下这个问题更加明显。我们采用的思路是,视频宽度铺满屏幕宽度,而视频本身是较长(高)的,比如本身适配的是iphoneX的全屏播放高度,但视频下方其实是可以舍弃的部分,没有什么关键内容,就算有字幕等也不会在最底部,而是底部靠中间一点的位置,这个位置的要求是在小手机上依然可以看得到完整字幕
这样做的好处就是较长的手机上尽量不会出现底部留白,而小手机上则不会缺失内容,再配合不允许上下滑动,一般来说就相当于全屏视屏播放了