总结移动端video视频播放的坑(不定时更新) 您所在的位置:网站首页 qq音乐怎么全屏播放视频 总结移动端video视频播放的坑(不定时更新)

总结移动端video视频播放的坑(不定时更新)

2023-07-21 09:48| 来源: 网络整理| 查看: 265

以下为自己亲身踩过的坑,希望对你有帮助~

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几台安卓手机得出来的),视频的右上方会出现一个无法去除的全屏按钮,如图:

想要去掉这个按钮,要通过css把视频区域挤出屏幕外,在通过object-opsition把视频定位回正常的位置,以下video-player__main__tech为video元素:

&.x5-android { overflow: hidden; & { .video-player__main { padding-left: 200px; width: calc(100% + 200px); .video-player__main__tech { position: absolute; width: calc(100% - 200px) !important; right: 0; object-position: calc(50% - 200px) 50% !important; } } } } 复制代码

必须注意的是,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、视频全屏播放后的大小

这个情况只针对安卓的同层播放器播放时全屏播放的情况。在同层播放器全屏播放后,视频底色会变成黑色,然后视频只是在中间居中,大小是原来视频设置的大小,并不是会全屏铺满。

效果如图。 1、我第一次采用的方案是,当视频全屏时,会触发onresize方法,在该方法里面强制把视频的大小设置为屏幕的宽高:

let video = this.$refs.video; // 以下代码是为了解决安卓播放无办法自动全屏 this.myPlayer.on('play',() => { console.log('play') window.onresize = function () { document.querySelector('.video-container').style.width = window.innerWidth + "px"; document.querySelector('.video-container').style.height = document.documentElement.clientHeight + "px"; } }) this.myPlayer.on('pause',() => { console.log('pause') window.onresize = function () { document.querySelector('.video-container').style.width = "270px"; document.querySelector('.video-container').style.height = "170px"; } }) 复制代码

但是这种方法,由于是整个视频的尺寸直接设置为当前屏幕的宽高,因此测试反映说视频被拉伸变形了,因为尺寸不是按照比例的。

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、视频全屏后出现白边

安卓启用同层播放器后全屏出现的,这是个很诡异的问题,仅在部分的安卓机型下出现。如图:

经过排查,该白边是页面的颜色,就是同层播放器的全屏是把这个页面旋转过来,然后区域放大这样。 解决方法:全屏时把页面背景色设置为黑色,取消全屏时改回来。

6、全屏方法调用问题

由于视频播放器的控制条是自己实现的,所以需要实现自己全屏方法。

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-player--is-cssfullscreen { position: fixed !important; left: 0 !important; top: 0 !important; width: 100% !important; height: 100% !important; z-index: $z-index-video !important; } 复制代码 2、横版全屏

点击全屏时,先把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 实验室设备网 版权所有