摘要:網(wǎng)絡(luò)電視,或稱在線電視,是利用互聯(lián)網(wǎng)上進(jìn)行電視直播,通常電視節(jié)目以WMV、ASF等流媒體的格式,現(xiàn)如今已成為我們網(wǎng)絡(luò)生活中不可缺少的一部分,它的技術(shù)與發(fā)展廣受人關(guān)注,而研究它,也是具有深遠(yuǎn)意義的。
該文介紹的是一個基于MFC和Windows Media Format 開發(fā)工具包而制作的網(wǎng)絡(luò)電視播放器。該播放器能具有友好的用戶界面,能播放網(wǎng)絡(luò)上的MMS實(shí)時流媒體,并能夠?qū)崿F(xiàn)流媒體的定時錄像,彌補(bǔ)了網(wǎng)絡(luò)上眾多網(wǎng)絡(luò)電視不能定時錄像的缺憾,它具有體積小,占有資源少,播放列表等特點(diǎn)。
該文首先介紹了如今網(wǎng)絡(luò)流媒體發(fā)展的背景,然后介紹WMP控件和WMF SDK的一些基本概念和實(shí)現(xiàn)的方法,最后介紹該程序的設(shè)計。
關(guān)鍵詞:網(wǎng)絡(luò)電視;流媒體;MMS;ASF;Window Media Format SDK
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2013)02-0386-03
隨著近幾年來網(wǎng)絡(luò)視頻的蓬勃發(fā)展,各種流媒體文件已經(jīng)被我們熟知,但潛藏在其背后的流媒體技術(shù)卻是更吸引人的所在。
流媒體技術(shù)包含三方面內(nèi)容,分別是編碼器(編碼技術(shù))、播放器(播放支持)和流服務(wù)器(媒體內(nèi)容發(fā)布),三者缺一不可。當(dāng)前市場上主流的流媒體技術(shù)有三種,分別是RealNetworks公司的RealMedia、Apple公司的QuickTime和Microsoft公司的Windows Media。
Windows Media是Microsoft公司開發(fā)的流媒體技術(shù)。以Windows Media 9 Series為例,整個系列由Windows Media Codec、Windows Media Encoder、Windows Media SDK等內(nèi)容組成。
其中,Windows Media SDK中的Windows Media Format SDK對ASF文件格式提供了支持。通過使用Windows Media 音視頻編解碼,實(shí)現(xiàn)對Windows Media媒體內(nèi)容的生成、讀取、編輯三大功能。
1 Windows 流媒體技術(shù)概述
Windows Media媒體內(nèi)容采用的是ASF文件格式。Microsoft公司提供了Windows Media Format SDK,以支持 ASF文件的生成(包括ASF數(shù)據(jù)的流化)、ASF文件的編輯和ASF文件的播放(包括ASF媒體流的播放)。
Windows Media Format SDK 采用面向?qū)ο笤O(shè)計,是一套完全基于COM組件模型的高級開發(fā)包。這里所謂的高級,是指SDK屏蔽了ASF數(shù)據(jù)格式、網(wǎng)絡(luò)傳輸控制等較為底層的流媒體技術(shù)實(shí)現(xiàn)細(xì)節(jié),留給開發(fā)者的只有比較上層的編程接口。
SDK引入了一系列對象,如生成器(Writer Object)、讀取器(Reader Object)、編輯器(Metadata Editor Object),等等,正是這些SDK對象屏蔽了Windows Media技術(shù)實(shí)現(xiàn)細(xì)節(jié),使得應(yīng)用程序開發(fā)者不需要了解太多的流媒體底層技術(shù),也能開發(fā)出非常專業(yè)的流媒體應(yīng)用系統(tǒng)。
1.1 MMS協(xié)議
MMS(Microsoft Media Server)是Microsoft公司自己擁有的流媒體協(xié)議。MMS協(xié)議實(shí)際上是一種應(yīng)用層協(xié)議,支持快進(jìn)、倒回、暫停、啟動和停止索引數(shù)字媒體文件等播放器控制操作。MMS協(xié)議有TCP和UDP兩種傳輸方式的實(shí)現(xiàn)——使用TCP傳輸?shù)姆Q為MMST協(xié)議,使用UDP傳輸?shù)姆Q為MMSU協(xié)議。MMS是一種串流媒體傳送協(xié)議,用來訪問并流式接收Windows Media服務(wù)器中.asf文件的一種協(xié)議。MMS協(xié)議用于訪問Windows Media發(fā)布點(diǎn)上的單播內(nèi)容。MMS是連接Windows Media單播服務(wù)的默認(rèn)方法。若觀眾在Windows Media Player中鍵入一個URL以連接內(nèi)容,而不是通過超級鏈接訪問內(nèi)容,則他們必須使用MMS協(xié)議引用該流。MMS的默認(rèn)端口是1755。
1.2 ASF文件
ASF是(Advanced Streaming Format 高級串流格式)的縮寫,是 Microsoft 為 Windows 98 所開發(fā)的串流多媒體文件格式。ASF是微軟公司W(wǎng)indows Media的核心。這是一種包含音頻、視頻、圖像以及控制命令腳本的數(shù)據(jù)格式。這個詞匯當(dāng)前可和 WMA 及 WMV 互換使用。
ASF是一個開放標(biāo)準(zhǔn),它能依靠多種協(xié)議在多種網(wǎng)絡(luò)環(huán)境下支持?jǐn)?shù)據(jù)的傳送。同JPG、MPG文件一樣,ASF文件也是一種文件類型,但它是專為在IP網(wǎng)上傳送有同步關(guān)系的多媒體數(shù)據(jù)而設(shè)計的,所以ASF格式的信息特別適合在IP網(wǎng)上傳輸。ASF文件的內(nèi)容既可以是我們熟悉的普通文件,也可以是一個由編碼設(shè)備實(shí)時生成的連續(xù)的數(shù)據(jù)流,所以ASF既可以傳送人們事先錄制好的節(jié)目,也可以傳送實(shí)時產(chǎn)生的節(jié)目。
ASF用于排列、組織、同步多媒體數(shù)據(jù)以利于通過網(wǎng)絡(luò)傳輸。ASF是一種數(shù)據(jù)格式,它也可用于指定實(shí)況演示。ASF最適于通過網(wǎng)絡(luò)發(fā)送多媒體流,也同樣適于在本地播放。任何壓縮/解壓縮運(yùn)算法則(編解碼器)都可用來編碼ASF流。
2 程序設(shè)計的基本思想
程序的播放界面可以調(diào)用Windows Media Player里面的WMP.dll控件進(jìn)行二次開發(fā),在此基礎(chǔ)上,將一些控制按鈕實(shí)現(xiàn)。
節(jié)目列表功能則要調(diào)用MFC基礎(chǔ)空間里面的LIST CONTROL完成。
而錄像功能稍微麻煩點(diǎn),不能直接通過控件完成,因此要研究Windows Media Format SDK里面的內(nèi)容,根據(jù)里面的內(nèi)容進(jìn)行二次開發(fā)。這樣,程序的播放與錄像功能是分離的,這樣做有一點(diǎn)好處,可以在播放的同時進(jìn)行錄像。
而錄像需要定時,還需要在程序里面加入若干的定時器,實(shí)現(xiàn)錄像功能的定時性。
3 程序?qū)崿F(xiàn)
3.1播放窗口實(shí)現(xiàn)
Windows Media Player控件是播放器的主窗口,它的添加很簡單,直接在窗體右鍵中選擇Insert ActiveX Control選定添加即可,但在之前只需要確定系統(tǒng)上裝有Windows Media Player的第九版以上的版本即可。
控件添加后,這時以CWMP開頭的17個類將被添加到工程:
這時ClassWizard會將控件與CWMPPlayer4類對象建立關(guān)聯(lián)。
CWMPPlayer4類提供了與Windows Media Player控件進(jìn)行交互的基本方法,而且部分成員函數(shù)還能夠進(jìn)一步獲取得到其他相關(guān)類對象的實(shí)例。其中,SetUrl()和close()方法將能夠打開和關(guān)閉指定的媒體文件。在打開文件之后,能夠通過控件上的自帶按鈕控制媒體的播放、暫停、停止以及對音量的控制等。如果需要在程序中控制媒體的播放,可使用GetControls()函數(shù)返回CWMPControls類對象,并進(jìn)一步調(diào)用該對象的play()、stop()、pause()等方法來完成播放、停止、暫停等相應(yīng)動作;如果需要在程序中對控件屬性進(jìn)行設(shè)置和更改,可在GetSettings()方法返回一個CWMPSettings類的對象后通過其成員函數(shù)來完成相應(yīng)的設(shè)置。
Windows Media Player控件的使用較為簡單,其功能的調(diào)用開發(fā)都比較智能化,在這里就不長篇幅介紹了。
3.2錄像功能實(shí)現(xiàn)
3.2.1類的組成
為此功能新建一類CWMDownload。其中的主要函數(shù)如下:
class CWMDownloader:public IWMReaderCallback, public IWMReaderCallbackAdvanced
為了與讀取器交互,應(yīng)用程序需要實(shí)現(xiàn)IWMReaderCallback、IWMReaderCallbackAdvanced兩個回調(diào)接口
其中入口函數(shù)是BOOL Start(CString& inSourceFile, CString& inTargetFile),代碼如下:
BOOL CWMDownloader::Start(CString& inSourceFile, CString& inTargetFile)
由此函數(shù)實(shí)現(xiàn)了整個程序執(zhí)行的流程,那便是:1) 創(chuàng)建讀取器;2) 獲得源文件的Profile;3) 創(chuàng)建生成器;3) 復(fù)制編碼信息、元屬性、腳本等內(nèi)容;4) 執(zhí)行讀取寫入;5) 探聽事件。
Start函數(shù)接收inSourceFile和inTargetFile兩個參數(shù),分別是CString格式的源文件路徑和保存文件的路徑。要將這兩個路徑轉(zhuǎn)換成寬字符串的形式,以供后面函數(shù)調(diào)用。如下:
MultiByteToWideChar(CP_ACP, 0, inSourceFile, -1, mSourceFile,MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, inTargetFile, -1,
mTargetFile, MAX_PATH);
3.2.2創(chuàng)建讀取器和生成器
CreateReader(void)函數(shù)調(diào)用WMCreateReader函數(shù)進(jìn)行創(chuàng)建,同樣,CreateWriter(void)函數(shù)調(diào)用WMCreateWriter函數(shù)進(jìn)行創(chuàng)建,指針保存在類成員
mIReader和mIWriter。
創(chuàng)建讀取器的同時,通過如下語句獲得IWMReaderAdvanced和IWMHeaderInfo的接口:
hr = mIReader→QueryInterface(IID_IWMReaderAdvanced, (void **)&mIReaderAdvanced);
hr = mIReader→QueryInterface(IID_IWMHeaderInfo, (void **)&mIReaderHeaderInfo);
IWMReaderAdvanced接口提供了讀取器更高級的控制功能,包括用戶提供時鐘、數(shù)據(jù)緩存分配、讀取器內(nèi)部統(tǒng)計信息返回、流選擇通知等。
IWMReaderAdvanced接口用于獲取ASF文件頭對象中的信息,包括元數(shù)據(jù)屬性、標(biāo)記、腳本命令等。
同樣的,創(chuàng)建生成器的時候也會獲得IWMWriterAdvanced和IWMHeaderInfo接口。
而接下來,生成器的創(chuàng)建需要配置Profile,但Profile哪兒來呢?當(dāng)然最簡便的做法便是使用源文件的Profile,GetProfileInfo()將源文件的Profile賦給類成員mIReaderProfile,創(chuàng)建生成器時通過mIWriter→SetProfile(mIReaderProfile)獲得讀取器的Profile。
最后,讀取器通過mIReader→Open(mSourceFile, this, NULL)這條語句獲得讀取地址,而生成器通過mIWriter→SetOutputFilename(mTargetFile)獲取生成地址。
3.2.3復(fù)制元數(shù)據(jù)屬性、編解碼器信息、腳本、標(biāo)記
元數(shù)據(jù)屬性和編解碼器信息在數(shù)據(jù)讀取過程開始之前,就可以從源文件復(fù)制到目標(biāo)文件,由CopyAttributes()和 CopyCodecInfo()兩個函數(shù)完成,具體內(nèi)容較為繁瑣,不詳細(xì)介紹。腳本比較特殊,因?yàn)樗梢杂袃煞N存在形式:在文件頭對象中,或作為一個腳本流。如果源文件的腳本存在于頭對象中,則也可以在數(shù)據(jù)讀取過程開始之前將其復(fù)制到目標(biāo)文件中,這部分由CopyScriptInHeader()函數(shù)完成。但如果是腳本流保存到目標(biāo)文件時,可以仍然是以腳本流的形式,也可以在數(shù)據(jù)讀取過程中將各腳本緩存起來,在數(shù)據(jù)讀取完畢之后再一起將它們寫入到文件頭對象中。標(biāo)記只能通過SDK的編輯器來復(fù)制。因此,標(biāo)記復(fù)制的時機(jī)是在數(shù)據(jù)讀取過程結(jié)束之后,此函數(shù)是CopyMarkers(),在類外部調(diào)用。
3.3定時功能的實(shí)現(xiàn)
要能定時錄像,除了錄像,還必須要定時。
MFC有DATA TIME PICKER這樣一個控件,可以直接讓用戶輸入開始時間和結(jié)束時間,在用與它綁定的CTime格式的成員進(jìn)行操作。CTime格式的時間能進(jìn)行比較大小等操作,很是方便。
在對話框拖入兩個DATA TIME PICKER控件,在ClassWizard中給兩控件設(shè)置變量m_startTime和m_stopTime,這樣,在用戶改變控件值的時候,用Updatedata(true)便能獲取CTime格式的時間。另外設(shè)置m_taskstarttime和m_taskstoptime作為保存的任務(wù)下載時間的變量。
時間取到了,再寫一個函數(shù)對用戶輸入合法性進(jìn)行判斷。
4 結(jié)束語
至此,一個包括定時錄像功能的流媒體播放器便可以搭建成功了。該播放器利用了Windows Media Formate的接口進(jìn)行二次開發(fā),能實(shí)時獲取MMS協(xié)議的流媒體進(jìn)行播放,還能進(jìn)行定時錄制視頻。
參考文獻(xiàn):
[1] 四維科技,劉袆瑋.VisualC++ 視頻/音頻開發(fā)實(shí)用工程案例精選[M].北京:人民郵電出版社,2005,5.
[2] 陸其明.DirectsShow實(shí)務(wù)精選[M].北京:科學(xué)出版社,2004,7.
[3] 陸其明.Windows Media 編程導(dǎo)向[M].北京:清華大學(xué)出版社,2006,12.
[4] 王亞琴,董彥榮,薄靜儀.流媒體傳輸協(xié)議及應(yīng)用[J].辦公自動化雜志,2009,12.