其他

Android微信视频播放填坑指南

2017-10-27 田翔 网易MC

某日,正在愉快着敲着代码的我,突然发现了一个诡异的现象,在Android微信中,只要视频播放后,不能把普通dom元素(div等)覆盖在video上,就算是z-index为9999999也无法实现,如图:

我只是播放了一下视频,怎么结构样式全部发生了变化,还有我覆盖在视频上的小按钮呢?


●●●


我们知道,Android的微信浏览器,是基于X5内核进行渲染。那么,这样的现象会不会X5的一个bug?经过资料的查询,发现在Android微信中,video标签会自动被X5所劫持,换成原生的播放器去播放,也就是说,我们看到的video其实不在是html5规范里面的那个video了,已经被脱离文档流换成微信的播放器,自然,z-index已经起不到什么作用了,同时播放完成后你甚至可以看到腾讯的广告(是不是有一万只草泥马飘过)。官方的人是这么解释的:

X5内核视频播放使用了自研的播放器,考虑用户体验,我们使用了统一的播放界面。如果有相关问题,请联系腾讯浏览服务产品经理做进一步交流。(就是这么霸气~不要问为什么,因为很cooooooool~~~)

那么有没有什么方法去解决被劫持的问题呢?答案是:有的

方案1

我们发现X5内核加载页面后,会有这么一段JS代码注入到页面中。同时发现这一些网站上的video没有被劫持,拿bilibili为例,发现bilibili的视频上只是加了一个(如下图)但是,对应到我们自己的video加上该属性,没有起到任何作用,也就是说,x5内核存在白名单机制,只要申请了白名单,就可以不被劫持,愉快的使用标准的video标签渲染视频了。

Q: 那么怎么申请白名单呢?

A:官方已经去掉了申请白名单入口,已经没有办法在申请了

Q:既然不能申请白名单,还说什么?浪费时间!

A:这样才能愉快的介绍方案2


方案2

在浏览X5的时候,我们找到了这样一个文档(戳阅读原文可以直接点开):https://x5.tencent.com/tbs/guide/video.html, 同层浏览器,什么意思呢,就是说,如果你在video标签上添加 x5-video-player-type="h5" 和 x5-video-player-fullscreen="true"就可以实现用元素去覆盖video这样一个功能了(初见文档内心还有一点小激动,可用起来,还有很多坑需要去填)

既然官方已经声明了可以用,那么我们就用来试试看,根据官方定义,使用同层浏览器后,就可以将普通元素覆盖到video上,但是,声明同层浏览器,会自动在播放视频的时候,进行全屏,像这样:

按照官方文档所述,只要修改video元素的「object-position」属性,就可以修改视频部分的显示位置,但实际上还要把video元素的宽高设成屏幕的宽高才行:


使用NEJ语法改写如下:

_event._$addEvent(this._videoNode, "x5videoenterfullscreen", this._onx5VideoEnterFullScreen._$bind(this)); _event._$addEvent(this._videoNode, "x5videoexitfullscreen", this._onx5VideoExitFullScreen._$bind(this)); // x5内核浏览器全屏    _pro._onx5VideoEnterFullScreen = function () {        _element._$setStyle(this._videoNode, 'width', window.screen.width + 'px');        _element._$setStyle(this._videoNode, 'height', window.screen.height + 'px');        _element._$addClassName(document.body,'z-x5-video-fullscreen');    }    _pro._onx5VideoExitFullScreen = function () {        _element._$setStyle(this._videoNode, 'width', '');        _element._$setStyle(this._videoNode, 'height', '');        _element._$delClassName(document.body,'z-x5-video-fullscreen');        _element._$delClassName(document.body,'z-x5-video-fullscreen-landscape');    } video{    object-position:center top }


改写后:

使用object-position样式配合全屏video,就可以将显示部分加到任意想要的地方了,然后通过给其他元素设置z-index值大于video的z-index,就可以完成覆盖了

(欢呼,撒花 ╰(°▽°)╯)


你以为文章这么简单就完了吗?


太天真了,产品同学是不会提这么简单的需求的!

产品同学:你的这个不能全屏啊,给加个全屏。

A: 全屏还不容易吗,全屏api就是requestFullScreen嘛,微信里面就是webkitRequestFullScreen

来我们掉用一下,诶?怎么不对劲,用控制台打印微信内容,确实有这个方法,怎么调用无效呢;诶,我先调用api,在去播放视频就可以全屏了;但是我先播放视频在去调用api发现X5是不会理我们的!!这应该是一个X5的bug,同时还发现,使用video原生controls上的全屏按钮而不是api也是可以全屏的!

也就是说,在播放的时候去调用全屏api是无法实现全屏的,那么只能通过其他手段来实现全屏,通过不断的去摸索,发现文档中介绍了x5内核的video会有这样一个属性x5-video-orientation,这个属性用于控制播放器全屏状态下是横屏展示还是竖屏展示,默认是竖屏,那么基于这个属性,可否间接满足全屏条件呢。经过探索在调用全屏api时,设置该属性,可以实时的控制播放器横屏和竖屏,那么实现就简单了。


//判断  if (_mobileUtil._$isWeixin() && _mobileUtil._$isAndroid()) {                var node = document.querySelector('#video');                // 模拟全屏                _element._$attr(node, 'x5-video-orientation', 'landscape');                //添加全屏全局样式                _element._$addClassName(document.body, 'z-x5-video-fullscreen-landscape');                setTimeout(function () {                     //因为横屏宽高发生了变化,所以设置宽高                    node.style.width = window.screen.width + 'px';                    node.style.width = window.screen.height + 'px';                });            } else {                this._rootNode.webkitRequestFullScreen();            }


同理,取消全屏,只需要设置x5-video-orientation的值为portrait即可

if (_mobileUtil._$isWeixin() && _mobileUtil._$isAndroid()) {                var node = document.querySelector('.j-mainVideo video');                node.setAttribute('x5-video-orientation',"portrait");                setTimeout(function () {                    node.style.width =window.screen.width+'px';                    node.style.width =window.screen.height+'px';                }._$bind(this));            } else {                document.webkitCancelFullScreen();            }


同时,点击左上角的按钮会退出视频播放,也应该清除全屏


_pro._onx5VideoExitFullScreen = function () {        _element._$setStyle(this._videoNode, 'width', '');        _element._$setStyle(this._videoNode, 'height', '');        _element._$delClassName(document.body,'z-x5-video-fullscreen');        _element._$delClassName(document.body,'z-x5-video-fullscreen-landscape');  // 退出后需要设置为竖屏全屏,x5内核        _element._$attr(this._videoNode, 'x5-video-orientation', 'portrait');    }

结果


●●●


  1. x5内核接管了video的播放,体验和苹果是不同的,如果能加入白名单最好加入白名单

  2. 默认的x5播放器会播放广告,体验极差

  3. 同级播放器有一定的bug,需要通过一些api手段去规避解决


——【特别推荐】——

歪果仁短视频花式玩法

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存