標籤:圖片 細節 推送 fonts javascrip nim com handler jdk1.7
-
- 前言
- 思路如下
- 本機環境
- 介面設計
- 各個模組的設計
- 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實現動態即時視頻彈幕