知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

網易易盾發表於2022-11-17

導讀:彈幕的出現增加了影片觀看者的深度參與感,彈幕也逐漸成為國內各大影片網站最基本的評論互動形式,本文將透過網易易盾在彈幕實現原理及互動方式方面的實踐,具體介紹彈幕相較於傳統聊天室的區別與實踐經驗,希望能為大家在彈幕系統設計方面帶來一些借鑑。

引言

在 2022 年的今天,彈幕在國內的各大影片網站已經成為了一個最基本的評論互動形式,它為影片社交增添了很大的活力,然而這也給影片內容的稽核工作帶來了巨大挑戰,在較為嚴格的稽核場景下,數量龐大的彈幕透過機審後,我們會進行一輪或多輪的人工稽核,但是為了不誤判,易盾的智慧稽核平臺的實踐中為了能結合影片內容上下文,對被稽核彈幕進行精準判斷,實現了一套彈幕系統,和原影片內容及彈幕內容保持高度一致,更有利於提高稽核的精準與效率。接下來就是易盾在彈幕系統的實踐中總結出來的通用設計與實踐。

彈幕簡介

彈幕的讀音為 dàn mù,因為大量評論在影片上方滾動時很像飛行射擊遊戲裡的“彈幕”,所以國人命名如此,而在日語中被稱為 danmaku,注意了,不是 danmuku。

彈幕的發明者具體到個人不是很清楚,這種評論形式最初是在日本的線上影片分享網站 Niconico 動畫出現的,後來被 AcFun 引進,再後來大家都知道了,Bilibili 將這種形式發揚光大,可以說彈幕成就了 B 站,B 站也發揚了彈幕這種形式。

現如今國內各大影片平臺,發彈幕已經成為了最基本的功能了,不過就我目前體驗來看,還是 B 站的彈幕花樣最多,但實際上對於騰訊影片、愛奇藝這種偏影視的影片網站來說,也不需要多少花樣,不然可能會適得其反。

彈幕得以發展的原因

在彈幕這種評論形式出現之前,對於線上影片使用者,他們之間的實時交流方式主要是聊天室模式,使用者輸入文字內容後,文字列表將整體從下向上滾動,如下圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

而在彈幕出現之後,使用者輸入文字內容後,文字將出現在影片右側,在獨立的軌道中從右向左移動,如下圖: 

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

兩者之間各有各的優勢,不過就現在使用者的觀看習慣來說,彈幕帶來的使用者體驗是比聊天室模式要好的,接下來筆者將介紹彈幕都有哪些優勢。

評論同屏密度 

與聊天室模式相比,彈幕模式有更寬的展示區域,畢竟使用者觀看的資訊主體在影片內容,沒有哪個網站會把聊天框的寬度設定的比影片寬度還大的。同一條評論,因為彈幕是橫向軌道內移動,所以不會像聊天室模式下由於句子過長而導致這行佔據更多高度。所以同屏下,對於人眼來說,彈幕模式比聊天室模式接收到的資訊更多。

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

評論更新頻率 

在聊天室模式中,所有評論都是以相同的頻率向上滾動,一條評論的出現會將所有評論向上頂,而彈幕模式下每條評論都在獨立的軌道中移動,並不受其他評論的出現所影響,可以透過演算法保障每條評論在螢幕內的展示時長。

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

視線移動適應性 

在聊天室模式中,使用者如果關注影片內容則無法閱讀評論。而彈幕模式透過把文字覆蓋於影片畫面之上讓使用者可以同時閱讀評論與觀看影片,無需視線在兩個區域間往返移動,有更好的沉浸體驗。

以下是聊天室模式下,我們的視線移動方向示意圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

以下是彈幕模式下,我們的視線聚焦範圍示意圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

閱讀習慣

我們大多數人(除了像阿拉伯國家的人民)閱讀習慣是從左到右、從上到下,因此人們養成了橫向閱讀單行資訊的習慣。

在彈幕模式下文字從右向左移動,人從左向右閱讀,形成了從左向右的合力,在這種模式下我們可以用較短時間就能理解文字的含義。

以下是彈幕模式下,視覺的合力方向示意圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

而在聊天室模式下,人從左到右閱讀,而閱讀中的文字則在不停的向上移動,形成一個傾斜向上的合力,這會對快速閱讀產生障礙。

以下是聊天室模式下,視覺的合力方向示意圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

心理因素 

彈幕的出現能使多個使用者對同一影片時間點於不同的時空發表看法,有一種跨越時空交流的感覺,極大的增強了使用者的參與感。

在觀看影片的某一時間節點,在彈幕上能看到很多與自己相同的觀點,會覺得這個世界上有很多和你一樣想法的人,會有一種共鳴感。另外,有時候還會看到很有意思的彈幕,惹的人會心一笑,還會看到一些很有哲理、對自己的知識擴充套件也很有幫助的彈幕。

