用Delphi开发视频聊天软件.doc_第1页
用Delphi开发视频聊天软件.doc_第2页
用Delphi开发视频聊天软件.doc_第3页
用Delphi开发视频聊天软件.doc_第4页
用Delphi开发视频聊天软件.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用Delphi开发视频聊天软件摘要:目前网上视频聊天软件、视频会议软件、可视IP电话软件随处可见,你是否想自己做一个玩玩?其实这类软件无非是视频加上网络而建成的。如果熟悉视频捕捉和网络传输技术,根本就难不倒你。微软为软件开发人员提供了一个专门用于视频捕捉的VFW SDK(Video for Windows SDK),用它实现视频捕捉很简单,至于网络传输嘛,Delphi更是提供了N多种网络组件,随你用了。本文详细介绍了如何利用Delphi中开发视频聊天软件,同时给出了两个程序示例。 关键词:Delphi VFW 视频 视频会议 视频聊天 Video for Windows一、引言我们知道视频聊天软件的关键技术在于采集视频,并实时传输给聊天软件在线的人。对于视频的采集,这里采用微软公司的关于数字视频的一个软件包VFW(Video for Windows)。相信很多人对它都很熟习,VFW能使应用程序通过数字化设备从传统的模拟视频源得到数字化的视频剪辑,VFW的一个关键思想是播放时不需要专用硬件。为了解决数字视频数据量大的问题,需要对数据进行压缩,而VFW引进了AVI的文件标准。该标准未规定如何对视频进行捕捉、压缩及播放,仅规定视频和音频该如何存储在硬盘上及在AVI文件中交替存储视频帧和与之相匹配的音频数据。通过VFW,开发人员通过发送消息或设置属性来捕捉、播放和编辑视频剪辑。当用户在安装VFW时,安装程序会自动地安装配置视频所需要的组件,如设备驱动程序、视频压缩程序等。VFW主要由6个模块组成。VFW功能模块:AVICAP.DLL 包含执行视频捕捉的函数,它给AVI文件的I/O处理和视频、音频设备驱动程序提供一个高级接口 MSVIDEO.DLL 包含一套特殊的DrawDib函数,用来处理屏幕上的视频操作 MCIAVI.DRV 包括对VFW的MCI命令解释器的驱动程序 AVIFILE.DLL 包含由标准多媒体I/O(mmio)函数提供的更高的命令,用来访问.AVI文件 ICM 压缩管理器,用于管理的视频压缩/解压缩的编译码器(Codec) ACM 音频压缩管理器,提供与ICM相似的服务,适用于波形音频 对于视频的传输,我们使用UDP来传,因为UDP传输速度快,TCP是面向连接的,建立连接时双方需经过三次握手,数据传输可靠,FTP、telnet等就是基于TCP的,UDP是面向非连接的,发出信息不需对方确认,但这样速度比TCP快,但有可能丢失数据,象SMTP、tftp等就是基于UDP的。另外UDP还支持广播,UDP广播两种,一种是directed broadcast,比如你的网段是192.168.0.X,你就往55发就可以了。另一种是limited broadcast,广播地址是55二、视频聊天软件的开发步骤2.1 创建捕捉窗口,采集视频在进行视频捕捉之前必需要先创建一个捕捉窗口,并应以此为基础进行所有的捕捉及设置操作。捕捉窗口可用AVICap窗口类的CapCreateCaptureWindow函数来创建,其窗口风格可设置为WSCHILD和WS_VISIBLE参数。有了捕捉窗口,我们就可以将视频流和音频流捕捉到一个AVI文件中;动态地同视频和音频输入器件连接或断开;用Overlay或Preview模式对输入的视频流进行实时显示,设置捕捉速率,显示控制视频源、视频格式及视频压缩的对话框,创建、保存或载入调色板,将图像和相关的调色板拷贝到剪贴板,将捕捉的单帧图像保存到BMP格式文件中。2.2 捕捉窗口和驱动程序的关联仅仅一个捕捉窗口是不能工作起来的,它必须要与一个设备相关联才能取得视频信号。用函数CapDriverConnect可使捕捉窗与其设备驱动程序相关联。2.3设置视频设备的属性通过设置TcaptureParms结构变量的各个成员变量,可以控制设备的采样频率、中断采样按键、状态行为。设置好TcaptureParms结构变量后,可以用函CapCaptureSetSetup使设置生效。之后还可以用CapPreviewScale、CapPreviewRate设置预览的比例与速度,也可以直接使用设备的默认值。2.4打开预览利用函数CapOverlay可选择是否采用叠加模式预览,以使系统资源占用小,视频显示速度加快。然后用CapPreview启动预览功能,这时就可以在屏幕上看到来自摄像头的图像了。2.5使用捕捉窗回调函数前的四个步骤就可以建立一个基本的视频捕捉程序了,如果想自己处理从设备捕捉到的视频数据,则要使用捕捉窗回调函数来处理,比如一帧一帧地获得视频数据,也可以以流的方式获得视频数据等等。2.6传输视频流使用回调函数可以取得第一帧的数据,我们使用网络技术将数据发给其它机器,其它机品将接收的数据显示出来。2.7接收视频接收UDP数据,同时将接收到的数据回显出来,这样就可以看到远处传来的视频了。三、用Delphi编写程序代码微软的VFW SDK只有VC和VB版,并没有Delphi版,不过在网上可以找到VFW.PAS文件,FW.PAS文件声明了调用DLL中的各个函数和变量。(注:源代码中提供了VFW.PAS文件)下面就以Delphi7开发一个网络视频聊天软件,聊天软件分两个程序,一个是视频采集程序并进行UDP广播的视频聊天软件服务器,另一个是接收UDP广播程序显示传来的视频数据的视频聊天软件客户端。3.1建立视频聊天软件服务器3.1.1新建一个工程,命名为Project1.dpr,并把VFW.PAS加到USE中3.1.2在Form1上放置一个Tpanel控件,该控件用于显示视频。之后再放置两个Tbutton控件,一个caption为开始,另一个Name为停止,放置一个UDP组件,这里用indy的IdUDPClient用来传输视频,如图示:3.1.3定义全局变量CapWnd:THandle; /定义捕捉窗句柄 CapParms:TcaptureParms; /用于设置设备属性的结构变量BMPINFO:TBitmapInfo; /BMP图像信息 3.1.4编码事件代码 开始按钮代码:CapWnd := capCreateCaptureWindow(我的窗口, WS_VISIBLE or WS_CHILD,/窗口样式 0, /X坐标 0, /Y坐标 panel1.Width, /窗口宽 panel1.Height, /窗口高 panel1.handle, /窗口句柄 0); /通常为0 if CapWnd = 0 then exit; /定义帧捕捉回调函数 CapSetCallbackOnFrame(CapWnd,FrameCallBack); CapParms.dwRequestMicroSecPerFrame:=1; CapParms.fLimitEnabled:=FALSE;CapParms.fCaptureAudio:=FALSE;CapParms.fMCIControl:=FALSE;CapParms.fYield:=TRUE;CapParms.vKeyAbort:=VK_ESCAPE;CapParms.fAbortLeftMouse:=False; CapParms.fAbortRightMouse:=FALSE; /让设置生效CapCaptureSetSetup(capWnd,CapParms,sizeof(TCAPTUREPARMS);CapPreviewRate(capWnd,33); /设置预览视频的频率CapCaptureSequenceNoFile(capWnd); /如果要捕捉视频流,则要使用函数来指定不生成文件,不然会自动生成AVI文件 CapDriverConnect(CapWnd,0); /连接摄像头设备,第二个参数是个序号,当系统中装有多个显示驱动程序时,其值分别依次为0到总个数如果有多个摄像头,那么就是0-1-2 capGetVideoFormat(capWnd, BMPINFO,sizeof(TBitmapInfo); /取得视频图像数据头CapPreviewScale(capWnd,TRUE); /是否缩放CapOverlay(capWnd,true); /指定是否使用叠加模式,true为使用,否则为falseCapPreview(capWnd,true);回调函数代码:var hd:Thandle; jpg:TJpegImage;memStream :TMemoryStream;Bitmap:TBitmap;begin /将数据显在Image, Bitmap:=TBitmap.Create;Bitmap.Width :=BMPINFO.bmiHeader.biWidth;/ New size of Bitmap Bitmap.Height:=BMPINFO.bmiHeader.biHeight;hd:= DrawDibOpen; DrawDibDraw(hd,Bitmap.canvas.handle,0,0,_BMPINFO.BmiHeader.biwidth,BMPINFO.bmiheader.biheight,_BMPINFO.bmiHeader,lpVHdr.lpData,0,0,BMPINFO.bmiHeader.biWidth,_BMPINFO.bmiHeader.biheight,0);DrawDibClose(hd); /发送数据memStream := TMemoryStream.Create;jpg := TJpegImage.Create;jpg.Assign(Bitmap);jpg.CompressionQuality := 10; /jpg压缩质量jpg.JPEGNeeded; jpg.Compress; jpg.SaveToStream(memStream);jpg.Free; /因为UDP数据包有大小限制,这里如果超出部分,就没有传输,完全可以发几次发出去Form1.IdUDPClient1.BroadcastEnabled:=true;/用广播功能if memStream.SizeForm1.IdUDPClient1.BufferSize then /向192.168.0.X网段广播,端口 9001Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,Form1.IdUDPClient1.BufferSize) else Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,memStream.Size);memStream.Free; Bitmap.Free;End;停止代码:capCaptureAbort(CapWnd); /停止捕捉 capDriverDisconnect(CapWnd); /将捕捉窗同驱动器断开完整的视频聊天软件服务器代码:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,VFW, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,jpeg;type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton;Button2: TButton;IdUDPClient1: TIdUDPClient;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private Private declarations public Public declarations end;var Form1: TForm1;CapWnd:THandle; /定义捕捉窗句柄CapParms:TcaptureParms; /用于设置设备属性的结构变量BMPINFO:TBitmapInfo; /BMP图像信息implementation$R *.dfmfunction FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): LongInt;stdcall;var hd:Thandle;jpg:TJpegImage;memStream :TMemoryStream;Bitmap:TBitmap;begin /将数据显在Image, Bitmap:=TBitmap.Create;Bitmap.Width :=BMPINFO.bmiHeader.biWidth;/ New size of Bitmap Bitmap.Height:=BMPINFO.bmiHeader.biHeight; hd:= DrawDibOpen; DrawDibDraw(hd,Bitmap.canvas.handle,0,0,BMPINFO.BmiHeader.biwidth,BMPINFO._bmiheader.biheight,BMPINFO.bmiHeader,_lpVHdr.lpData,0,0,BMPINFO.bmiHeader.biWidth,BMPINFO.bmiHeader.biheight,0);DrawDibClose(hd);/发送数据 memStream := TMemoryStream.Create;jpg := TJpegImage.Create; jpg.Assign(Bitmap);jpg.CompressionQuality := 10; /jpg压缩质量 jpg.JPEGNeeded; jpg.Compress;jpg.SaveToStream(memStream);jpg.Free;/因为UDP数据包有大小限制,这里如果超出部分,就没有传输,完全可以发几次发出去Form1.IdUDPClient1.BroadcastEnabled:=true;/用广播功能if memStream.SizeForm1.IdUDPClient1.BufferSize then /向192.168.0.X网段广播,端口 9001 Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,Form1.IdUDPClient1.BufferSize) elseForm1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,memStream.Size); memStream.Free;Bitmap.Free;end;procedure TForm1.Button1Click(Sender: TObject);beginCapWnd := capCreateCaptureWindow(我的窗口, WS_VISIBLE or WS_CHILD,/窗口样式 0, /X坐标 0, /Y坐标 panel1.Width, /窗口宽panel1.Height, /窗口高 panel1.handle, /窗口句柄 0); /通常为0 if CapWnd = 0 then exit; /定义帧捕捉回调函数CapSetCallbackOnFrame(CapWnd,FrameCallBack); CapParms.dwRequestMicroSecPerFrame:=1; CapParms.fLimitEnabled:=FALSE;CapParms.fCaptureAudio:=FALSE;CapParms.fMCIControl:=FALSE;CapParms.fYield:=TRUE;CapParms.vKeyAbort:=VK_ESCAPE; CapParms.fAbortLeftMouse:=False;CapParms.fAbortRightMouse:=FALSE; /让设置生效 CapCaptureSetSetup(capWnd,CapParms,sizeof(TCAPTUREPARMS);CapPreviewRate(capWnd,33); /设置预览视频的频率 CapCaptureSequenceNoFile(capWnd); /如果要捕捉视频流,则要使用函数来指定不生成文件,不然会自动生成AVI文件 CapDriverConnect(CapWnd,0); /连接摄像头设备,第二个参数是个序号,当系统中装有多个显示驱动程序时,其值分别依次为0到总个数如果有多个摄像头,那么就是0-1-2 capGetVideoFormat(capWnd, BMPINFO,sizeof(TBitmapInfo); /取得视频图像数据头 CapPreviewScale(capWnd,TRUE); /是否缩放 CapOverlay(capWnd,true); /指定是否使用叠加模式,true为使用,否则为false CapPreview(capWnd,true);end;procedure TForm1.Button2Click(Sender: TObject);begin capCaptureAbort(CapWnd); /停止捕捉 capDriverDisconnect(CapWnd); /将捕捉窗同驱动器断开end;end.3.2建立视频聊天软件客户端3.1.4编码事件代码 开始按钮代码:CapWnd := capCreateCaptureWindow(我的窗口, WS_VISIBLE or WS_CHILD,/窗口样式 0, /X坐标 0, /Y坐标 panel1.Width, /窗口宽 panel1.Height, /窗口高 panel1.handle, /窗口句柄 0); /通常为0 if CapWnd = 0 then exit; /定义帧捕捉回调函数 CapSetCallbackOnFrame(CapWnd,FrameCallBack); CapParms.dwRequestMicroSecPerFrame:=1; CapParms.fLimitEnabled:=FALSE;CapParms.fCaptureAudio:=FALSE;CapParms.fMCIControl:=FALSE;CapParms.fYield:=TRUE;CapParms.vKeyAbort:=VK_ESCAPE;CapParms.fAbortLeftMouse:=False; CapParms.fAbortRightMouse:=FALSE; /让设置生效CapCaptureSetSetup(capWnd,CapParms,sizeof(TCAPTUREPARMS);CapPreviewRate(capWnd,33); /设置预览视频的频率CapCaptureSequenceNoFile(capWnd); /如果要捕捉视频流,则要使用函数来指定不生成文件,不然会自动生成AVI文件 CapDriverConnect(CapWnd,0); /连接摄像头设备,第二个参数是个序号,当系统中装有多个显示驱动程序时,其值分别依次为0到总个数如果有多个摄像头,那么就是0-1-2 capGetVideoFormat(capWnd, BMPINFO,sizeof(TBitmapInfo); /取得视频图像数据头CapPreviewScale(capWnd,TRUE); /是否缩放CapOverlay(capWnd,true); /指定是否使用叠加模式,true为使用,否则为falseCapPreview(capWnd,true);回调函数代码:var hd:Thandle; jpg:TJpegImage;memStream :TMemoryStream;Bitmap:TBitmap;begin /将数据显在Image, Bitmap:=TBitmap.Create;Bitmap.Width :=BMPINFO.bmiHeader.biWidth;/ New size of Bitmap Bitmap.Height:=BMPINFO.bmiHeader.biHeight;hd:= DrawDibOpen; DrawDibDraw(hd,Bitmap.canvas.handle,0,0,_BMPINFO.BmiHeader.biwidth,BMPINFO.bmiheader.biheight,_BMPINFO.bmiHeader,lpVHdr.lpData,0,0,BMPINFO.bmiHeader.biWidth,_BMPINFO.bmiHeader.biheight,0);DrawDibClose(hd); /发送数据memStream := TMemoryStream.Create;jpg := TJpegImage.Create;jpg.Assign(Bitmap);jpg.CompressionQuality := 10; /jpg压缩质量jpg.JPEGNeeded; jpg.Compress; jpg.SaveToStream(memStream);jpg.Free; /因为UDP数据包有大小限制,这里如果超出部分,就没有传输,完全可以发几次发出去Form1.IdUDPClient1.BroadcastEnabled:=true;/用广播功能if memStream.SizeForm1.IdUDPClient1.BufferSize then /向192.168.0.X网段广播,端口 9001Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,Form1.IdUDPClient1.BufferSize) else Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,memStream.Size);memStream.Free; Bitmap.Free;End;停止代码:capCaptureAbort(CapWnd); /停止捕捉 capDriverDisconnect(CapWnd); /将捕捉窗同驱动器断开完整的视频聊天软件服务器代码:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,VFW, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,jpeg;type TForm1 = class(TForm) Panel1: TPanel; Button1: TButton;Button2: TButton;IdUDPClient1: TIdUDPClient;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private Private declarations public Public declarations end;var Form1: TForm1;CapWnd:THandle; /定义捕捉窗句柄CapParms:TcaptureParms; /用于设置设备属性的结构变量BMPINFO:TBitmapInfo; /BMP图像信息implementation$R *.dfmfunction FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): LongInt;stdcall;var hd:Thandle;jpg:TJpegImage;memStream :TMemoryStream;Bitmap:TBitmap;begin /将数据显在Image, Bitmap:=TBitmap.Create;Bitmap.Width :=BMPINFO.bmiHeader.biWidth;/ New size of Bitmap Bitmap.Height:=BMPINFO.bmiHeader.biHeight; hd:= DrawDibOpen; DrawDibDraw(hd,Bitmap.canvas.handle,0,0,BMPINFO.BmiHeader.biwidth,BMPINFO._bmiheader.biheight,BMPINFO.bmiHeader,_lpVHdr.lpData,0,0,BMPINFO.bmiHeader.biWidth,BMPINFO.bmiHeader.biheight,0);DrawDibClose(hd);/发送数据 memStream := TMemoryStream.Create;jpg := TJpegImage.Create; jpg.Assign(Bitmap);jpg.CompressionQuality := 10; /jpg压缩质量 jpg.JPEGNeeded; jpg.Compress;jpg.SaveToStream(memStream);jpg.Free;/因为UDP数据包有大小限制,这里如果超出部分,就没有传输,完全可以发几次发出去Form1.IdUDPClient1.BroadcastEnabled:=true;/用广播功能if memStream.SizeForm1.IdUDPClient1.BufferSize then /向192.168.0.X网段广播,端口 9001 Form1.IdUDPClient1.SendBuffer(55,9001,memStream.Memory,Form1.IdUDPClient1.BufferSize) elseForm1.IdUDPClient1.SendBu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论