阿不都克里木·玉素甫,王亮亮
(1.新疆師范高等??茖W校(新疆教育學院)現(xiàn)代教育技術(shù)中心,新疆 烏魯木齊 830043;2.新疆教育云技術(shù)與資源實驗室,新疆 烏魯木齊 830043)
近年來隨著計算機多媒體技術(shù)的不斷發(fā)展,先后出現(xiàn)多種視頻格式,如:AVI、DV-AVI、MPEG、WMV、ASF、DivX、DAT(VCD)、VOB(DVD)、MOV、MKV等。由于這些視頻格式是由不同技術(shù)公司所制定或發(fā)明的,比如:AVI由微軟公司制定,MOV由Apple公司制定[1],因此視頻格式的技術(shù)標準或者說是視頻編碼[2]也有所不同,需要相應的解碼器才可以播放。一般為了將這些不同視頻源發(fā)布至Web中,首先需要將視頻源轉(zhuǎn)換為FLV或MP4等格式后上傳至服務器,再通過相應的Web嵌入播放器來播放視頻。視頻發(fā)布工作如果按照傳統(tǒng)的方法進行操作,需要3個步驟來完成:首先轉(zhuǎn)換視頻文件,然后上傳視頻,最后填寫相應的信息后發(fā)布視頻。這種傳統(tǒng)方法的過程還是非常繁瑣并且耗時的。
FFMPEG是一個免費、開源、跨平臺的軟件,且FFMPEG的開源項目已經(jīng)走過了十幾個年頭[1],有很多使用場景。其中較為典型的有播放器、媒體編輯器、轉(zhuǎn)碼器等,對音視頻編碼處理有著較好的支持,因此目前視頻處理相關(guān)的大部分研究[3-5]都是采用FFMPEG。本文研究與實現(xiàn)一種基于自主可控平臺技術(shù)的FFMPEG在線視頻轉(zhuǎn)換系統(tǒng)。本系統(tǒng)也采用FFMPEG對視頻進行轉(zhuǎn)換及壓縮等操作,但是程序中的調(diào)用方式有所不同,即直接以命令行的方式通過Java接口調(diào)用FFMPEG程序,并與上傳模塊、Socket服務模塊、注入關(guān)鍵幀模塊和視頻播放模塊有效地結(jié)合,實現(xiàn)各個模塊協(xié)同工作機制,達到一個步驟完成視頻文件的上傳、轉(zhuǎn)換、壓縮、注入關(guān)鍵幀等一系列操作的目的,為視頻轉(zhuǎn)換提供便利的同時減少了一定的工作量。
在線視頻轉(zhuǎn)換系統(tǒng)基于B/S架構(gòu)設計,即客戶端通過Web瀏覽器向服務器端傳輸視頻文件,與此同時服務器端接收上傳文件并做一系列相應的操作后,將轉(zhuǎn)換完成的目標視頻文件存儲至服務器。服務器端根據(jù)處理內(nèi)容主要分為3個部分:Tomcat服務器、Socket服務和Nginx服務器。其中Tomcat服務器負責視頻傳輸、存儲以及向Socket服務發(fā)送指令,Socket[6-8]服務主要處理視頻的轉(zhuǎn)換、壓縮以及注入關(guān)鍵幀等操作,而Nginx[9-12]服務器提供負載均衡功能和視頻資源的在線播放功能。系統(tǒng)總體框架如圖1所示。
圖1 系統(tǒng)框架圖
根據(jù)系統(tǒng)框架圖中服務器端的處理內(nèi)容,具體操作如下:
1)Tomcat服務器。
客戶端用戶通過Web瀏覽器上傳視頻源文件至服務器,這時服務器開始對用戶所傳輸?shù)囊曨l文件進行處理。首先Tomcat服務器上傳模塊開始將視頻文件存儲至指定的文件路徑,與此同時向客戶端返回進度數(shù)據(jù)并顯示上傳進度。客戶端上傳進度顯示為100%時,上傳模塊結(jié)束文件的上傳操作,并向Socket服務發(fā)送指令。
2)Socket服務。
系統(tǒng)將啟用Socket服務對視頻文件進行不同指令操作。Socket服務采用多線程技術(shù)[13-16],可以將多個文件根據(jù)上傳完成時間逐一放入消息隊列依次處理。這樣用戶就避免等待視頻轉(zhuǎn)換完畢后才上傳下一個視頻文件,也就是說客戶端用戶只需要下達指令,Socket服務將自動地進行線程處理,將視頻文件逐一放入消息隊列并轉(zhuǎn)換為目標視頻文件。具體操作是Socket服務接收上傳完畢指令后,根據(jù)用戶填寫的視頻信息啟動FFMPEG程序開始對文件進行轉(zhuǎn)換和壓縮操作。此時客戶端也會顯示視頻目前處理的狀態(tài),如:正在轉(zhuǎn)換視頻文件等。視頻轉(zhuǎn)換完畢后,Socket服務將啟動流媒體關(guān)鍵幀注入程序Yamdi,對視頻文件注入metadata信息。主要包括創(chuàng)建者、關(guān)鍵幀、視頻相關(guān)信息等。而其中最為有效的是關(guān)鍵幀,即注入完成后視頻可支持進度條的隨意拖動播放。整個視頻文件的轉(zhuǎn)換、壓縮以及注入關(guān)鍵幀操作完畢后,Socket服務將視頻文件存儲至指定的Nginx服務器視頻文件播放路徑,隨后刪除對應的原始視頻文件,并將視頻轉(zhuǎn)換狀態(tài)寫入數(shù)據(jù)庫。如果用戶上傳了多個文件,Socket服務將對線程中下一個視頻文件進行處理。處理完成后客戶端瀏覽器會顯示視頻轉(zhuǎn)換狀態(tài)為已轉(zhuǎn)換完畢。
3)Nginx服務器。
客戶端可以通過Web嵌入播放器對已轉(zhuǎn)換完畢的視頻進行播放。視頻播放采用Nginx服務器的負載均衡技術(shù)[17-21]且視頻文件已注入關(guān)鍵幀,因此可以在Web嵌入播放器中隨意拖動進度條到緩沖還未加載的位置進行播放。
服務器操作系統(tǒng):CentOS 6.6。
使用編程語言:Java,JavaScript,ActionScript。
使用視頻編碼工具:FFMPEG,Yamdi。
使用開發(fā)工具:Eclipse,Adobe Flash Builder。
系統(tǒng)框架:主要采用B/S架構(gòu)。
視頻上傳模塊分為客戶端模塊和服務器端模塊這2個子模塊??蛻舳四K主要功能是上傳視頻文件以及顯示進度條等,主要基于RIA技術(shù)[22]開發(fā)并支持動態(tài)數(shù)據(jù)顯示,客戶端上傳模塊的實現(xiàn)界面如圖2所示。
圖2 視頻上傳客戶端模塊
服務器端模塊的主要功能是視頻文件數(shù)據(jù)的接收以及返回進度數(shù)據(jù)。當通過客戶端Web瀏覽器將視頻文件上傳至服務器時會啟用FileUploadServlet監(jiān)聽類,并開始對視頻進行上傳操作。即首先讀取配置文件和獲取客戶端相關(guān)參數(shù),包括:路徑、文件名、文件數(shù)據(jù)等信息,再對文件進行傳輸操作。與此同時通過ServletFileUpload類的setProgressListener方法將上傳進度數(shù)據(jù)實時返回至客戶端,傳輸完畢后將信息寫入數(shù)據(jù)庫。服務器端上傳模塊核心代碼如下:
try {uploadedItems= upload.parseRequest(request);
Iterator i=uploadedItems.iterator();
while(i.hasNext())
{fileItem=(FileItem) i.next();
if(fileItem.isFormField()==false){
if(fileItem.getSize()>0){
File uploadedFile=null;
String myFullFileName=fileItem.getName();
slashType=(myFullFileName.lastIndexOf("\")>0)?"
\":"/";
int startIndex=myFullFileName.lastIndexOf(slashType);
myFileName=myFullFileName.substring(startIndex+1,
myFullFileName.length());//獲取文件名
uploadedFile=new File(filePath,myFileName);
System.out.println(filePath+"/"+myFileName;
fileItem.write(uploadedFile);//文件寫入
insert_database(myFileName,filePath,name1,name2);
//寫入數(shù)據(jù)庫}
}}} catch (FileUploadException e){
e.printStackTrace();}
Socket服務負責視頻的轉(zhuǎn)換、壓縮和注入關(guān)鍵幀等操作。主要采用Java Socket技術(shù)和多線程技術(shù),實現(xiàn)了隊列管理和防阻塞機制,以此避免系統(tǒng)資源消耗過高出現(xiàn)異常等問題。Socket服務模塊主要操作包括:啟動多線程、調(diào)用FFMPEG進行視頻轉(zhuǎn)換和壓縮、注入關(guān)鍵幀、存儲轉(zhuǎn)換文件、刪除源文件、數(shù)據(jù)庫寫入等。
3.3.1 FFMPEG
FFMPEG[23-24]是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計算機程序。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案,包含了先進的音頻、視頻編解碼庫libavcodec,并且可以支持多種視頻格式的相互編碼轉(zhuǎn)換,主要有:AVI、MPEG、MOV、3GP、M4A、RMVB、RM、MP4等。除了視頻轉(zhuǎn)換功能以外還可支持視頻壓縮、視頻抓圖和對視頻進行加水印操作等。因此本文主要采用FFMEPEG對視頻進行轉(zhuǎn)換、壓縮以及抓圖等操作。
3.3.2 FFMPEG安裝
為通過FFMPEG程序?qū)σ曨l進行轉(zhuǎn)換和壓縮操作,在CentOS中安裝了FFMPEG以及一些相關(guān)視頻音頻解碼插件[25-26]。FFMPEG在轉(zhuǎn)換或者播放的過程中也需要調(diào)用相關(guān)解碼插件才可進行操作。已安裝解碼器包括:libfdk_aac、libfreetype、libmp3lame、libopus、libvorbis、libvpx、libx264、libx265等。
具體FFMPEG安裝方法如下:
sudo rpm --import RPM-GPG-KEY-nux.ro
sudo rpm -Uvh nux-dextop-release-0-5.el7.nux
sudo yum install ffmpegffmpeg-devel -y
3.3.3 調(diào)用FFMPEG
Socket服務將通過調(diào)用FFMPEG程序?qū)σ曨l進行轉(zhuǎn)換和壓縮操作。但本文沒有調(diào)用FFMPEG的C語言類庫,而是直接通過Java的Process類調(diào)用預裝好的FFMPEG程序,此方法方便簡單并且可通過Java的多線程實時監(jiān)聽轉(zhuǎn)換進度。具體調(diào)用代碼如下:
Runtimert=Runtime.getRuntime();
Processproc=rt.exec("ffmpeg -y -i"+ filename+VideoCode_Parameter+upload_path+addpath+"/"+flvname1+"."+FileFormat); //轉(zhuǎn)換命令
InputStream stderr=proc.getErrorStream();
InputStreamReader isr=new InputStreamReader(stderr);
BufferedReader br=new BufferedReader(isr);
String line1=null;
while((line1=br.readLine())!=null)
{System.out.println(line1);}//顯示轉(zhuǎn)換進度
intexitVal=proc.waitFor();
System.out.println("exitVal"+exitVal);
yamdi(upload_path+addpath+"/"+flvname1,flvname2,addpath,ID,filename);//注入關(guān)鍵幀
轉(zhuǎn)換進度如圖3所示。
圖3 FFMPEG視頻轉(zhuǎn)換以及壓縮
視頻播放模塊為一個獨立的模塊,主要采用專用Web嵌入視頻播放器,并結(jié)合Nginx服務器的負載均衡技術(shù),實現(xiàn)視頻的在線播放和進度條的隨意拖動。
為了測試并了解在線視頻轉(zhuǎn)換系統(tǒng)功能和性能,本文做了一個實驗,即對系統(tǒng)核心模塊進行單元測試,具體單元測試內(nèi)容和結(jié)果如表1所示。
表1 系統(tǒng)單元測試
功能模塊測試內(nèi)容測試結(jié)果視頻上傳模塊是否支持批量上傳支持批量上傳是否支持大容量文件上傳系統(tǒng)支持在線上傳4 GB以下視頻文件上傳用時測試經(jīng)過測試上傳用時合理Socket服務模塊是否開啟多線程開啟多線程是否調(diào)用FFMPEG進行轉(zhuǎn)換調(diào)用FFMPEG進行轉(zhuǎn)換是否調(diào)用Yamdi對視頻注入關(guān)鍵幀調(diào)用Yamdi對視頻注入關(guān)鍵幀視頻轉(zhuǎn)換模塊是否支持不同格式視頻文件的轉(zhuǎn)換支持AVI、MPEG、MOV、3GP、M4A、RMVB、RM、MP4、AVI、MKV、WMV等是否支持大容量文件轉(zhuǎn)換支持大容量文件的轉(zhuǎn)換轉(zhuǎn)換用時測試多文件轉(zhuǎn)換時用時較長視頻播放模塊是否支持在線播放支持在線播放是否支持進度條的隨意拖動播放支持進度條的隨意拖動播放
作為自主可控平臺技術(shù)研究的一部分,為嵌入式平臺提供在線視頻格式轉(zhuǎn)換服務和視頻編碼處理環(huán)境,本文研究與實現(xiàn)了一種基于自主可控平臺的FFMPEG在線視頻轉(zhuǎn)換系統(tǒng)。首先介紹了系統(tǒng)設計所采用的框架以及開發(fā)環(huán)境等;然后介紹了在線視頻轉(zhuǎn)換系統(tǒng)核心模塊的實現(xiàn),主要包括:視頻上傳模塊,Socket服務模塊,視頻轉(zhuǎn)換、壓縮、注入關(guān)鍵幀模塊和視頻播放模塊等;最后做了系統(tǒng)單元測試,對系統(tǒng)核心功能模塊和性能進行了測試。結(jié)果表明該系統(tǒng)支持批量上傳、轉(zhuǎn)換、壓縮大容量視頻文件,可支持不同視頻文件格式的轉(zhuǎn)換,并且客戶端支持視頻進度條的隨意拖動播放。性能方面系統(tǒng)采用Socket隊列管理和多線程防阻塞技術(shù),因此在經(jīng)過多次反復測試過程中CPU、內(nèi)存占用率合理,沒有出現(xiàn)系統(tǒng)異常。但對于多個文件轉(zhuǎn)換、壓縮用時較長等問題,主要取決于視頻文件總時長,因此在后續(xù)的研究中將通過多臺服務器做一個整體的負載均衡,將文件上傳至不同服務器并通過Socket消息隊列中的任務進行轉(zhuǎn)換和壓縮操作。通過這種技術(shù)方案就可以解決測試中遇到的多個文件轉(zhuǎn)換用時較長等問題。