摘要:Delphi被稱(chēng)為第四代編程語(yǔ)言,它具有簡(jiǎn)單、高效、功能強(qiáng)大的特點(diǎn)。和VC、VC++等編程語(yǔ)言相比,Delphi更簡(jiǎn)單、更易于掌握,而在功能上卻絲毫不遜色,集成了多種語(yǔ)言的特點(diǎn),可以開(kāi)發(fā)出靈活強(qiáng)大的程序。在各種聊天程序、聊天室中,常常用到網(wǎng)絡(luò)視頻技術(shù),開(kāi)發(fā)網(wǎng)絡(luò)視頻程序的工具有很多,Delphi是很多程序員喜愛(ài)的一種。本文就筆者開(kāi)發(fā)的基于Delphi的網(wǎng)絡(luò)視頻編程進(jìn)行分析闡述,并給出部分Delphi的相關(guān)代碼。
關(guān)鍵詞:Delphi;網(wǎng)絡(luò)視頻;編程
中圖分類(lèi)號(hào):TP311文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2009)14-3619-02
1 引言
在各種聊天程序、聊天室中,常常用到網(wǎng)絡(luò)視頻技術(shù)。Delphi具有強(qiáng)大的功能,也可以用Delphi來(lái)開(kāi)發(fā)網(wǎng)絡(luò)視頻。本文就筆者開(kāi)發(fā)的基于Delphi的網(wǎng)絡(luò)視頻編程進(jìn)行分析闡述,并給出部分Delphi的相關(guān)代碼。
2 視頻捕獲
視頻捕獲,可以使用微軟提供的專(zhuān)門(mén)用于視頻捕獲的VFW(Video for Windows)SDK。VFW SDK為在Windows系統(tǒng)中實(shí)現(xiàn)視頻捕獲提供了標(biāo)準(zhǔn)的接口,從而大大方便了程序員的設(shè)計(jì)開(kāi)發(fā)。
VFW是微軟公司推出的關(guān)于數(shù)字視頻的一個(gè)軟件包,它能使應(yīng)用程序通過(guò)數(shù)字化設(shè)備從傳統(tǒng)的模擬視頻源得到數(shù)字化的視頻剪輯。VFW的一個(gè)關(guān)鍵思想是播放時(shí)不需要專(zhuān)用硬件,為了解決數(shù)字視頻數(shù)據(jù)量大的問(wèn)題,需要對(duì)數(shù)據(jù)進(jìn)行壓縮。VFW使程序員能通過(guò)發(fā)送消息或設(shè)置屬性來(lái)捕獲、播放和編輯視頻剪輯。
VFW主要由以下6個(gè)模塊組成:① AVICAP.DLL:包含了執(zhí)行視頻捕獲的函數(shù),它給AVI文件I/O和視頻、音頻設(shè)備驅(qū)動(dòng)程序提供一個(gè)高級(jí)接口;② MSVIDEO.DLL:包含一套特殊的DrawDib函數(shù),用來(lái)處理屏幕上的視頻操作;③ MCIAVI.DRV:包括對(duì)VFW 的MCI命令解釋器的驅(qū)動(dòng)程序;④AVIFILE.DLL:包含由標(biāo)準(zhǔn)多媒體I/O(MMIO)函數(shù)提供的更高的命令,用來(lái)訪(fǎng)問(wèn).AVI文件;⑤壓縮管理器(ICM):用于管理的視頻壓縮/解壓縮的編譯碼器(CodeC);⑥ 音頻壓縮管理器ACM:提供與ICM相似的服務(wù),適用于波形音頻。
AVICAP為應(yīng)用程序提供了一個(gè)簡(jiǎn)單的、基于消息的接口,使之能訪(fǎng)問(wèn)視頻和波形音頻硬件,并能在將視頻流捕獲到硬盤(pán)上的過(guò)程中進(jìn)行控制。AVICAP支持實(shí)時(shí)的視頻流捕獲和圖像捕獲并提供對(duì)視頻源的控制。AVICAP在捕獲視頻方面具有一定的優(yōu)勢(shì),它能直接訪(fǎng)問(wèn)視頻緩沖區(qū),不需要生成中間文件,實(shí)時(shí)性很強(qiáng),效率很高。同時(shí),它也可將數(shù)字視頻捕獲到文件。
利用AVICAP進(jìn)行視頻捕獲的開(kāi)發(fā)步驟有:① 創(chuàng)建“捕獲窗”;② 關(guān)聯(lián)捕獲窗和驅(qū)動(dòng)程序;③ 設(shè)置視頻設(shè)備的屬性;④ 打開(kāi)預(yù)覽。
通過(guò)以上4步就可以建立一個(gè)基本的視頻捕獲程序。下面介紹實(shí)現(xiàn)基于Delphi的視頻捕獲。
使用微軟的AVICAP32.DLL實(shí)現(xiàn)對(duì)視頻攝像頭控制:
1) 打開(kāi)Delphi,新建一個(gè)工程,并新建一個(gè)窗口。先定義一個(gè)函數(shù)和部分常量(定義成全局類(lèi)型)。
const WM_AP_START=WM_USER;
const DRIVER_CONNECT=WM_CAP_START+10
const SET_PREVIEW=WM_CAP_START+50
const SET_CALLBACK_VIDE05TREAM=WM_CAP_START+6;
const SET_SCALE=WM_ CAP_TART+53;
const SET_PREVIEWRATE=WM_CAP_START+52
const DRIVER_DISCONNECT=WM_CAP_START+11;
function capCreateCaptureWindowA(1pszWindowName:PCHAR;
dwStyleaongint;x:integer;y:integer;nWidth:integer;
nHeight:integer;ParentWin:HWND;nId:integer):HWND;
STDCALL EXTERNAL 'AVICAP32.DLL'
2) 在窗口上放置一個(gè)Panel,添加2個(gè)按鈕,Caption設(shè)置為“開(kāi)始”和“停止”,并定義一個(gè)全局變量,var CWin2:THandle;//定義捕捉窗句柄。
“開(kāi)始”按鈕代碼如下:
CWin2: =capCreateCapture WindowA('My CAPWin', WS_CHILD or WS_VISIBLE,
Panell.Left, Panell.Top, Panell.Width, Panell.Height,F(xiàn)orm 1. Handle, 0 )
//上面代碼創(chuàng)建“捕獲窗”
if CWin2<>0 then
begin
SendMessage ( CWin2 , SET_CALLBACK_VIDEOSTREAM,0, 0);
SendMessage (CWin2,DRIVER_CONNECT,O,0);
//上面代碼關(guān)聯(lián)捕獲窗和驅(qū)動(dòng)程序
SendMessage(CWin2,SET SCALE,1,0)
SendMessage (CWin2,SET_PREVIEWRATE,66,0);
//上面代碼Scale , Rate設(shè)置預(yù)覽的比例與速度
SendMessage(CWin2,SET_PREVIEW,1,0);
//上面代碼打開(kāi)預(yù)覽
end;
運(yùn)行Delphi,這時(shí)就可以在屏幕上看到來(lái)自攝像頭的圖像了。
“停止”按鈕代碼如下:
if Cwin2<>0 then begin
SendMessage(CWin2, DRIVER_DISCONNECT,0,0);
CWin2:= 0;
end;
3 對(duì)捕獲的視頻進(jìn)行壓縮與解壓
通過(guò)AVICap窗口捕獲的每一幀的數(shù)據(jù)是以BMP (RAW)文件格式存放的,若直接進(jìn)行傳輸,數(shù)據(jù)量非常大,對(duì)網(wǎng)絡(luò)的帶寬要求非常高,因此在傳輸之前必須對(duì)每一幀的數(shù)據(jù)進(jìn)行壓
縮處理后再進(jìn)行傳輸。具體步驟:
第一步,安裝視頻壓縮引擎。媒體播放器軟件都帶有壓縮引擎,也可以從網(wǎng)上下載單獨(dú)的解壓縮引擎,比如MPEG4或DIVX等。
第二步,初始化壓縮引擎。選擇壓縮引擎,獲得壓縮引擎的支持,確定輸人、輸出格式,設(shè)置壓縮器。
第三步,壓縮幀數(shù)據(jù)。通過(guò)指定的壓縮引擎,對(duì)獲取的每一幀數(shù)據(jù)進(jìn)行壓縮。
解壓的過(guò)程與壓縮的過(guò)程類(lèi)似,通過(guò)選擇相對(duì)應(yīng)的解壓引擎,將壓縮的數(shù)據(jù)解壓,以便于回放。
4 視頻數(shù)據(jù)傳輸
4.1 基本概念
計(jì)算機(jī)在傳輸數(shù)據(jù)時(shí)有兩種方式:分別是TCP(Transmission Control Protocol,傳輸控制協(xié)議)及UDP(User Datagram Protocol,用戶(hù)數(shù)據(jù)報(bào)協(xié)議),兩者分別因數(shù)據(jù)傳輸?shù)牟煌?qǐng)求而提供不同的數(shù)據(jù)傳輸方式。
1) TCP協(xié)議
TCP是一個(gè)基于連接的通信協(xié)議,主要目的是提供大量數(shù)據(jù)傳輸并確保其傳輸無(wú)誤,因此提供錯(cuò)誤檢查、數(shù)據(jù)復(fù)原及數(shù)據(jù)重傳等機(jī)制。TCP在傳輸數(shù)據(jù)之前,會(huì)先在主機(jī)間(例如主控端與被控端)創(chuàng)建連接。根據(jù)此連接,數(shù)據(jù)可在計(jì)算機(jī)間相互傳輸,即所謂的雙向傳輸模式。
2) UDP協(xié)議
UDP是一個(gè)非連接式的通信協(xié)議,主要目的在于傳輸少量的數(shù)據(jù)。與TCP不同的是,TCP在傳輸之前必須創(chuàng)建連接,而UDP不需要,只要設(shè)置計(jì)算機(jī)間的IP及使用相同的端口,就可以相互傳輸數(shù)據(jù)。因此UDP只提供單向的數(shù)據(jù)傳輸,即所謂的單向無(wú)連接傳輸模式。
由于UDP不需要先創(chuàng)建連接,節(jié)省了TCP創(chuàng)建連接所需的時(shí)間,所以適合在主機(jī)間進(jìn)行單向的數(shù)據(jù)傳輸。由于視頻數(shù)據(jù)的傳輸對(duì)于實(shí)時(shí)性要求很高,即使傳輸過(guò)程中有個(gè)別幀的數(shù)據(jù)有錯(cuò),也不會(huì)影響整個(gè)視頻的效果,故本文將會(huì)詳細(xì)介紹如何通過(guò)UDP實(shí)現(xiàn)視頻數(shù)據(jù)的傳輸。
4.2 控件及相關(guān)內(nèi)容介紹
在Delphi中對(duì)于UDP及TCP都提供了很好的支持,而且將它們封裝起來(lái)。開(kāi)發(fā)人員無(wú)須知道協(xié)議的具體實(shí)現(xiàn)細(xì)節(jié),而只要使用Delphi提供的TIdUDPServer元件(在Indy Servers頁(yè))即可完成相應(yīng)的功能。下面我們一起來(lái)認(rèn)識(shí)一下這個(gè)元件。
1) 相關(guān)屬性
DefaultPort該屬性是用來(lái)指定作為客戶(hù)端時(shí)要打開(kāi)的端口號(hào),也就是通過(guò)該端口來(lái)接收數(shù)據(jù)。
Active該屬性是用來(lái)打開(kāi)指定的端口號(hào),設(shè)置為T(mén)rue表示打開(kāi)端口,F(xiàn)alse表示關(guān)閉端口。
BroadcastEnabled該屬性是用來(lái)設(shè)置是否用來(lái)實(shí)現(xiàn)廣播,設(shè)置為T(mén)rue表示可以廣播,F(xiàn)alse表示不能廣播。
2) 相關(guān)事件
OnUDPRead當(dāng)客戶(hù)端收到服務(wù)器端發(fā)來(lái)數(shù)據(jù)時(shí)觸發(fā)該事件,通過(guò)該事件我們可以取得服務(wù)器端發(fā)的每一幀的數(shù)據(jù),以便在客戶(hù)端回放。
除了以上提到的一些屬性及事件外,TIdUDPServer還有一個(gè)重要的方法需要了解,那就是SendBuffer,通過(guò)該方法可以在服務(wù)器端向指定客戶(hù)端的指定端口發(fā)送數(shù)據(jù)。
5 結(jié)束語(yǔ)
目前,Delphi已經(jīng)被很多的程序開(kāi)發(fā)者作為開(kāi)發(fā)網(wǎng)絡(luò)視頻程序工具。本文介紹的網(wǎng)絡(luò)視頻編程,應(yīng)該是目前比較常用的方法之一。本文所有程序在Win XP/Delpphi 7.0下實(shí)現(xiàn)通過(guò),所用視頻攝像頭為市場(chǎng)上普通銷(xiāo)售的產(chǎn)品。
參考文獻(xiàn):
[1] 白先平. 應(yīng)用Delphi開(kāi)發(fā)視頻語(yǔ)音聊天軟件[J]. 科技資訊,2006,29:113.
[2] 李國(guó)芳. 在VC++ 6.0中實(shí)現(xiàn)視頻捕獲編程[J]. 井岡山醫(yī)專(zhuān)學(xué)報(bào),2003(4):76-78.
[3] 劉德華. 在Delphi下實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)中圖像的操作[J]. 電腦編程技巧與維護(hù),2007(7):60-62.
[4] 何鵬飛. Delphi7程序設(shè)計(jì)教程[M]. 北京:清華大學(xué)出版社,2003.