首页 > 代码库 > goeasy+jquery+ckplayer实现动态实时视频弹幕

goeasy+jquery+ckplayer实现动态实时视频弹幕

    • 前言
    • 思路如下
    • 本机环境
    • 界面设计
    • 各个模块的设计
      • ckplayer
      • goeasy实时消息推送功能
        • goeasy接收弹幕消息
        • goeasy发布弹幕消息
      • 弹幕的动画效果
    • 两个ajax请求
      • 第一个是在视频播放之前加载数据库中的所有内容
      • 第二个是在用户发送了弹幕消息时将该弹幕消息写入到数据库
    • 结语

前言

就在前几天,无聊中看了会斗鱼直播,看到他们的弹幕。就忽然有了个想法,我能不能做到呢? 于是趁着周六周日时间多,就做了下。

效果如图所示:
技术分享
也可以进入 http://www.susulovefreedom.cn/danmu.jsp
如果对goeasy和ckplayer不理解的可以进入相应的官网查看教程,挺简单的。

思路如下

  • 由于是实时弹幕,所以需要时时刻刻读取数据库内容,可是大量的ajax请求会影响服务器性能。于是就使用了goeasy第三方实时消息推送框架。
  • 弹幕的动态化可以使用jquery的animate动画来实现.弹幕的位置和颜色,随便一个随机数就搞定啦
  • 至于把弹幕消息发送到数据库就更简单了 ,随便一个请求就可以了
  • 最重要的就是视频插件了,这这里我使用的是ckplayer网页视频播放器,觉得很简单实用。
  • 还有一点就是显示数据库中的弹幕,由于goeasy只能接收实时弹幕,所以需要通过ckplayer来获得当前视频的播放时间。具体实现是,在视频播放之前使用Ajax请求读取数据中的所有弹幕并保存在一个集合里面(按弹幕时间排序),在视频播放时,轮询集合,当前视频播放的时间和弹幕时间对比即可。

本机环境

  • windows7 64位
  • jdk1.7
  • myeclipse10
  • ie浏览器+chrome浏览器

界面设计

记得以前好像看过郭霖大神的android弹幕实例,具体忘记了。就记得在视频上方套一层弹幕的区域。于是设计就出来了

    <!-- 文字区域-->    <div class="screen">         <!-- 播放器 -->        <div id="a1" class="player"></div>        <!-- 这里可以写弹幕输入框-->    </div>

然后就是通过一系列的css操作来布局界面 最终如下:

技术分享

  • 其中弹幕的区域大小和视频的区域大小一致(请忽略现在的视频插件)
  • 下方是弹幕输入区域

各个模块的设计

对于这个是浪费我时间最多的地方,ckplayer是找了好久才找到的一个网络视频插件。
goeasy是实现实时弹幕的第三方实时消息推送框架。

ckplayer

