HTML5弹幕视频播放器

前言

你们年前好,立刻就要元旦了,在好久没有写文章以后,想到这篇文章将会成为本人今年的
绝响也是有点蛋疼。不过也好,毕竟本人算不得什么勤快的生物,并且比起那些大神来讲也差远了,就做为本身工做半年后的一次沉淀算了。css

文中有些思想可能不见得是最好的解决办法,大神们请轻喷。linux

这个项目原本是我本身准备的一个开源插件,但因为上班写这个的过程当中被老板发现了(∑(O_O;)),就说把这个东西写成公司用的吧,而后,而后开源就GG了(我了个大擦,我说我这个是本身的项目也没用),虽说也能够偷偷放出来,但毕竟我还在职,就原谅我此次没办法把代码放出来吧。我会在讲解过程当中尽量讲解详细的。以上。。。。开始一波交♂易吧,骚年们(手动滑稽)android

demo : 我是你亲爱的demo (弹幕数2000)ios

准备

至少须要有canvas和js的编程经验,而后养成一个好的代码习惯(否则一段时间后你都不知道你本身干了什么),下面讲解的内容不会涉及到具体程序和功能的编写,更多地是在强调性能优化这方面,彻底当教程看的能够略过了。。。大神请随意css3

一. 选取合适的方案

其实实现弹幕的方式能够有多种,好比说用dom和canvas实现都是能够的,但咱们这里选取的是canvas来绘制弹幕。chrome

考虑到dom 只适合在单位时间内绘制少许弹幕 ,这对于咱们播放器来讲明显是不合需求的。其实去过B站的都知道,由于播放器有时会出现短期内的“弹幕轰炸”,你想一想若是是用dom来写,页面瞬间建立几百个、甚至上千个element。。。那酸爽,简直让人不敢相信。。。因此说,dom只适用于那些对时间把握要求不那么高的项目,由于你能够经过控制单位时间内弹幕的绘制数量来达到缓解性能的目的。编程

使用canvas好处有几点:
    1.不用频繁的操控dom元素
    2.有强大的api,操做简单
    3.在移动设备上也能比较高性能地运行
    4.强化你的代码组织能力(如何更好地分离功能什么的,而不是加个css3动画就了事)

二. 尽量地多考虑移动设备和PC的差别

其实最简单的就体如今api上,好比说实现全屏模式,其实android和ios到目前为止都仍是不支持元素全屏的,因此说你这里要考虑 requestFullScreen 不能用的状况下,对移动设备的降级处理。还有一点就是移动设备和PC的性能差距仍是有点大的,这就须要你考虑在某些消耗性能的功能和用户体验之间作些取舍。canvas

三. 在特效和性能之间作出平衡

其实这里也是考虑各个主流浏览器的性能差别,对某些功能作出适当的调整。其实在使用canvas text API的时候,有些效果的使用是会大大地加剧浏览器的负担,好比说:文字阴影、渐变、变换等;不见得每一个浏览器都能很迅速的绘制出你想要的效果,即便在你本身看起来不怎么须要时间。 这里,chrome内核的浏览器表现极其优秀,反而让我一脸懵逼的是火狐。。在这我整理了一些主流浏览器在绘制方面的差别(参考数据):api

upperNum : {
        //当弹幕数超过必定数额时,取消文字的全局特效(如阴影等)
        //ps:火狐爸爸不给力啊,向谷歌势力低头
        "firefox" : 500,
        "safari" : 800,
        "chrome" : 2000,
        "ie" : 900,
        "edge" : 1100
    },
    scale : 1,
    rotate : 0

从上面能够看出,其实浏览器性能之间的差别仍是有的,此时就须要咱们根据数据的多少来调整特效的展示,你能够分别用火狐和chrome打开demo页面看效果浏览器

四. 减小api的操做次数(主要部分)

如全局文字颜色等一些能在循环体外设置的api,就千万不要放到循环体内部去给每一个弹幕单独设置(除非全局样式发生了改变)。

还有就是优化循环,没错,就是优化循环。。。。。当你的弹幕池达到数千甚至上万的时候,你一个循环就能浪费掉许多时间,其实有些条件达到的时候你是不必再进行循环了的。对于视频弹幕来讲,咱们须要的只是 “把某一个时间点的全部弹幕进行一次绘制”,这样咱们就已经确立了一部分优化原则:在当前播放时间以前的弹幕我不须要管,在当前播放时间以后的弹幕我不须要管。至于怎么实现,咱们能够改变for循环的start下标来达到忽略前面的弹幕,能够经过判断当前弹幕的时间和播放器时间的大小来达到跳出循环的目的。 在下面的循环体代码(部分)就能够看出来优化的操做

if(!this.Canvas.globalStyleHasChanged)
Canvas.setBaseTextStyle(cxt);    //设置文字基本样式,咱们在这里设置好统同样式

//我这里是弹幕循环
for( var i = DMsystem.idx, DM; DM = DMs[i++]; ){
    if( DM.currentTime > currentTime ){
        break; 
    }
    if( DM.currentTime < currentTime && !DM.isDisplaying ){
        DM.hasShowed = true;
        continue;
    }
    DMsystem.refresh(DM);             //更新位置
    Canvas.drawDM(cxt,DM,options);     //绘制
    DMsystem.recovery(DM,currentTime);          //判断弹幕是否显示完毕并回收相关行
}

五. 避免某些误区

其实在这一版以前我还写过1.0版,不过在移动设备上的性能太糟糕因此舍弃了(大家能够用手机打开这一版demo看看效果,性能其实仍是能够的),缘由是我把每一条弹幕都new了一个实例。。。当时忙着js的伪面向对象编程实践:“弹幕嘛,每一条弹幕都应该是一个成熟的个体,不只有本身独特的颜色,还有所在的位置.....”。而后呢?当我把弹幕数调整为5000的时候---而后就没有而后了。。。。too young too simple,sometimes naive.....浏览器直接炸掉了。。。。。因此说咱们在面向对象的时候要考虑哪些才是真正应该new的。。(尽管看起来好像就我本身有点蠢....)

以上就是要写的全部的东西了,尽管我知道各位看起来可能有点不那么方便(毕竟代码少,并且讲得很笼统),当你本身开始写的时候就会明白项目中大部分东西都很简单(各类api的调用),真正麻烦的仍是性能的优化,以及对设备和浏览器差别的处理。。若是不懂的话欢迎留言询问,我这个还不是最终版,接下来还要加入模式的切换。。。好比说 直播播放器模式(live)和视频播放器模式(player)的优化细节又有点不同,还有高级弹幕的处理(图片,图形等)。。后续有空闲时间可能会继续更新,最后再说一次------------提早祝你们新年快乐

相关文章
相关标签/搜索