彈幕的實現方式

在現在市面上,彈幕的實現可以分為兩種方式,一個是 HTML+CSS 方式,另一個是 Canvas 方式。

前者實現能很方便地給每條彈幕新增事件,比如我們常用的移到彈幕上懸停並彈框跳出選項,這得益於原生的 DOM 事件很容易做到。而後者的實現需要自己去寫一套事件機制,對於像我這種對 Canvas 不太熟的前端,就比較麻煩了,不過願意花個幾天時間去搞一搞倒也不是什麼問題。

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

兩者在效能上還是有區別的,結論是 HTML+CSS 的效能沒有 Canvas 好,前者會在頁面下建立非常多的 DOM 節點,當同屏彈幕過多導致出現大量 DOM 節點時,對於一些“老機器”說不準都能卡死。所以大家會看到,在直播時,對效能要求很高,比如很多影片網站直播就會採用 Canvas 的實現方式去建立彈幕。

接下來我們的程式碼實操均採用 HTML+CSS 方式實現,對 Canvas 感興趣的,按照相同的設計思路也是能寫出來的。

彈幕的設計

我們開始對彈幕的實現做一個功能上的設計,在後面程式碼實操之前讓大家有一個初步的設計思路,更容易理解程式碼的意思。首先我們看一下影片中常規的彈幕畫面:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

其中我使用“紅線”標記出來的就是每輪彈幕所滾動的區域,我們稱這個區域為軌道,圖中又畫了我們常見的滾動彈幕及底部彈幕,當然,為了圖簡潔點,頂部彈幕我就不畫了。

目前我們能確定的資訊是,彈幕系統需要一個軌道的承載邏輯,同時背後還需要一個指揮官來決定每一條新加入的彈幕是去往哪個軌道,什麼時候開始渲染彈幕,以及動畫邏輯。

軌道 

從彈幕的呈現效果可以很明顯得知,一個軌道內有若干的彈幕,而且彈幕的出現是依次進行的,這意味著需要一個容器來把這些彈幕裝進去,適合的時機再一條條放出來。為了讓指揮官能計算出這個時機,我們還需要一個變數 offset 來表示軌道已佔據的寬度。

根據上面的簡單分析,我們可以先定義好表示這個軌道的類和它所需要的屬性:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

容器我們有了 danmus 這個陣列,但是如何新增、刪除彈幕呢?那就要定義方法了:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

最後還有一個特別重要的方法是用於更新軌道已佔據的寬度,在後面會說到渲染彈幕動畫的時候,彈幕進入軌道的時機是由這個所佔據軌道的寬度來計算的,所以彈幕的每次移動,我們都需要去對軌道的所佔據寬度進行更新。 

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

這就是整個軌道的設計,非常簡潔明瞭,它的職責非常清晰:管理軌道內彈幕的增加、刪除及已佔據寬度的更新,但是不負責渲染!