由于是第三方视频插件,具体就不说明了。
需要你知道的就是播放的视频路径,宽度和高度,为播放器绑定事件,我会在下面标注
具体设置可以查看ckplayer.js和ckplayer.xml

    var flashvars={        //视频路径        f:‘http://123.207.172.86/ckplayer/video/jannina weigel.mp4‘,        c:0,        p:1,        //为播放器绑定事件        loaded:‘loadedHandler‘        };    var video=    //视频路径    [‘http://123.207.172.86/ckplayer/video/jannina weigel.mp4->video/mp4‘,‘http://www.ckplayer.com/webm/0.webm->video/webm‘,‘http://www.ckplayer.com/webm/0.ogv->video/ogg‘];    //width和height为播放器的宽度和高度    CKobject.embed(‘ckplayer/ckplayer.swf‘,‘a1‘,‘ckplayer_a1‘,width,height-100,false,flashvars,video)       //HTML5用到    var support=[‘iPad‘,‘iPhone‘,‘ios‘,‘android+false‘,‘msie10+false‘];    CKobject.embedHTML5(‘a1‘,‘ckplayer_a1‘,width,height-100,video,flashvars,support);

在这里我也实现了视频的连播功能

    /*        视频加载事件 至于为什么使用if判断 是为了兼容HTML5        endedHandler:为视频的连播功能,当视频结束时会调用这个事件        timeHandler:监听视频当前的播放时间长度,单位秒。        */        function loadedHandler(){         if(CKobject.getObjectById(‘ckplayer_a1‘).getType()){          CKobject.getObjectById(‘ckplayer_a1‘).addListener(‘ended‘,endedHandler);              CKobject.getObjectById(‘ckplayer_a1‘).addListener(‘time‘,timeHandler);            }            else{              CKobject.getObjectById(‘ckplayer_a1‘).addListener(‘ended‘,‘endedHandler‘);              CKobject.getObjectById(‘ckplayer_a1‘).addListener(‘time‘,‘timeHandler‘);            }        }        //视频连播功能 更换视频的播放地址        function endedHandler(){            if(videoAddress)            {                        CKobject.getObjectById(‘ckplayer_a1‘).newAddress(‘{p->1}{f->http://123.207.172.86/ckplayer/video/dusk.mp4}{html5->http://123.207.172.86/ckplayer/video/dusk.mp4->video/mp4}‘)            }            else            {                CKobject.getObjectById(‘ckplayer_a1‘).newAddress(‘{p->1}{f->http://123.207.172.86/ckplayer/video/jannina weigel.mp4}{html5->http://123.207.172.86/ckplayer/video/jannina weigel.mp4->video/mp4}‘)            }            videoAddress=!videoAddress;        }

由于发送弹幕需要记录当前视频的播放时间,所以还需要记录当前视频的播放时间。

function timeHandler(t){            //time即为当前视频的播放时间            time=t;}

goeasy实时消息推送功能

goeasy接收弹幕消息

当有一个发送消息时,会将这个内容推送给订阅相同频道的其它用户
在js中:

        //new一个实体  其中appkey只能用来接收消息        var goeasy = new GoEasy({            appkey: ‘BS-6cab73eced1440c582eaf081488cf917‘             });        //从goeasy的DanMu频道接收内容        goeasy.subscribe({                  channel: ‘DanMu‘,        onMessage: function (result) {            //将其它客户端发送的消息显示到屏幕            addTxt2Screen(result.content);        }        }); 

goeasy发布弹幕消息

在某个用户的弹幕消息提交到数据库之前,将该消息发布给其它订阅此频道的用户

//your key 填写你注册的goeasy的appkeyGoEasy go=new GoEasy("your key");public void add(){        //使用goeasy第三方推送服务 向相同频道的其它用户推送消息        go.publish("DanMu", txt);        //将弹幕内容和时间保存到数据库        dmDao.add(new DanMu(txt,time));    }

弹幕的动画效果

当有用户发送弹幕时,在弹幕文字区域添加一个font标签即可。
并且使用jquery的animate

//把弹幕文字发射到屏幕中        function addTxt2Screen(txt){            var name="txt"+i;            i++;            $(‘.screen‘).prepend( ‘<font class=‘+name+‘>‘+txt+‘</font>‘);            name=".screen ."+name;            var x = $(name).width();            $(name).css({left:width-x,top:getRandomTop(),color:getRandomColor()});            //jq的animate动画            $(name).animate({                left : -width + x            }, 10000, function() {                //移除该文字                $(this).remove();            });        }

两个ajax请求

第一个是在视频播放之前,加载数据库中的所有内容

这个仅仅加载一次。并将所有的弹幕消息保存到danmuList(按时间从小到大排序)里面。
并且在timeHandler时间里每次都判断当前位置index的弹幕时间和当前视频的播放时间是否一致,如果大于就等待下次~while循环轮询

function timeHandler(t){            time=t;            if(isFirst){                isFirst=false;                //ajax请求获取数据库中所有弹幕                $.ajax({                    url:"DanMu/DanMu_query.action",                    type:"get",                    success:function(data){                        allDanmu=data.split(";");                        for(var i=0;i<allDanmu.length;i++){                            var temp=allDanmu[i].split(",");                            var x=new danmu(temp[0],temp[1]);                            danmuList[i]=x;                         }                        danmuLen=danmuList.length;                    }                });            }            //向弹幕文字区域发送弹幕            while(index<danmuLen){                if(Math.abs(danmuList[index].time-time)<0.3||danmuList[index].time<t){                    addTxt2Screen(danmuList[index].msg);                    index++;                    continue;                }                break;            }        }

第二个是在用户发送了弹幕消息时将该弹幕消息写入到数据库

因为在写入到数据库之前会将该弹幕消息广播给用户,也包括自己,所以在这里不用显示。

//发送弹幕事件            $(‘.textSubmit‘).click(function() {                        var txt = $(‘.inputText‘).val();                $(‘.inputText‘).val("");                /*                 * ajax异步将数据写入数据库                 * 在DanMu_add.action动作类中将弹幕广播发送给其它用户                 * */                 $.ajax({                    url:"DanMu/DanMu_add.action",                    type:"get",                    data:{"txt":txt,"time":time},                    success:function(data){                    }                });            });

结语

主要的功能就这么多,至于细节大家可以去我的github地址查看:https://github.com/scxwhite/java-

一点废话:
以前别人都推荐我使用github 可是全英文我看不懂啊,csdn挺好的,就是上传文件坑人。于是就注册一个github了。(第一次用,也不知道上传的位置对不对,哈哈)
其实我想说 为啥我觉得做着像前端了。。。
520 521 就弄这个女朋友了~

goeasy+jquery+ckplayer实现动态实时视频弹幕