德扑之星有限公司官方网站

視頻網站的彈幕原理和開源代碼分享

 

隨著視頻網站和直播網站的興起ⓣⓤⓥⓦⓧⓨⓩ,彈幕的功能算是一個核心元素㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂,彈幕最初是由日本視頻網站Niconico引入的⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵❆❇❈❉❊†☨✞✝☥☦☓☩☯,國內除了在Bilibili和AcFun等彈幕視頻網站中使用之外⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵❆❇❈❉❊†☨✞✝☥☦☓☩☯,其他主流視頻網站中的視頻播放器也支持彈幕⑰⑱⑲⑳⓪⓿❶❷❸❹❺,對于視頻網站和直播網站來說ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ,彈幕的交互實時性更高✺ϟ☇♤♧♡♢♠♣♥,更加受歡迎♦☜☞☝✍☚☛☟✌✽✾✿❁❃。

本文重點介紹一下彈幕的基本原理⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵❆❇❈❉❊†☨✞✝☥☦☓☩☯,以及JavaScript和HTML的代碼實現方式ⅲⅳⅴⅵⅶⅷⅸⅹⒶⒷⒸⒹ,最后分享一個彈幕的開源庫ⓣⓤⓥⓦⓧⓨⓩ。

關于視頻網站建設⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾,可以參考我們之前的通過Drupal構建自建視頻課程平臺♀☿☼☀☁☂☄。

 

 

彈幕基礎知識

單條彈幕的屬性

  1. 模式:滾動彈幕㈠㈡㈢㈣㈤㈥㈦、逆向彈幕웃유ღ♋♂、頂部彈幕☧☬☸✡♁✙♆。,、':∶;、底部彈幕✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴。
  2. 基本屬性:正文ⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉ、出現時間☾☽❄☃、持續時間✺ϟ☇♤♧♡♢♠♣♥、字體♦☜☞☝✍☚☛☟✌✽✾✿❁❃、字號ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ、顏色等樣式①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯。
  3. 容器:塊級元素✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴,一般是與視頻大小相同的區域웃유ღ♋♂。

彈幕的特性:

  1. 空間的獨立性:雖然在同一個元素內展現☧☬☸✡♁✙♆。,、':∶;,但空間計算上每種彈幕模式處于不同層☧☬☸✡♁✙♆。,、':∶;,每種模式也可以有多層⑰⑱⑲⑳⓪⓿❶❷❸❹❺,每層內的彈幕占位不會重疊ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ。
  2. 渲染的確定性:如果彈幕容器和渲染的列表固定不變㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉,在沒有用戶交互(比如暫停單條彈幕)的情況下♦☜☞☝✍☚☛☟✌✽✾✿❁❃,每次渲染每條彈幕所出現的位置和順序都是固定的㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂。
  3. 各模式的統一性:每種模式的彈幕的生存時間保持一致☾☽❄☃。

彈幕的基本模式:

  1. 滾動彈幕:自右向左勻速滾動過屏幕的彈幕❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣,以自上而下的優先度展示ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ。
  2. 逆向彈幕:自左向右勻速滾動過屏幕的彈幕♦☜☞☝✍☚☛☟✌✽✾✿❁❃,以自上而下的優先度展示ⓣⓤⓥⓦⓧⓨⓩ,逆向彈幕是相對于滾動彈幕的相反方向滾動的彈幕展示模式웃유ღ♋♂。
  3. 頂部彈幕:自上而下靜止居中的彈幕✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴、以自上而下的優先度展示⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵❆❇❈❉❊†☨✞✝☥☦☓☩☯。
  4. 底部彈幕:自下而上靜止居中的彈幕✵✶✷✸✹✺✻✼❄❅、以自下而上的優先度展示웃유ღ♋♂。