(看到這裡如果有心情仔細瞭解邏輯程式碼是怎麼樣的,可以點選這個倉庫檢視原始碼:https://github.com/vortesnail/qier-player/tree/master/packages/qier-player-danmaku)

指揮官 

由前文可知,我們一個影片畫布內是有多條軌道的,那麼如何管理這些軌道呢?那就是背後的指揮官在“負重前行”了。

首先是一種指揮官管理了當前彈幕型別下的 2N 個軌道:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

而我們這次的彈幕設計中包括了滾動彈幕,頂部固定彈幕和底部固定彈幕,所以對於指揮官我們又有了以下層級關係:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

然而這些指揮官是有共同的屬性及方法的,我們可以抽象成一個指揮官基類(BaseCommander),簡單的程式碼結構如下:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

有了指揮官基類,我們就可以去分別實現各種型別的指揮官了,在這裡我不想把指揮官的實現程式碼貼出來,放一張思路圖,如果有興趣的,可以再去閱讀原始碼:https://github.com/vortesnail/qier-player/tree/master/packages/qier-player-danmaku

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

render 

上面的圖除了“使用者傳送彈幕”這一步,其它所有步驟是我們的核心實現 render ,所以我們來對此方法做一個剖析。它的工作職責為下圖:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

從等待佇列中抽取合適的彈幕放入軌道 

每一個指揮官(Commander)都有自己的等待佇列 waitingQueue,裡面存放的是所有還未被渲染到畫布上的彈幕,每次在 render 方法執行時,要把等待佇列中的彈幕新增到合適的軌道上去,這個過程由 extractDanmu 方法實現:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

這裡的思想是,遍歷等待佇列中的彈幕,嘗試將其透過 add 方法新增到軌道上,如果新增成功,將該彈幕從等待佇列中刪掉,進行後面的彈幕的新增。

但是遍歷過程中若出現了一次新增失敗,證明所有軌道都沒有辦法再新增新的彈幕了,我們就要停止遍歷。

add 方法的作用即為將彈幕新增到合適的軌道上,而實現這一目的還需要以下過程:

1.找到合適的軌道;

2.建立真實的彈幕 DOM 並計算速度;

3.將其推入要被加入的軌道的 danmus 陣列中,計算彈幕的 offset。

另外,add 是繼承指揮官基類的抽象方法的具體實現,這裡我們以最複雜的滾動彈幕作為實現舉例:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

上面程式碼中第一行就是 findTrack 方法,目的就是找到合適的軌道,如何找到合適的軌道呢?

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

這裡採取的實現策略還是比較直觀簡單的,從上往下遍歷軌道,找到第一個能插入的軌道,

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

找到合適的軌道就返回其下標,繼續執行後面邏輯,沒有就返回 false。

接下來我們探索下怎麼計算彈幕的速度,這裡彈幕的速度看產品喜好,下面介紹兩種:

1.每個彈幕的速度都是相同的,所以也就不存在碰撞問題,但是效果非常死板。

2.每個彈幕的速度都是不一樣的,但是需要解決碰撞問題。

為了實現不同的速度,最簡單有效的方式其實就是透過追及問題求出彈幕的最大速度。

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

假設現在軌道長度為 L,軌道上已存在的最後一個 彈幕A 已經飛過了距離 S,其速度已知是 vA ,那麼如何計算 彈幕B 的速度呢?

首先我們假設 彈幕B 和 彈幕A 要在同一時間達到軌道的終點,就會得到以下的等式:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

於是見很簡單的推理出了 彈幕B 的速度為 vB,轉換為我們程式碼裡面的變數名就是後面紅色字的等式。

但是這樣會有一個問題就是,假入 彈幕A 已經快到了軌道終點了,這樣就會造成計算出的 彈幕B 的速度過大,具體表現即為彈幕飛的很快一閃而過,這種體驗是很差的,所以我們需要有一個最大速度的限制,在上面 add 方法中有這麼一行程式碼就是這個作用:

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

這裡 defaultSpped 大小為平均速度,所以這裡的限制即為平均速度的 2 倍。

後面就是將建立好的彈幕 DOM 放到指定的軌道中的 danmus 陣列等待渲染即可。

遍歷軌道陣列,依次渲染軌道中的彈幕 

放出 render 方法的實現,我們主要經歷以下四個過程:

1.遍歷每個軌道中的每個彈幕;

2.獲取彈幕 DOM 並計算 translateX;

3.更新軌道的偏移量 offset;

4.移除超出畫布的彈幕。

知物由學 | 彈幕蜂擁而入,智慧稽核平臺如何用技術破局?

以上程式碼應該是很容易看出對應的過程,這裡就不細述了。

總結

最後值得一提的是,中國網路視聽節目服務協會發布《網路短影片平臺管理規範》和《網路短影片內容稽核標準細則》,對短影片的釋出者和平臺方提出詳細要求,其中一大亮點是將“彈幕”劃入“先審後播”的範圍,進行“實時管理”先審後播,彈幕迎來良性發展。

百萬使用者同時線上,高併發的彈幕一度成為網站的內容生態治理的巨大挑戰。面臨的問題主要是:網友肆意發言,主動繞過機器稽核,且由於彈幕數量龐雜,難免有很多有害內容成為“漏網之魚”。無論是報復社會的噴子,還是競爭對手的黑粉水軍,都會破壞觀眾的觀看體驗,威脅直播平臺的核心競爭力。

彈幕稽核環節,易盾為網站彈幕提供“機審+人審+舉報”機制,透過機器學習來自行判斷彈幕,輔助人工靈活應對,抵禦內容生態惡化是易盾的使命。彈幕將以文字形式匯合入“智慧稽核平臺”,經過“內容智慧檢測技術”與“人工稽核”的兩道篩選,除了及時發現彈幕中涉及的廣告、涉黃、暴恐等網路監管部門嚴令禁止的內容,還可以針對主播的需求,為主播提供實時的可操控的介面,透過新增相關黑粉攻擊言論、帶節奏語言性質的文字,進行實時的遮蔽,保障主播粉絲的觀看氛圍。

如何確保平臺內容安全幾乎是網站發展的第一要務,其中就包括彈幕,但凡彈幕出現與“正能量”相悖的內容,都將面臨安全風險。這篇文章簡單的討論了彈幕的常規設計、實現與安全保障思路,裡面還有可以最佳化的點,比如彈幕的速度問題,還有沒有提到的事件監聽,具體實現大家如果有興趣可以閱讀下原始碼:https://github.com/vortesnail/qier-player/tree/master/packages/qier-player-danmaku


相關文章