羅尹奇
(電子科技大學 圖書館,四川 成都 610000)
隨著短視頻應(yīng)用的不斷推廣,以視頻為媒介的信息傳播技術(shù)正發(fā)揮著越來越重要的作用。一方面,互聯(lián)網(wǎng)的普及與通信技術(shù)的發(fā)展顯著地提升了音視頻數(shù)據(jù)的傳輸速率與質(zhì)量,克服了過去傳統(tǒng)的音視頻網(wǎng)絡(luò)傳輸延遲、畫質(zhì)低劣、播放技術(shù)兼容性差[1]等問題;另一方面,相比于文字與圖片等靜態(tài)內(nèi)容,音視頻以其豐富多樣、動態(tài)直觀的表現(xiàn)力更容易被大眾廣泛接受[2-3],也日益成為信息傳播的主要手段。
在短視頻應(yīng)用的浪潮下,高校作為培育人才的前沿基地,對短視頻平臺的需求尤為迫切,其主要表現(xiàn)在:
受眾的需求。學生群體作為高校最主要的有生力量,其對當下短視頻應(yīng)用的接受程度、活躍熱度和使用頻率均較高[4-5],音視頻中傳遞的信息也相比于枯燥的圖文更為有效。
教學的需求。視頻課堂的興起極大地豐富和補充了傳統(tǒng)教學手段,高校依托短視頻平臺能夠拉近師生的距離,提供形式多樣的自主學習手段,從而更好地實現(xiàn)人才培養(yǎng)[6-7]。
安全可控的需求。盡管當前諸多短視頻平臺可供高校選擇,然而平臺所呈現(xiàn)的視頻內(nèi)容與版權(quán)難以得到有效控制[8],內(nèi)容防篡改與視頻文件下載無法得到保障。
為實現(xiàn)構(gòu)建高校短視頻平臺,本文以電子科技大學知識產(chǎn)權(quán)信息服務(wù)中心網(wǎng)為例,分析了短視頻平臺所需的關(guān)鍵技術(shù),提出了平臺整體架構(gòu)方案,并給出了平臺核心代碼實現(xiàn)。
HLS(HTTP Live Streaming)是蘋果公司提出的基于HTTP協(xié)議的流媒體網(wǎng)絡(luò)傳輸協(xié)議,其基本原理是將視頻文件或媒體流按照不同的碼率切分成數(shù)個片段進行傳輸;客戶端在播放碼流時,可以根據(jù)自身的帶寬及性能限制,選擇合適碼率的碼流進行下載播放[9]。
作為視頻點播常用的協(xié)議,MP4與HLS各有特點和優(yōu)勢,對比結(jié)果如表1所示:
表1 MP4 與HLS 播放對比
盡管MP4與HLS均可以應(yīng)用于短視頻點播協(xié)議,但考慮到起播盡可能快,拖動時間軸能快速加載,以及相同分辨率與幀率情況下使用高碼率保證畫質(zhì),本文使用了HLS作為短視頻點播協(xié)議。
JavaCV是計算機視覺領(lǐng)域的封裝庫[10],其本身實現(xiàn)了對當前常用的基于C/C++音視頻處理庫的Java封裝,包括OpenCV、FFmpeg等,并通過JNI(Java Native Interface)方式實現(xiàn)調(diào)用。
本文使用JavaCV的主要原因基于如下三點:
視頻切片。HLS協(xié)議規(guī)定了其視頻文件由一個m3u8播放索引列表以及數(shù)個ts切片文件組成,直接上傳多個文件到流媒體服務(wù)器對于用戶使用體驗感不夠友好,因此用戶端采用MP4格式文件上傳,而在服務(wù)端則通過JavaCV實現(xiàn)對MP4文件切片。
平臺代碼整合。平臺采用Java作為開發(fā)語言,可以直接通過調(diào)用JavaCV的接口實現(xiàn)處理視頻,避免了直接調(diào)用本地可執(zhí)行程序引起的進程開銷。
跨平臺。JavaCV同時提供了基于Windows、Linux等多個平臺的底層庫封裝,因此僅需替換底層封裝庫即可實現(xiàn)跨平臺,而上層平臺邏輯則無需改變,能夠更好的適應(yīng)不同的部署環(huán)境要求。
為了構(gòu)建短視頻平臺,實現(xiàn)視頻文件的上傳與分發(fā)切片等功能,系統(tǒng)采用ActiveMQ作為視頻處理請求緩存隊列,避免服務(wù)器并行處理多個管理員的多個視頻文件造成的負載過大問題。同時使用MySQL作為中心數(shù)據(jù)庫,用于記錄視頻切片處理后的結(jié)果,以便檢索視頻。檢索的結(jié)果會組織為對應(yīng)的視頻資源訪問路徑,再次提交到Nginx流媒體服務(wù)器,并最終返回該視頻流。系統(tǒng)整體架構(gòu)如圖1所示:
圖1 系統(tǒng)整體架構(gòu)
其中控制層包含了整個系統(tǒng)的關(guān)鍵功能,其核心內(nèi)容為:
視頻上傳:提供視頻上傳接口,用于接收管理員端傳遞的視頻文件。該接口一方面對上傳文件的格式、大小、MIME類型進行限制,確保傳遞的文件符合系統(tǒng)的要求;另一方面接口將接收到的視頻文件存儲到臨時視頻文件夾中,并向隊列中寫入處理請求。
視頻切分:循環(huán)不斷的從隊列中取出處理請求,讀取請求中的文件路徑數(shù)據(jù)從而獲得用戶上傳的原始文件對象。通過調(diào)用JavaCV庫,將用戶上傳的視頻轉(zhuǎn)化為HLS格式的視頻,并將處理結(jié)果寫入中心數(shù)據(jù)庫。由于為了降低服務(wù)器的負載壓力,切分過程采用了單線程阻塞模式,即每一次讀取一個處理請求,將視頻處理完畢并向數(shù)據(jù)庫寫入結(jié)果之后,再處理第二個請求。
隊列讀寫:提供隊列讀寫操作接口,對控制層訪問ActiveMQ的細節(jié)進行封裝屏蔽。
視頻查詢與URL生成:對MySQL數(shù)據(jù)庫中的視頻處理結(jié)果進行檢索,將檢索出的處理后的視頻信息重新拼接形成URL訪問地址,該地址即為m3u8文件的網(wǎng)絡(luò)訪問地址,并再次提交到Nginx流媒體服務(wù)器,獲取視頻切片數(shù)據(jù)。
根據(jù)系統(tǒng)整體架構(gòu)設(shè)計,本文提出整個系統(tǒng)由三大部分構(gòu)成:業(yè)務(wù)系統(tǒng)、視頻切分程序和流媒體服務(wù)器。其工作模式如圖2所示:
圖2 系統(tǒng)工作模式
其中業(yè)務(wù)系統(tǒng)負責一方面接收管理員上傳視頻,并向隊列寫入視頻處理請求;另一方面接收用戶查詢視頻的請求,在返回的頁面中生成獲取視頻的URL規(guī)則。視頻切分程序則周期性的從隊列中取出處理請求,對管理員上傳的視頻進行切分,將處理結(jié)果寫入數(shù)據(jù)庫。Nginx作為流媒體服務(wù)器,響應(yīng)視頻URL,返回對應(yīng)的視頻流。
視頻上傳與切分作為系統(tǒng)的核心功能,其實現(xiàn)了對管理員上傳的視頻進行切片處理,并最終在數(shù)據(jù)庫中插入處理后的結(jié)果。其具體流程如圖3所示:
圖3 視頻上傳及切分流程
首先,管理員端通過后臺上傳MP4文件到服務(wù)器。服務(wù)器接收到MP4文件之后,一方面將該文件寫入臨時目錄中,實現(xiàn)視頻的暫時存儲;另一方面,在將文件成功存儲到臨時目錄之后,系統(tǒng)將該文件的絕對路徑連同附加信息(如標題、發(fā)布時間等)作為請求對象,寫入到處理隊列中,表示該文件需要進行切分。
其次,視頻切分程序循環(huán)地從隊列中取出請求,獲取上傳的MP4文件對象,并調(diào)用JavaCV接口實現(xiàn)將MP4轉(zhuǎn)化為HLS文件(即一個m3u8索引列表文件及數(shù)個ts文件),并寫入VOD點播目錄中。需要注意的是,由于HLS協(xié)議定義的是一組文件,為了方便管理,系統(tǒng)會在VOD目錄下生成具有唯一編號的子目錄,再在該子目錄中存儲這一組文件。此時系統(tǒng)可以使用子目錄來實現(xiàn)定位到特定視頻。
最后,系統(tǒng)將生成的子目錄作為處理的結(jié)果,并連同視頻的附加信息一并寫入到數(shù)據(jù)庫中,從而完成了整個視頻的處理流程。
在完成視頻處理之后,數(shù)據(jù)庫中包含了關(guān)于該視頻的相關(guān)信息,一方面附加信息描述了該段視頻的文本信息,便于檢索分類;另一方面子目錄信息則可以根據(jù)URL生成規(guī)則,產(chǎn)生實際的視頻訪問路徑,從而為網(wǎng)絡(luò)播放插件提供數(shù)據(jù)源。其具體流程如圖4所示:
圖4 視頻查詢與獲取
流程中最為關(guān)鍵的是URL生成規(guī)則。系統(tǒng)在邏輯上是使用子目錄表示視頻,而實際網(wǎng)絡(luò)視頻播放插件需要定位到m3u8文件,因此URL生成規(guī)則的主要功能是實現(xiàn)將邏輯表示轉(zhuǎn)化為實際表示。
系統(tǒng)后端采用Struts2+Spring+Hibernate開發(fā),其中Struts2負責完成控制層代碼實現(xiàn),Hibernate負責實現(xiàn)對數(shù)據(jù)庫的訪問,Spring則實現(xiàn)對象托管與注入。網(wǎng)絡(luò)視頻播放插件使用了Video.js。系統(tǒng)關(guān)鍵代碼實現(xiàn)如下:
根據(jù)實際應(yīng)用的需要,系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)主要有MessageInfo類與VideoInfo類,其中MessageInfo類用于記錄管理員上傳的視頻以及其附加信息;VideoInfo類則是與數(shù)據(jù)庫表對應(yīng),利用Hibernate框架實現(xiàn)對象關(guān)系映射。其代碼如表2、表3、表4所示:
表3 VideoInfo 類
表4 VideoInfo 類對應(yīng)的數(shù)據(jù)庫表tsg_infos_videos
由于MessageInfo類實例需要存儲到隊列中,因此該類必須是可序列化的,需實現(xiàn)Serializable接口。
在數(shù)據(jù)庫表tsg_infos_videos中,主鍵為id,video_uuid用于記錄VOD點播目錄下生成的子目錄的名稱,子目錄名稱生成策略為UUID。除此之外,其余字段為符合當前實際應(yīng)用所需的附加字段。
視頻上傳模塊主要實現(xiàn)將管理員上傳的MP4文件存儲到服務(wù)器臨時視頻目錄,并向隊列中寫入該視頻的相關(guān)信息。其代碼如表5所示:
表5 視頻上傳
視頻切分為后臺進程,不斷地從隊列中獲取文件的相關(guān)信息,提取絕對路徑轉(zhuǎn)化為文件對象,并利用JavaCV實現(xiàn)切分,生成m3u8文件及ts切片。其中視頻切分關(guān)鍵代碼如表6所示:目錄路徑作為參數(shù)傳遞給模塊。其調(diào)用代碼如表7所示。
表6 視頻切分
表7 調(diào)用視頻切分
當獲取某一條視頻時,系統(tǒng)接受傳遞的id參數(shù),并在數(shù)據(jù)庫中檢索出該id對應(yīng)的一條記錄。該記錄包含了視頻的附加信息以及子目錄,子目錄直接返回給視圖層,由視圖層來生成URL規(guī)則。其代碼如表8所示。
表8 查詢視頻
上述代碼提供了視頻切分的功能,而在調(diào)用該模塊之前,程序需要在指定的VOD目錄中自動生成子目錄,并將子當查詢成功并將數(shù)據(jù)返回給視圖層之后,視圖層負責生成獲取視頻的URL規(guī)則,其代碼如表9所示。
表9 URL 生成規(guī)則
通過視頻切分之后,在VOD直播目錄下會生成一系列子目錄,每一個子目錄代表了一個HLS視頻。此時VOD直播目錄尚不具備推送視頻流的能力,因此需要將Nginx配置為支持HLS協(xié)議點播的流媒體服務(wù)器。本文中Nginx使用的版本為nginx-1.19.10,其具體配置如表10所示。
表10 Nginx 流媒體服務(wù)器配置
現(xiàn)對電子科技大學知識產(chǎn)權(quán)信息服務(wù)中心網(wǎng)做實例分析。在管理員端,系統(tǒng)提供了視頻上傳與管理功能,其效果如圖5所示:
圖5 視頻上傳(左)與管理(右)
在管理員上傳視頻成功之后,會生成視頻切分請求,并存入隊列中;而視頻切分后臺程序會持續(xù)地從隊列中取出請求,對指定的視頻進行切分,其效果如圖6所示:
圖6 視頻切分
在用戶端,當點擊視頻鏈接后,鏈接中包含的ID值會定位到該條視頻記錄,取出記錄中的附加信息(如標題、瀏覽量等),同時取出子目錄(即UUID編號),并在視圖層中生成訪問視頻的URL,瀏覽器通過該URL拉取視頻流,其效果如圖7所示:
圖7 生成URL 及視頻播放
綜上所述,本文以電子科技大學知識產(chǎn)權(quán)信息服務(wù)中心為例,通過上傳視頻,利用JavaCV對視頻進行切分,搭建Nginx流媒體服務(wù)器,實現(xiàn)了構(gòu)建短視頻平臺。
然而上述方案也存在一定的缺陷。第一、視頻存儲為單一節(jié)點存儲,磁盤空間有限,缺少分布式視頻存儲方案,無法應(yīng)對大規(guī)模的視頻存儲需求。第二、視頻切分時,視頻參數(shù)與原視頻一致,缺少必要的視頻壓縮選項;視頻壓縮仍需要管理員自行處理,易用性不足。第三、當大量用戶同時觀看視頻時,由于缺少負載均衡機制,視頻服務(wù)器會有極高的處理壓力,這會導(dǎo)致視頻出現(xiàn)卡頓甚至拒絕請求。這些問題在后續(xù)的工作中需進一步深入分析和研究。