semi-xi / blog

blog
4 stars 1 forks source link

移动端实现自动播放解决思路 #16

Open semi-xi opened 6 years ago

semi-xi commented 6 years ago

移动端自动播放视频

需求:年前的时候,公司需要做一个年会专题,就给到了我这边。看了下原型,首页是需要播放2段视频,而且第2段视频是需要循环播放的。

技术方案选择

因为涉及到视频播放的问题在移动端都会有非常多坑,尤其是还需要做自动播放,所以在开始之前做了个技术调研,找出下面的几个技术方案:

综合考虑之后最后选择了最后一种

双视频加载切换方案

本来的想法就是,直接丢2个video,在两个视频都timeupdate的时候暂停,然后第二个视频用loop的办法去播放

很遗憾的是,在安卓出现部分手机自动全屏的情况,而且loop的时候也会出现一个play的按钮,不符合预期。

img.src 序列帧方案

code

let part2Start = 50;
let part2End   = 100;
let index ++ ;
index > part2End || index = part2Start;
img.src = `${ index }.jpg`

后面发现这种渲染起来白屏太严重了,fail

canvas序列帧方案

code

canvas.drawImage();

fail,理由同上,而且在安卓低端机会卡顿非常严重

合并视频,修改时间轴方案

code

let video = document.querySelector('#video');
video.addEventListener('timeupdate', () => {
    let time = this.currentTime;

    if(currentTime > 10) {
        currentTime  = 5;
    }
})

这里会有2个问题,
一个是视频是没有办法自动播放的,需要用户手动点这个视频才可以触发 一个是视频在安卓上面暂停回去的继续播放的时候会有明显的卡顿,并且会有play按钮

对于第一个问题,其实已经跟交互跟设计都已经沟通过了,可以做一个引导页去解决,但是对于第二个问题,觉得是一个缺陷,最后把这种方案也给排除了。

jsmpeg视频+序列帧方案

js播放mpeg用的是 jsmpeg 这种
这种的话需要自己把视频按照他的命令自己转一次转成*.ts文件,然后直接用new JSMpeg.Player()去播放,播放完成之后再直接走序列帧的流程

ctx.clearRect(0,0,750, 1206)
ctx.drawImage(dataUrl[urlIndex],0, 0,750, 1206);

因为是全屏滚动的,所以这里可以做一个优化是在其他屏的时候暂停这个绘制就可以了,这里就不贴代码了。

还有一个优化点是,你做这个loading的时候,可以先play一下这个视频,能play了之后再pasue,这样就可以知道这个视频以及加载完了 到这里可能会有的问,为什么不选择jsmpeg+jsmpeg去播放两个视频,原因是切换的时候会卡顿

最终成果

线上年会页面