石昊蘇,董歡,張曼
(西北政法大學(xué)商學(xué)院,陜西西安710063)
隨著計算機(jī)多媒體技術(shù)和網(wǎng)絡(luò)技術(shù)的飛速發(fā)展,“嵌入式”已經(jīng)成為計算機(jī)領(lǐng)域諸多研究者密切關(guān)注的學(xué)術(shù)方向,在支持嵌入式硬件平臺的主流操作系統(tǒng)中,Linux因出于自身的優(yōu)越而成為嵌入式開發(fā)的最佳選擇[1-2]。同時越來越多的用戶對多媒體播放器也提出更高的要求,由最初的支持更多類型的音頻、視頻,即實現(xiàn)“能”播放,到對音質(zhì)保真、畫面清晰,再到對播放器本身系統(tǒng)資源占用、加載啟動速度的追求等,使得多媒體播放器的設(shè)計者必需不斷改進(jìn)完善、追求完美。當(dāng)前網(wǎng)絡(luò)可供下載的多媒體播放器軟件品種繁多、功能齊全,但是普遍性存在捆綁插件、加載速度慢等不足,甚或界面使用不便。因此在嵌入式Linux系統(tǒng)上開發(fā)一款克服上述缺點的多媒體播放器已經(jīng)成為必需,不僅滿足基本視聽需要,而且功能實用、操作方便、加載速度快、占用資源少、移植性強等[3-4],這應(yīng)該具有很好的應(yīng)用前景及價值。
Linux下多媒體播放器的整體工作流程:用戶通過圖形界面控制,添加媒體文件(音頻或視頻)到播放列表,軟件自動關(guān)聯(lián)媒體源(媒體文件)與媒體對象,然后建立媒體對象和音頻匯點(虛擬渲染設(shè)備)/視頻匯點的連接。開始播放后,匯點將音頻和視頻分流處理到系統(tǒng)后端解碼插件,解碼處理后,Phonon的后端對音頻和視頻進(jìn)行同步處理。最終,音頻通過連接在計算機(jī)的默認(rèn)聲卡輸出,視頻畫面渲染到播放器界面對應(yīng)部件上。這樣,就完成了一個媒體文件從加載到完成播放的整個流程[5-8]。
多媒體播放器中,用戶可以添加一個或多個媒體文件到播放列表。程序?qū)λ斜惶砑拥奈募闅v處理,檢查每個文件的合法性,然后將所有的有效媒體源保存在一個媒體源隊列中,并顯示在播放器列表中。添加成功后,用戶可以選擇對播放列表中的某個媒體文件進(jìn)行播放、暫停、停止、上一個、下一個、音量調(diào)節(jié)、拖動進(jìn)度條播放等基本播放控制[9]。
音頻文件在開始播放時,媒體解析器自動在媒體文件同級目錄下加載字幕文件,解析后保存到內(nèi)存中[10]。中央屏幕的字幕是固定顯示的,用戶可以選擇是否顯示桌面字幕。多媒體播放器的音頻播放功能模塊如圖2所示。
圖2 音頻播放功能模塊
針對視頻媒體,可以調(diào)整視頻畫面的寬高比以及視頻畫面的色彩模式(色調(diào)、對比度、亮度等),可以全屏播放,支持屏幕截圖。
視頻播放功能模塊如圖3所示。
圖3 視頻播放功能模塊
Phonon多媒體框架從本地讀入媒體源,傳輸至后端插件解碼,最后輸出到聲卡和負(fù)責(zé)渲染視頻畫面的部件。從邏輯上來說,它可以分為4部分:在Phonon庫支持下編寫的應(yīng)用程序、Phonon庫(由邏輯路徑相連接的媒體對象和匯點)、Phonon的后端插件、系統(tǒng)的后端插件[11-12]。
Phonon的API被前臺程序所調(diào)用,它不需要知道自己輸入的媒體流由哪套程序去解碼,最后在哪個設(shè)備上去播放。它只需要將對媒體流的指定操作發(fā)送給后端,最后由后端實現(xiàn)并回饋給Phonon,從而實現(xiàn)目的。因此,實現(xiàn)多媒體播放,Phonon后端和系統(tǒng)的解碼后端二者缺一不可。Phonon后端的準(zhǔn)備:編譯QT庫中的的phonon庫文件生成后端鏈接庫文件,復(fù)制到開發(fā)路徑調(diào)用。系統(tǒng)后端的準(zhǔn)備:Linux下安裝phonon-backend-gstreamer,采用GStreamer作為系統(tǒng)后端。
多媒體播放器的主界面包括窗口圖標(biāo)、菜單欄、PushButton按鈕、Widget部件 QListWidget列表、進(jìn)度條等。使用水平布局管理器和垂直布局管理器,以便在編寫代碼時對界面上每個部件進(jìn)行固定的布局管理,自動控制部件的大小變化。在顯示/隱藏播放列表、全屏播放等操作中,對每個部件的大小位置進(jìn)行整體調(diào)整,以適應(yīng)界面的美觀性和體驗感[13]。
在多媒體播放器的主界面類MPlayer中,實例化了一個ui類的堆對象,主界面所有部件的圖標(biāo)、大小、信號關(guān)聯(lián)、styleSheet等屬性都在代碼中通過這個指針去訪問對應(yīng)部件進(jìn)行控制。
播放進(jìn)度條部件通過Phonon::SeekSlider::setMediaObject()函數(shù)初始化,關(guān)聯(lián)到專門用于播放的Phonon::MediaObject媒體對象中,使得可以通過該滑塊來對媒體對象進(jìn)行控制。媒體對象在播放過程中,也會通過向滑塊發(fā)射信號達(dá)到同步顯示的效果。在每個媒體源播放即將結(jié)束時,Phonon會自動發(fā)射結(jié)束信號,滑塊通過Phonon::MediaObject::seek()函數(shù),將顯示值設(shè)置為當(dāng)前媒體的總時間。
聲音控制滑塊通過Phonon::VolumeSlider::setAutioOutput()函數(shù)與音頻輸出節(jié)點Phonon::AudioOutput相關(guān)聯(lián),通過移動滑塊對音頻輸入對象進(jìn)行控制,從而實現(xiàn)了音量高低的調(diào)整。滑塊值每次發(fā)生變化時,會發(fā)射volumeChanged信號,信號參數(shù)中攜帶了變化后的值。通過關(guān)聯(lián)這個信號,在對應(yīng)的槽中設(shè)置每次音量變化時,實時在播放界面用QLabel部件顯示出當(dāng)前音量的百分比值。
多媒體播放器實現(xiàn)播放媒體文件,需要創(chuàng)建Phonon媒體流圖來實現(xiàn)。本地媒體文件的源數(shù)據(jù)是一個媒體源,Phonon中有一個MediaObjects類用來實現(xiàn)媒體對象。媒體源要實現(xiàn)播放,需要和專門負(fù)責(zé)播放任務(wù)的媒體對象綁定在一起。匯點相當(dāng)于Phonon中的一個虛擬節(jié)點,它的功能是從媒體對象獲取媒體流數(shù)據(jù),通過后端解碼、同步處理后,輸送到聲卡或者視頻渲染部件中。創(chuàng)建一個媒體流圖,就是分別創(chuàng)建媒體對象和匯點(音頻匯點和視頻匯點)的實例,通過Phonon::createPath()函數(shù)創(chuàng)建一條虛擬的路徑,將二者連接起來[3,12]。
圖4 視頻媒體流圖
音頻媒體流相對來說比較簡單,只需要建立媒體對象和音頻匯點之間的一條路徑。后端對媒體流解析后由音頻節(jié)點直接輸送到系統(tǒng)的默認(rèn)音頻設(shè)備,即聲卡中實現(xiàn)聲音播放。而視頻媒體流需要建立兩條虛擬路徑,如圖4所示,分別是媒體對象和音頻匯點的連接和媒體對象和視頻匯點的連接。前者與音頻媒體流圖的處理原理完全一致,后者通過解碼、處理后的視頻畫面通過Phonon::VideoWidget類的部件對象在主界面上進(jìn)行渲染。因為VideoWidget類是繼承自QT的Widget部件類,它可以像普通的Widget部件一樣,設(shè)置大小、背景等屬性。
播放器的播放列表主要實現(xiàn)文件添加、從播放列表刪除、清空播放列表、從播放列表控制播放、循環(huán)模式等功能。
為了降低系統(tǒng)模塊之間的耦合性,播放列表采用單獨的類(PlayerList)進(jìn)行設(shè)計,該類繼承自QListWidget部件類。QListWidget中的數(shù)據(jù)采用列表的數(shù)據(jù)結(jié)構(gòu)保存條目的索引和數(shù)據(jù)(字符串)。為了方便顯示,在播放列表類中,設(shè)置了條目的內(nèi)容或數(shù)量超出控件的默認(rèn)長度時,自動使用水平和垂直滾動條。播放列表中的所有功能通過關(guān)聯(lián)部件的customContextMenuRequested(const QPoint&)信號,創(chuàng)建上下文菜單實現(xiàn)[14-15]。
添加文件:將文件打開對話框中選擇的媒體源路徑保存在字符串列表中。對這個字符串列表進(jìn)行解析,為每個媒體文件創(chuàng)建媒體源,保存到媒體源列表中。解析每個媒體源的合法性,使用媒體對象的metaData()、totalTime()函數(shù)獲取媒體源的文件名和總時長,作為播放列表的條目值。只有將前一個媒體源加入播放列表后,才開始后一個媒體文件的解析。通過這樣的加載方式,媒體源列表和播放列表相互對應(yīng),方便后續(xù)播放處理。
從播放列表刪除:要刪除的媒體是在播放列表中被選中的條目,currentRow()函數(shù)可以獲取正在選中條目的索引值,它和對應(yīng)媒體源在媒體源列表中的索引值完全一致。文件加入播放列表后,刪除前不會對兩個列表中的數(shù)據(jù)進(jìn)行任何操作。通過QListWidget::takeItem()和 QList::removeAt()函數(shù)分別將對應(yīng)媒體從播放列表和媒體源列表中刪除。QT中的列表結(jié)構(gòu)會在刪除某節(jié)點后,動態(tài)地調(diào)整后續(xù)節(jié)點。刪除成功后,如果播放列表沒有被清空,優(yōu)先設(shè)置后一個媒體源為當(dāng)期媒體源。
清空播放列表:由于播放列表和媒體源列表之間的同步管理關(guān)系,在清空播放列表時,需要使用兩個對象的clear()函數(shù)同時清空兩個列表。停止當(dāng)前正在播放/暫停的媒體,斷開媒體對象和所有媒體源的連接。
循環(huán)模式:利用全局的枚舉對象,保存順序播放、列表循環(huán)、隨機(jī)播放、單個播放、單個循環(huán)模式狀態(tài)。設(shè)計一個播放模式控制函數(shù)playerMode(),判斷當(dāng)前設(shè)置的模式(默認(rèn)為順序播放)。在與媒體對象結(jié)束信號相關(guān)聯(lián)的槽函數(shù)中,設(shè)置當(dāng)前模式下的下一個媒體源為當(dāng)前媒體源,開始播放。
多媒體播放器的字幕顯示,是針對于播放MP3類的音樂文件時,匹配本地下載好的歌詞文件,進(jìn)行解析處理。在播放過程中,根據(jù)播放時間動態(tài)地顯示出對應(yīng)字幕內(nèi)容。多媒體播放器的字幕實現(xiàn)主要分為3個模塊:字幕文件解析、桌面字幕顯示、播放器界面中央字幕顯示。
字幕文件解析。目前常用歌曲字幕文件是LRC格式的文本文件,字幕文件內(nèi)容主要分為兩種類型。一種是文件主要標(biāo)識,包括歌曲名、歌手名等信息。另一種是歌曲的歌詞,是時間(分:秒:毫秒)和歌詞的數(shù)據(jù)對。按照這樣的規(guī)律,對LRC格式的字幕文件的解析,只需要用一個合適的數(shù)據(jù)結(jié)構(gòu)來保存(時間,字幕內(nèi)容)數(shù)據(jù)對,而且時間不可重復(fù)[16]。
設(shè)計字幕解析函數(shù)myResolve(const QString&),在每次音頻媒體文件開始播放時,獲取播放媒體文件路徑,調(diào)用解析函數(shù)。因為字幕文件和媒體文件的文件名相同,所以首先將文件路徑的后綴修改為lrc后,開始尋找指定字幕文件。找到字幕文件后,使用QFile和QStringlist對象讀出文件所有內(nèi)容過后,按行進(jìn)行解析。
使用設(shè)置更新播放時間的槽函數(shù)中來完成對QMap
播放器界面中央字幕顯示。中央字幕顯示在播放器顯示視頻畫面的部件位置上層,在這個部件上層覆蓋一個QListWidget部件,控制該部件條目數(shù)量為十個。在解析字幕完成時,一次性從QMap
圖5 播放主界面中央字幕顯示
圖6 視頻畫面色彩調(diào)節(jié)后效果圖
經(jīng)實驗測試(如圖5、6所示),該播放器可播放當(dāng)前絕大多數(shù)的主流多媒體文件類型,基本功能均已實現(xiàn)達(dá)到預(yù)期的目的。該設(shè)計具有存儲空間小,速度快,功能簡單,移植性良好等特點,可以供媒體播放器開發(fā)設(shè)計者的參考。不足之處暫時沒有添加WiFi功能模塊,這將在進(jìn)一步解碼器優(yōu)化、支持高清視頻H.264的播放時一并改進(jìn)。
參考文獻(xiàn):
[1]武穎.基于Linux的嵌入式多媒體播放器的設(shè)計與實現(xiàn)[D].太原:中北大學(xué),2013.
[2]趙宏,尹磊,曹潔,等.多媒體終端的設(shè)計與實現(xiàn)[J].科學(xué)技術(shù)與工程,2010,10(22):5420-5424.
[3]馬曉敏.多媒體播放器的設(shè)計與開發(fā)[J].電子世界,2013,37(18):126.
[4]王洪斌.基于嵌入式Linux的多媒體系統(tǒng)研究與設(shè)計[D].哈爾濱:哈爾濱理工大學(xué),2016.
[5]鄭戊午,徐煒強.基于Xscale的掌上多媒體播放器設(shè)計[J].電子技術(shù),2016,45(3):87-89.
[6]楊博,李可生,何書專,等.基于i.MX6的LED異步控制系統(tǒng)軟件設(shè)計[J].計算機(jī)工程與設(shè)計,2016,37(6):1478-1484.
[7]胡國強,周兆永,信朝霞.基于SRS的開源直播系統(tǒng)的設(shè)計與實現(xiàn)[J].現(xiàn)代電子技術(shù),2016,39(16):36-39.
[8]李毅航.流程圖化的嵌入式系統(tǒng)開發(fā)平臺[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2017(2):15-17.
[9]潘文睿.基于Android系統(tǒng)多媒體播放器的設(shè)計與實現(xiàn)[D].西安:西北大學(xué),2014.
[10]李飛,吳鴻江.河南電視臺新數(shù)字播出系統(tǒng)亮點解析[J].廣播與電視技術(shù),2013,40(7):71-72..
[11]朱兆祺,李強,袁晉蓉.嵌入式Linux開發(fā)實用教程[M].北京:人民郵電出版社,2014.
[12]溪利亞,程殊,王侶為.基于Phonon的多媒體播放器的設(shè)計與實現(xiàn)[J].科學(xué)技術(shù)與工程,2011,11(29):7283-7285.
[13]張增虎.基于Qt的嵌入式多媒體播放終端的設(shè)計與實現(xiàn)[D].太原:中北大學(xué),2014.
[14]孫熠,史劍,安輝耀,等.一種輕型高效的多媒體播放列表解決方案[J].計算機(jī)技術(shù)與發(fā)展,2014(3):1-5.
[15]張正政,林耀榮.基于Android系統(tǒng)的影音播放器開發(fā)[J].現(xiàn)代電子技術(shù),2011,34(2):5-8.
[16]肖夢華,劉新,葉德建.一種基于嵌入式流媒體視頻播放器的多字幕組件設(shè)計[J].計算機(jī)應(yīng)用與軟件,2014(3):139-141.