彈幕的使用場景:

  1. 點播視頻互動⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓,把評論搬到彈幕上來
  2. 直播互動ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ,直播視頻中㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉,可以直接通過彈幕討論ⅲⅳⅴⅵⅶⅷⅸⅹⒶⒷⒸⒹ、互動
  3. 視頻內容增強㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂,比如對視頻中某些內容進行解釋☾☽❄☃,描述等
  4. 標記視頻亮點ⅲⅳⅴⅵⅶⅷⅸⅹⒶⒷⒸⒹ,對視頻中的高亮進行提示等
  5. 網頁互動ⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉ,比如彈幕可以點贊✵✶✷✸✹✺✻✼❄❅,回復等
  6. 互動上墻ⅲⅳⅴⅵⅶⅷⅸⅹⒶⒷⒸⒹ,大屏的投票可以通過彈幕來實現交互大墻
  7. 蒙版彈幕☈⊙☉℃℉❅,可以對某系地方不想讓用戶看到ⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉ,可以通過彈幕掩蓋
  8. 非文字彈幕ⓣⓤⓥⓦⓧⓨⓩ,比如表情웃유ღ♋♂、紅包等等交互效果

 

彈幕的實現原理

彈幕本身不是對視頻的操作♦☜☞☝✍☚☛☟✌✽✾✿❁❃,其實是給視頻上面加DIV等DOM元素⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓,也就是給視頻上面加層⒜⒝⒞⒟⒠⒡⒢⒣⒤,然后展示我們想要的內容即可❻❼❽❾❿⓫⓬⓭⓮⓯⓰,目前彈幕的主要實現有兩種方式:

  1. Canvas
  2. HTML+CSS

首先ⓚⓛⓜⓝⓞⓟⓠⓡⓢ,這種我們自然想到用CanvasⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉ,使用Canvas能很方便地繪制動畫❻❼❽❾❿⓫⓬⓭⓮⓯⓰,并且獲得非常不錯的性能⑰⑱⑲⑳⓪⓿❶❷❸❹❺,目前前端不少動畫都是通過Canvas去做⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾。不過對于基于Canvas的動畫而言♦☜☞☝✍☚☛☟✌✽✾✿❁❃,最大的問題就是“交互性”上面①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯。

如果用HTML+CSS的方式實現ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ,我們可以很簡單地通過監聽原生DOM事件去知道哪一條彈幕與用戶鼠標發生了交互ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ。但是通過Canvasⓚⓛⓜⓝⓞⓟⓠⓡⓢ,我們只能通過監聽畫布的事件♀☿☼☀☁☂☄,然后做一堆遍歷計算坐標的騷操作去確定是哪一條彈幕♦☜☞☝✍☚☛☟✌✽✾✿❁❃。從鵝廠的視頻網站可以看到⑰⑱⑲⑳⓪⓿❶❷❸❹❺,他們的彈幕是可交互的✺ϟ☇♤♧♡♢♠♣♥,所以他們使用了HTML+CSS的實現方式ⓚⓛⓜⓝⓞⓟⓠⓡⓢ;而B站的彈幕是非交互的☈⊙☉℃℉❅,它提供Canvas和HTML+CSS可選☈⊙☉℃℉❅,默認是前者㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂。

雖然功能性上兩者的實現會有點差異ⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙ,但彈幕的基本原理都是一樣✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴。

所以彈幕本身就是對DIV元素的操作✵✶✷✸✹✺✻✼❄❅,DIV層一般在Video層上面ⓚⓛⓜⓝⓞⓟⓠⓡⓢ,類似下面的圖⒔⒕⒖⒗⒘⒙⒚⒛ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅰⅱ,不過也有放在Video層下面❣❦❧♡۵,彈幕層在底下✺ϟ☇♤♧♡♢♠♣♥,詳情參考這篇文章的介紹 https://github.com/logcas/a-barrage 

 

 

 

 

彈幕實現的技術細節

我們先分析一下文檔管理系統的基本需求以及功能點㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉,

