在WebSocket API中,瀏覽器和服務(wù)器只需要做一個(gè)握手動(dòng)作,然后,瀏覽器和服務(wù)器之間就形成一條快速通道,兩者之間就可以直接進(jìn)行數(shù)據(jù)傳送,這一個(gè)功能可以應(yīng)用到“字幕”,自己做了一個(gè)demo,廢話不說了,直接貼代碼:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>彈幕</title> 6 </head> 7 <script type="text/javascript" src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script> 8 <style type="text/css"> 9 #Barrage{ 10 width:800px; 11 height:400px; 12 margin:0 auto; 13 border:1px solid #000; 14 } 15 #Video1{ 16 box-shadow: 10px 5px 5px black; 17 display: block; 18 } 19 </style> 20 <script type="text/javascript"> 21 22 function vidplay() { 23 var video = document.getElementById("Video1"); 24 var button = document.getElementById("play"); 25 if (video.paused) { 26 video.play(); 27 button.innerHTML = "||"; 28 } else { 29 video.pause(); 30 button.innerHTML = ">"; 31 } 32 } 33 34 function restart() { 35 var video = document.getElementById("Video1"); 36 video.currentTime = 0; 37 } 38 39 function skip(value) { 40 var video = document.getElementById("Video1"); 41 video.currentTime += value; 42 } 43 44 function makeBig(){ 45 var video = document.getElementById("Video1"); 46 video.width = 600; 47 } 48 </script> 49 50 <body> 51 <p id="Barrage"> 52 <video id="Video1" autoplay loop> 53 <source src="http://www.runoob.com/try/demo_source/mov_bbb.mp4" type="video/mp4"> 54 <source src="http://www.runoob.com/try/demo_source/mov_bbb.ogg" type="video/ogg"> 55 </video> 56 <p id="buttonbar" style="margin-left: 50px;margin-top: 20px"> 57 <button id="restart" onclick="restart();">重播</button> 58 <button id="rew" onclick="skip(-3)"><<</button> 59 <button id="play" onclick="vidplay()">暫停</button> 60 <button id="fastFwd" onclick="skip(3)">>></button> 61 <button onclick="makeBig()">放大</button> 62 </p> 63 </p> 64 </body> 65 <script type="text/javascript"> 66 var that = this; 67 //舞臺(tái)是全局變量 68 var stage = $('#Barrage'); 69 //彈幕的總時(shí)間,這個(gè)是值得思考的問題,根據(jù)業(yè)務(wù)而已,這個(gè)不應(yīng)該是一開始寫死,因?yàn)槭莿?dòng)態(tài)的彈幕,不過這里是為了測(cè)試方便,后面會(huì)修改 70 var totalTime = 9000; 71 //檢測(cè)時(shí)間間隔 72 var checkTime = 1000; 73 //總飛幕數(shù) 74 var playCount = Math.ceil(totalTime / checkTime); 75 76 var messages=[{ 77 //從何時(shí)開始 78 time:0, 79 //經(jīng)過的時(shí)間 80 duration:4292, 81 //舞臺(tái)偏移的高度 82 top:10, 83 //彈幕文字大小 84 size:16, 85 //彈幕顏色 86 color:'#000', 87 //內(nèi)容 88 text:'前方高能注意' 89 },{ 90 //從何時(shí)開始 91 time:100, 92 //經(jīng)過的時(shí)間 93 duration:6192, 94 //舞臺(tái)偏移的高度 95 top:100, 96 //彈幕文字大小 97 size:14, 98 //彈幕顏色 99 color:'green', 100 //內(nèi)容 101 text:'我準(zhǔn)備追上前面那條', 102 },{ 103 //從何時(shí)開始 104 time:130, 105 //經(jīng)過的時(shí)間 106 duration:4192, 107 //舞臺(tái)偏移的高度 108 top:90, 109 //彈幕文字大小 110 size:16, 111 //彈幕顏色 112 color:'red', 113 //內(nèi)容 114 text:'遮住遮住遮住。。', 115 },{ 116 //從何時(shí)開始 117 time:1000, 118 //經(jīng)過的時(shí)間 119 duration:6992, 120 //舞臺(tái)偏移的高度 121 top:67, 122 //彈幕文字大小 123 size:20, 124 //彈幕顏色 125 color:'blue', 126 //內(nèi)容 127 text:'臨水照影Testing....~~', 128 }]; 129 130 //構(gòu)造一個(gè)單獨(dú)的彈幕 131 var BarrageItem = function(config){ 132 //保存配置 133 this.config = config; 134 //設(shè)置樣式,這里的樣式指的是一個(gè)容器,它指包含了單個(gè)彈幕的基礎(chǔ)樣式配置的p 135 this.outward = this.mySelf(); 136 //準(zhǔn)備彈出去,先隱藏再加入到舞臺(tái),后面正式獲取配置參數(shù)時(shí)會(huì)把一些樣式修改。 137 this.outward.hide().appendTo(stage); 138 } 139 140 //單個(gè)彈幕樣式,從config中提取配置 141 BarrageItem.prototype.mySelf = function(){ 142 //把配置中的樣式寫入 143 var outward = $('<p style="min-width:400px;font-size:'+this.config.size +'px;color:'+this.config.color+';">'+this.config.text+'</p>'); 144 return outward; 145 } 146 147 //定義彈的過程,這是彈幕的核心,而且一些高級(jí)擴(kuò)展也是在這里添加 148 149 BarrageItem.prototype.move = function(){ 150 var that = this; 151 var outward = that.outward; 152 var myWidth = outward.width(); 153 //用jq自帶animate來讓它運(yùn)動(dòng) 154 outward.animate({ 155 left: -myWidth 156 },that.config.duration,'swing',function(){ 157 outward.hide(); //彈完我就藏起來 158 }); 159 } 160 161 //開始彈彈彈 162 163 BarrageItem.prototype.start = function(){ 164 var that = this; 165 var outward = that.outward; //這里引用的還是原型中的那個(gè)outward 166 //開始之前先隱藏自己 167 outward.css({ 168 position: 'absolute', 169 left: stage.width() + 'px', //隱藏在右側(cè) 170 top:that.config.top || 0 , //如果有定義高度就從配置中取,否則就置頂 171 zIndex:10,//展示到前列 172 display: 'block' 173 }); 174 175 //延遲時(shí)間由配置的開始時(shí)間減去隊(duì)列中該彈幕所處的位置所需要等的位置,而這里的隊(duì)列位置是由驅(qū)使者diretor分配的,事實(shí)上根據(jù)我的調(diào)試發(fā)現(xiàn)這種寫法只能近似于模仿順序,然而如果兩個(gè)播放時(shí)間間隔不大將會(huì)同時(shí)出發(fā),不過這個(gè)對(duì)于普通體驗(yàn)影響不大。后期如果有強(qiáng)需求可能需要把整個(gè)邏輯改掉 176 var delayTime = that.config.time - (that.config.queue - 1) * checkTime; 177 setTimeout(function(){ 178 that.move(); 179 },delayTime); 180 181 } 182 183 //設(shè)置一個(gè)支持事件機(jī)制的對(duì)象,也就是彈幕們的驅(qū)使者,它來驅(qū)使彈幕彈彈彈 184 185 var diretor = $({});//創(chuàng)建一個(gè)空的對(duì)象 186 187 //對(duì)舞臺(tái)進(jìn)行樣式設(shè)置,其實(shí)可以直接寫到css里面 188 stage.css({ 189 position:'relative', 190 overflow:'hidden' 191 }); 192 193 //批量讀取寫好的彈幕配置內(nèi)容,然而后期是需要?jiǎng)討B(tài)彈幕,打算采用websocket來分配因此這里也只是為了測(cè)試而簡(jiǎn)寫 194 195 //that.messages 是配合vue的data來設(shè)置的,如果是為了在單個(gè)文件中引用,去掉that,把message寫在該js里面 196 197 $.each(messages,function(k,config){ 198 //確認(rèn)彈出的時(shí)間 199 var queue = Math.ceil(config.time / checkTime); 200 config.queue = queue; 201 202 //新建一個(gè)對(duì)象給它配置 203 var go = new BarrageItem(config); 204 //驅(qū)動(dòng)者監(jiān)聽驅(qū)使動(dòng)作 205 diretor.on(queue+'start',function(){ 206 go.start(); 207 }) 208 }); 209 210 var currentQueue = 0; 211 setInterval(function(){ 212 //從隊(duì)列中取第n個(gè)開始談 213 diretor.trigger(currentQueue+'start'); 214 //如果都彈完了 循環(huán)來一遍 215 if (currentQueue === playCount) { 216 currentQueue = 0; 217 }else{ 218 currentQueue++; 219 } 220 221 },checkTime); 222 </script> 223 224 225 226 </html>
效果展示:
可以把代碼copy出來,點(diǎn)擊重播、暫停、快進(jìn)、放大等功能試試效果,后續(xù)結(jié)合webSocket 的即時(shí)彈幕也會(huì)有所展示!
下班嘍?。。?!拜拜~~