总结移动端video视频播放的坑(不定时更新) | 您所在的位置:网站首页 › qq音乐怎么全屏播放视频 › 总结移动端video视频播放的坑(不定时更新) |
以下为自己亲身踩过的坑,希望对你有帮助~ 1、x5同层播放器移动端浏览器中的video元素是比较特别的,早期无论是在iOS还是Android的浏览器中,它都位于页面的最顶层,无法被遮盖。后来这个问题在iOS下得到了解决,但是Android的浏览器则问题依旧。X5是腾讯基于Webkit开发的渲染引擎,它提供了一种名叫「同层播放器」的特殊video元素以解决遮盖问题。 只要给普通的video元素加上X5的自定义属性 x5-video-player-type,就可以调用同层播放器。 复制代码同层播放器的视频样式和ios的视频播放器是一样的。安卓的原生播放器(非同层播放器)无法控制是否自动播放、点击播放时是否自动全屏。 如果你需要安卓的视频样式和ios表现为一样,可以使用腾讯的H5同层播放器接入规范。 同层页面内播放是标准的视频播放形态,在video标签中添加x5-video-player-type:h5-page属性来控制网页内部同层播放,可以在视频上方显示html元素。 坑点注意:使用x5的tbs同层播放器,在tbs版本4.5.2以下(这个是经过测试了10几台安卓手机得出来的),视频的右上方会出现一个无法去除的全屏按钮,如图:
必须注意的是,x5下tbs版本在4.5.2以上是不需要做样式适配的,否则会造成视频画面缺失,因此使用前要先做判断: isAndroidX5SupportInlinePlayer() { const ua = window.navigator.userAgent; const tbs = ua.match(/TBS\/([\d.]+)/); const x5 = { tbsWx: ua.match(/MicroMessenger/i) == 'micromessenger' && tbs && tbs[1] >= 36849, // tbsQQ: browser.versions.QQ && isTBS && (isTBS[1]>= 36855) && (isTBS[1] = 7.2, // qq 浏览器 或者 qq 内置 webview tbsX5: tbs && tbs[1] >= 36900 && (isTBS[1] -1 || ua.indexOf('Linux') > -1) && (x5.tbsWx || x5.tbsQQ || x5.MQQBrowser || x5.tbsX5) ); }, 复制代码 2、autoplay自动播放video标签可以设置自动播放,只需在标签设置autoplay即可。但是,设置自动播放是会有兼容性问题的,并不是所有机型都可以。 1.我所遇到的,设置了autoply ios基本可以实现自动播放,但是要设置静音,即:没音频轨道,或者设置了muted属性。 2.安卓的话,只有部分机型可以自动播放。而且不能模拟自动播放,一定要有用户行为才可以触发播放。 微信自动播放微信自动播放实在是太多坑了T_T,具体表现为 1、ios在用户无交互时触发play()方法会报错,导致视频无法加载。 解决方法: document.addEventListener( "WeixinJSBridgeReady", () => { this.video.play(); }, false ); // 兼容微信自动播放 复制代码但是这个方法也有一个问题,关乎于WeixinJSBridge的注入时机,有时候快有时候慢。因此如果项目是像vue这种单页应用,需要额外加载js生成dom元素,才能定义以上方法,会导致定义的WeixinJSBridgeReady不一定每次都可以触发,所以不一定每次自动播放都能成功。 2、安卓里面,如果设置了自动播放,视频会先播放(但是currentTime没有变,视频在加载,因此并没有播放进度),视频加载完会,就会自动暂停。如果封面图是自己实现的,不是使用video的,就会给用户一种不正常的表现(因为用户的体验是,视频并没有进行播放,封面图却消失了)。我的解决方法: 监听视频的pause事件 如果视频的currentTime为false(0或者NaN),是安卓并且是微信,则恢复封面图的显示。 onPause: function() { self.status = "暂停"; self.isPlaying = false; if(!self.currentTime && !util.isIOS() && util.isWeixin()) { // 微信下安卓设置了自动播放,还没播放就会自动暂停,然后封面图就会消失了,会给人一种不正常的感觉, // 因此用这种方法恢复封面图 self.isPlayed = false; }else{ self._fixShowControl(); } }, 复制代码 3、视频行内播放默认情况下,点击video播放会全屏播放,如果想要视频在局部内可以播放的话,可以设置:x5-playsinline 坑点注意:如果想播放时默认全屏播放,在设置了x5-video-player-type=h5这个属性,即使存在x5-video-player-fullscree=true,安卓也是是不能默认全屏播放的。解决方法:在点击播放视频的事件那里添加视频全屏的操作 4、视频全屏播放后的大小这个情况只针对安卓的同层播放器播放时全屏播放的情况。在同层播放器全屏播放后,视频底色会变成黑色,然后视频只是在中间居中,大小是原来视频设置的大小,并不是会全屏铺满。
但是这种方法,由于是整个视频的尺寸直接设置为当前屏幕的宽高,因此测试反映说视频被拉伸变形了,因为尺寸不是按照比例的。 2、因此,采取以下方案。videoHeight()和videoWidth()分别获取原视频的高和宽,然后与屏幕的宽高计算出比例。 if (MJSSDK.UA.android) { this.myPlayer.on('play', () => { // console.log('play'); window.onresize = () => { // console.log('onresize-play'); this.isfull = true; let vheight = this.myPlayer.videoHeight(); let vweight = this.myPlayer.videoWidth(); let clientHeight = document.documentElement.clientHeight; document.querySelector('.video-container').style.width = (clientHeight * vweight) / vheight + 'px'; document.querySelector('.video-container').style.height = clientHeight + 'px'; document.querySelector('#my-video').style.backgroundColor = 'black'; }; }); this.myPlayer.on('pause', () => { // console.log('pause'); window.onresize = () => { // console.log('onresize-pause'); this.isfull = false; // 全屏后,华为等部分机型会有白边,是页面的颜色,用该值控制背景色 document.querySelector('.video-container').style.width = '270px'; document.querySelector('.video-container').style.height = '170px'; }; }); } }, 复制代码 5、视频全屏后出现白边安卓启用同层播放器后全屏出现的,这是个很诡异的问题,仅在部分的安卓机型下出现。如图:
由于视频播放器的控制条是自己实现的,所以需要实现自己全屏方法。 1、原生全屏原生全屏一般会使用这种方法: if (video.requestFullscreen) { video.requestFullscreen(); } else if (video.mozRequestFullScreen) { video.mozRequestFullScreen(); } else if (video.webkitRequestFullscreen) { video.webkitRequestFullscreen(); } else if (video.webkitSupportsFullscreen) { video.webkitEnterFullscreen(); } else if (video.msRequestFullscreen) { video.msRequestFullscreen(); } else { this.addClass(el, "video-player--is-cssfullscreen"); } 复制代码后来看了videojs的源码,发现可以用screenfull.js这个库直接实现全屏,非常方便。 import screenfull from "screenfull"; if (screenfull.isEnabled) { screenfull.request(video); } 复制代码但是,在ios上面调试,发现screenfull.request(video)无法实现全屏,而且也无法监听得到全屏变化事件。只有webkitEnterFullscreen()才可以在ios实现全屏 因此,为了兼容ios: if (util.isIOS()) { document.getElementById(this.vId).webkitEnterFullscreen(); return; } 复制代码 2、伪全屏这里的伪全屏是指通过css实现的样式全屏,可以实现自定义html元素覆盖在视频上。 1、竖版全屏
点击全屏时,先把video元素的最外层父容器旋转90度,并设置为fixed,固定窗口。为了使视频能够居中,left设置为50%,top为当前文档宽度的一半,我这里为-375px。 .cross-screen { position: fixed; top: -375px; left: 50%; background: #000; transform-origin: 0; transform: rotate(90deg) translate3d(0, 0, 0); } 复制代码video的上一层父元素的宽设置为窗口的高,高则设置为当前窗口的宽: this.crossScreenStyle = { width: window.innerHeight + "px", height: window.innerWidth + "px", }; 复制代码 坑点注意:如果同时设置了position:fixed 以及transform属性,可能会导致z-index层级表现异常,层级高的元素被层级低的覆盖了。解决方法:层级高的元素额外添加属性transform: translateZ(100px),把元素提升上来 7、video 标签被浏览器劫持接管现象: 强制出现controls控制条 强制全屏 强制画中画 强制浮动播放器且浮动有bug 等等。。。 这里是指即使使用了x5同层播放器,还是会出现以上现象。 我目前是在vivo的某台手机复现过。 解决方案浏览器厂商添加域名白名单。如 uc ios 白名单的域名有 *.v.qq.com *.taobao.com 8、动态插入video标签的问题为了提升页面渲染性能,会考虑动态插入插入video标签,例如点击了播放才把video标签插入到对应容器里面。 但是,如果启用了x5同层播放器,动态插入的video是会被浏览器劫持的。 解决方案1、可以使用第7点的解决方案 2、判断是x5内核下,则不使用动态插入的方式 |
CopyRight 2018-2019 实验室设备网 版权所有 |