從上圖可以看到❻❼❽❾❿⓫⓬⓭⓮⓯⓰,彈幕是很清晰地分成了一行一行✵✶✷✸✹✺✻✼❄❅,我把它們稱為“軌道”⑰⑱⑲⑳⓪⓿❶❷❸❹❺。每一個彈幕都只在軌道上從右往左移動ⅲⅳⅴⅵⅶⅷⅸⅹⒶⒷⒸⒹ,不會越界☧☬☸✡♁✙♆。,、':∶;。那么♦☜☞☝✍☚☛☟✌✽✾✿❁❃,要實現彈幕功能☈⊙☉℃℉❅,首先我們必須把彈幕分成若干個軌道ⓣⓤⓥⓦⓧⓨⓩ,然后再在合適的時間把彈幕“塞”進去讓它平移♀☿☼☀☁☂☄。

每一個軌道會有兩個屬性:

barrages: T[] = []
offset: number = 0

barrages為一個彈幕數組㈠㈡㈢㈣㈤㈥㈦,offset則是已占據的寬度㈠㈡㈢㈣㈤㈥㈦。offset用于滾動彈幕時♦☜☞☝✍☚☛☟✌✽✾✿❁❃,彈幕軌道添加彈幕前判斷最佳軌道❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣;當彈幕類型時固定時無作用❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣。barrages存放當前軌道上可現實的彈幕實例✵✶✷✸✹✺✻✼❄❅。

每一個軌道實例管理自己軌道中的數組ⓚⓛⓜⓝⓞⓟⓠⓡⓢ,主要進行進行增✵✶✷✸✹✺✻✼❄❅、刪ⓣⓤⓥⓦⓧⓨⓩ、重置以及更新offest的操作⒔⒕⒖⒗⒘⒙⒚⒛ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅰⅱ。

添加新彈幕

push(...items: T[]) {
  this.barrages.push(...items)
}

刪除彈幕
remove(index: number) {
  if (index <0 || index >= this.barrages.length) { return }
  this.barrages.splice(index, 1)
}

重置軌道

reset() {
  this.barrages = [] this.offset = 0
}

更新剩余軌
updateOffset() {
  const endBarrage = this.barrages[this.barrages.length - 1]
  if (endBarrage && isScrollBarrage(endBarrage)) {
    const { speed } = endBarrage this.offset -= speed
} }
 

拿來即用-開源的方案

 

在知名的男性交友網站github上♀☿☼☀☁☂☄,已經有一款很好用的彈幕開源解決方案❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣,并且是國產的☧☬☸✡♁✙♆。,、':∶;,叫abarrage⒜⒝⒞⒟⒠⒡⒢⒣⒤,同時實現了Canvas和HTML+CSS的模式⒔⒕⒖⒗⒘⒙⒚⒛ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅰⅱ,要用的話直接在github把源代碼擼下來⒜⒝⒞⒟⒠⒡⒢⒣⒤,并且有在線的體驗地址⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓,效果非常不錯ⓚⓛⓜⓝⓞⓟⓠⓡⓢ。

A-Barrage 同時支持Canvas渲染和HTML+CSS的渲染模式㈠㈡㈢㈣㈤㈥㈦,你可以根據實際情況采用不同的渲染引擎進行彈幕的渲染♀☿☼☀☁☂☄。其中☧☬☸✡♁✙♆。,、':∶;,Canvas是非交互式渲染웃유ღ♋♂,也就是說❻❼❽❾❿⓫⓬⓭⓮⓯⓰,采用Canvas渲染的彈幕并不會有任何的交互操作♦☜☞☝✍☚☛☟✌✽✾✿❁❃,純展示性質☧☬☸✡♁✙♆。,、':∶;;HTML+CSS是交互式渲染ⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉ,如果你的網站允許用戶與彈幕之間進行一些交互(如點贊웃유ღ♋♂、回復等)✵✶✷✸✹✺✻✼❄❅,那么可以采用HTML+CSS的渲染模式♀☿☼☀☁☂☄,它會結合瀏覽器的DOM事件進行響應ⓣⓤⓥⓦⓧⓨⓩ。

github地址: https://github.com/logcas/a-barrage 

測試地址: https://logcas.github.io/a-barrage/example/css3.html 

 

 

德扑之星官网下载 网站地图