最近在开发一个视频类的转发项目,客户端的视频播放并没有太多问题,但是在微信浏览器中,就会产生很多问题。记录一下遇到的问题及解决方案。
先看一下原生的video标签一些属性。
<!-- video --> <script id="template-video" type="text/html"> <video id="video" class="video" webkit-playsinline="true" // 可以让ios视频小窗播放 x-webkit-airplay="true" // 不太清楚这个属性的作用 playsinline="true" // ios在微信浏览器内可以小窗播放 x5-video-player-type="h5-page" // 启用H5播放器 x5-video-player-fullscreen="true" // 禁止横屏 width="94%" // video的宽度 preload="auto" // 是否进行预加载 autoplay="autoplay" // 是否自动播放(在微信浏览器中,设置了也是不可以的) poster="{{imgSrc}}" // 封面图片地址 src="{{src}}" // 视频播放地址 onerror="vc.onVideoError()" // 视频播放错误回调(无论视频在哪个环节出现问题都会触发此函数) > </video> </script>
上面是原生的video常见的一些属性,作用在注释里简单的介绍了一下,想了解更详细的可以去找些文档,网上很多。
下面主要说一下video在微信浏览器的一些怪异行为:
1.项目中想做类似抖音的切换效果,我的想法是video结合slide,但是做起来发现问题很多。首先是如果用这种方案,页面首次加载的时候就要加载所有视频,请求次数太多,会很慢,浪费了用户的流量,导致很差的用户体验。
解决方案:
页面中只存在一个video标签,请求完视频接口后,创建和视频个数相等的silde,当做video的容器,每次切换silde时去切换视频源。video是定位在页面上的,将宽度和高度设置为页面的高度和宽度(width, height都设置为100%,当然,你的视频源尺寸也要合适,不然会变形),将video的z-index设置低一点,后面会在界面上做一些其他操作,而不去直接操作video。
上面的代码我用的是art-template模板去渲染的,是一种模板语言,写一些页面的时候,用起来还是很方便的,有兴趣的可以去看下一下用法,很简单。
2.在微信浏览器中,video不能自动播放,需要用户手动触发一次,才可以自动播放。
这也是我只用了一个video标签的原因,用户在首次进入页面时,可以给用户定位一个按钮,让用户触发一个点击事件,调用video.paly()让视频播放。为了让用户体验更好,我们可以监听视频加载时的一些状态。
在视频加载到视频可以播放:可以在加载视频时给用户展示一个loading效果
$('.loading-box').show(); if (system == 1) { } else { setTimeout(function () { $('.loading-box').hide(); }, 2000) } // loading param.oncanplay = function() { $('.loading-box').hide(); param.play(); }
上面代码中system代表的是客户端的类型,system == 1 代表的是IOS,param代表的是传入的视频对象。ios可以监听到视频的oncanplay方法,但是测试很多次发现,在个方法里ios并不能让loading消失,所以进行了一个处理,让loading效果在两秒后消失。而安卓可以完美的使用。
onended:播放结束回调,在这个函数中可以记录视频播放的次数和置空一些状态,统计用户对哪一个视频更喜欢,用法和oncanplay一样;
ontimeupdate:这个方法里可以做很多事情,是在视频处于播放中调用的。这个函数可以拿到视频的总时长,当前播放时长,可以给视频写一个进度条。因为某些原因,我的这个项目不允许用户拖动视频快进快退,所以加个进度条对用户的体验会好一点。
这里有个坑,安卓在播放之前是拿不到视频总时长的,所以在进行一些判断和操作时,一定要判断视频总时长是否存在,不然会产生一些怪异的数据(切记)。这个方法用处还是比较大的,比如你在特定的时间可以给用户一个弹窗之类的;结合需求可以完成很多操作。
// 视频播放中 param.ontimeupdate = function() { var currentTime = param.currentTime; var duration = param.duration; // 时间在0-50% uv+1 if (currentTime > 1 && vc.uvNew) { vc.uvNew = false; vc.changeVideo.uv += 1; // uvNum+1 vc.sendWs(vc.changeVideo); } // 有效播放次数+1 if (duration && currentTime >= duration * vc.effect && vc.playNew) { vc.playNew = false; vc.changeVideo.play += 1; vc.sendWs(vc.changeVideo); } // 设为播放中 if (duration && currentTime > 0.15) { vc.isPlaying = true; } // 进度条 $('.line').css({ Math.ceil((currentTime / duration) * 100) + '%' }); // 判断用户二维码是否显示 if (duration && currentTime >= duration * vc.effect && vc.codeShow && vc.isCode && vc.codeTrue) { $('.userCode').show(); } };