1、实现视频通信(6分)实现音视频同步(8分)3.系统总体方案设计 8摘 要随着互联网技术的飞速发展,基于网络的即时通信给人们带来诸多便利,也成为当今网络应用的主流。聊天工具作为当今使用最为广泛的即时通信工具之一,可以方便人们随时随地进行在线交流,比如腾讯公司的QQ聊天软件。本次设计就是开发一个包括语音及视频交流等功能的聊天软件。本设计的开发采用VC+编程语言进行本软件的开发。本文对开发环境和开发语言进行了简单介绍;对本设计所要开发的多功能聊天软件作了较为详细的需求分析,并给出了多功能聊天软件的设计方案,主要功能包括文字聊天、语音聊天及视频聊天等;本次设计主要实现的是多功能聊天软件的部分功能,即语
2、音聊天、视频聊天等功能,主要实现用户注册、用户登录、用户之间语音、视频聊天功能;与另一位同学开发实现的文字聊天与文件传输模块集成在一起,构成一个实用的、功能完善的聊天软件,达到预期目标;通过运行、测试与分析说明,该多功能聊天软件运行稳定、可靠,具有一定的实用价值。关键词:聊天软件;视频聊天;语音聊天;VC+1.软件开发工具1.1 WIN32 SDK编程所谓的Win32开发,就是在C+语言的层面上,直接使用Win32 API(Application Programming Interface:系统开放出来,给程序员使用的接口。)开发Windows应用程序或者系统程序。所谓的Win32,其实是一个
3、API规范,与UNIX系统编程接口标准POSIX是相对应的。下面是进行直接的Win32 SDK方式编程的基本思路或者说是一个框架。一个Windows程序分为程序代码和UI(User Interface 用户界面)资源两大部分,两部分最后以RC编译程序编译为一个完整的EXE文件。所谓UI资源是指功能菜单、对话框外貌、程序图标、光标形状等等。这些UI资源的实际内容借助各种工具产生,并以各种扩展名存在,如 .ico .bmp .cur等等。程序员必须在一个所谓的资源描述档(.rc )中描述它们。RC编译器( RC.EXE )读取RC 文件的描述后将所有UI资源文件集中制作出一个.Res资源文件,再与
4、程序代码结合在一起,这才是一个完整的 Windows可执行文件。1.WinMain函数main()函数是C+程序的进入点,而WinMain函数则是Windows程序的进入点。2. Msg结构体定义了一个Msg结构体,是Windows内设的一种数据格式, 在Windows程序中,消息是由MSG结构体来表示的。3. 注册窗口RegisterClass()完成注册窗口类的功能,设定窗口的属性:边框、颜色、标题、位置等等。4. 创建窗口CreateWindow函数可以用于创建父窗口、弹出窗口以及子窗口,在创建窗口时它可以确定窗口类、窗口标题、窗口风格、大小以及初始化位置。5. 显示窗口创建窗口后需要使
5、用ShowWindow函数用于显示窗口。6、刷新窗口调用UpdateWindow函数来刷新窗口。7. 消息循环初始化工作完成后,WinMain进入所谓的消息循环,使用while循环,不断的GetMessage,再使用TranslateMessage将消息转化,用DispatchMessage将消息传递给窗口函数去处理。8. 获取消息GetMessage功能函数从消息队列中获取消息,如果消息队列中没有消息,此功能函数则会一直等得消息。9. 转换消息将特定的消息转换为不同的消息,例如消息队列中同时有WM_KEYDOWN和WM_KEYUP消息时,意味着用户同时按下了键盘上的某几个键,此时Transl
6、ateMessage将其转换为一个WM_CHAR消息。10. 将消息发送到回调函数DispatchMessage通过USER模块的协助将消息送到该窗口的窗口函数去了,但是DispatchMessage并没有指定函数名,却可以将消息传送过去,这是因为消息发生的时候,OS已经根据当时状态,为它标明了所属窗口,而窗口所属的窗口类亦是明确的。11. WinMain函数返回值return msg.wParam; /返回结构体变量msg中的wParam的值。12. WindowProc窗口函数窗口中的生命枢纽:窗口函数WindowProc。WindowProc是一个callback函数,常利用switch
7、/case方式判断消息的种类,以决定处理方式。1.2 TCP/IP协议及WINDOWS SOCKETS 网络编程接口1.2.1 TCP/IP协议 简介TCP/IP已成为当今计算机网络最成熟、应用最广的互联协议。Internet采用的就是TCP/IP协议,网络上各种各样的计算机上只要安装了TCP/IP协议,它们之间就能相互通信。运行TCP/IP协议的网络是一种采用包(分组)交换网络。TCP/IP协议是由100多个协议组成的协议集,TCP和IP是其中两个最重要的协议。通常包含了一系列与“TCP(传输控制协议)”和“IP(网际协议)”有联系的网络协议,它包括其它的协议,应用软件,甚至网络媒介。这些协
8、议的示例是:UDP(User Datagram Protocol)协议、ICMP(Internet Control Message Protocol)协议、ARP(地址解析协议)和其他一些协议的协议组。TCP和IP两个协议分别属于传输层和网络层,在Internet中起着不同的作用。1.2.2 Windows Socket 网络编程简介Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有 Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。Windows Sockets 规范定义了一套开放的、支持多种协议的、 Windows 下
9、的网络编程接口。它不仅包含了人们所熟悉的Berkeley Socket 风格的库函数,也包含了一组针对Windows 的扩展库函数,使得程序员能充分地利用Windows 消息驱动机制进行编程。现在的Windows Sockets已经基本上实现了与协议无关,你可以使用Windows Sockets来调用多种协议的功能,但较常使用的是TCP/IP协议。1.3 VC+ 6.0 简介我们通常所说的Visual C+实际上是一个完善的、非常强大的C+程序开发环境,它的名字是 Microsoft Developer Studio 。二者之间的细小差别并不重要,通常这两个术语可以互换。但如果你不围绕Deve
10、loper Studio 来进行学习,就不能有效地使用Visual C+(Developer Studio 听起来很像Visual Studio , 但它们之间没有关系)。它包含:C+编译器、调试器、应用程序框架生成器、项目管理器、设计和实现菜单等资源的编辑器等等。1.4 Video for Windows简介VFW是Microsoft 1992年推出的关于数字视频的一个软件包,它能使应用程序数字化并播放从传统模拟视频源得到的视频剪辑。VFW的一个关键思想是播放时不需要专用硬件,为了解决数字视频数据量大的问题,需要对数据进行压缩。它引进了一种叫AVI的文件标准,该标准未规定如何对视频进行捕获、
11、压缩及播放,仅规定视频和音频该如何存储在硬盘上,在AVI文件中交替存储视频帧和与之相匹配的音频数据。VFW给程序员提供.VBX和AVICap窗口类的高级编程工具,使程序员能通过发送消息或设置属性来捕获、播放和编辑视频剪辑。现在用户不必专门安装VFW了,Windows95本身包括了Video for Windows1.1,当用户在安装Windows时,安装程序会自动地安装配置视频所需的组件,如设备驱动程序、视频压缩程序等。VFW主要由以下六个模块组成:(1)AVICAP.DLL:包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口。(2)MSVIDEO.DLL:
12、用一套特殊的DrawDib函数来处理屏幕上的视频操作。(3)MCIAVI.DRV:此驱动程序包括对VFW的MCI命令的解释器。(4)AVIFILE.DLL:支持由标准多媒体I/O(mmio)函数提供的更高的命令来访问.AVI文件。(5)压缩管理器(ICM):管理用于视频压缩解压缩的编解码器(CODEC)。(6)音频压缩管理器ACM:提供与ICM相似的服务,不同的是它适于波形音频。1.5 G729.dll的简介G.729算法是ITU-T制定的编码速率为8kb/s的共轭结构码激励线性预测声码器语音编码算法标准,作为低速率的语音编码器,在传输的带宽有限的情况下运用越来越受到广泛的重视。G.729系列
13、算法声码器的原理都是相通的,各种算法不同之处在于算法的简化和编码比特的多少。G.729编码器是基于码激励线性预测(CELP)声码器模型的。这个编码器运算的帧长为10ms,相应于抽样率为8000kHz的语音数据流的80个样值,具有8kbit/s的编码速率,较低的延迟和高编码语音质量等优点。本程序在语音聊天模块中,调用了G729.dll动态链接库文件,它包括G.729的函数和资源,是一种可执行文件,它允许程序共享执行特殊任务所必需的代码和其他资源。1.6 LanMsgLibrary.dll的简介该聊天软件系统的语音聊天、视频聊天功能的实现主要是引用了LanMsgLibrary.dll这个动态链接库
14、文件,它包括VFW以及其他相关的函数与资源。在音频与视频聊天实现的过程中,程序就引用了LanMsgLibrary.dll中的VFW以及相关的函数和资源。在视频聊天过程中,主要实现了视频的捕获与播放,视频流的压缩与解压。在语音聊天过程中,主要实现了声音的采集与播放,通过调用了G729.dll动态链接库文件,对音频进行了压缩与解压。在整个语音聊天与视频聊天实现的过程中,程序主要对LanMsgLibrary.dll的引用来实现其功能。2.系统原理分析2.1系统原理概述 从技术上而言,音视频通信技术,涉及音视频设备操作、音视频流编解码、媒体流网络传输、流媒体接受处理等相关技术。另外,由于媒体流信息量大
15、,及时要求度高,还要保障媒体帧的流畅性,这就对依赖于高速网络、高性能的硬件设备以及相关媒体流网络包的建包和解包算法。 2.2关键技术分析 对于一个端对端的语音聊天系统来说,主要涉及两个方面的动作,即语音的采集和播放、语音数据的发送和接收。系统采用多线程的设计思想来完成并协调各个过程。语音的采集实际上就是一个音频压缩的过程。语音的播放是声音数据流的还原过程,通过一个父线程读取接收线程接收到的数据,并通过管道让其子线程播放解压后的声音数据。语音数据的发送和接收主要用Socket编程来实现,socket是网络通讯过程中端点的抽象表示。为了通过socket接口进行网络通讯,程序在对话的每一端都需要一个
16、socket,两个socket采用无连接的UDP协议。视频模块的设计思想与语音模块一致,也涉及到两个方面的动作,视频的采集和播放,视频数据的发送和接收。视频的采集与播放是基于VFW来实现的,利用VFW的关于数字视频的软件包实现对视频的采集与播放。视频数据的发送与接收同样采用了Socket编程,在发送视频时,通过Socket端口进行监听。当收到对方发送的包含视频请求信息和对方IP地址、端口号等信息后,如果同意请求,则向请求方发送包含了本地IP、端口号的接受视频信息,这样就建立了连接,开始视频聊天。TCP/IP是一组用于实现网络互连的通信协议。Internet网络体系结构以TCP/IP为核心。基于
17、TCP/IP的参考模型将协议分成四个层次,它们分别是:网络访问层、网际互连层、传输层(主机到主机)、和应用层。UDP协议的全称是用户数据包协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。3.系统总体方案设计3.1系统功能模块图图3.1.1 系统功能模块图图3.1.2 语音视频聊天流程图3.2 语音聊天过程分析用户1通过麦克对自己的声音进行采集,在通过压缩,使其在网络上传输的效率更高,然后再进行传输,当用户2接收到用户1的声音数据后将其解压,然后进行播放。图3.2.1 语音模块数据流程图在进行语音聊天时,两台计算机必须先要建立连接,如图5所示,用户1向用户2发送“发送语音请求
18、”信息,用户2收到用户1请求信息后,发送回应信息给用户1,如果用户2同意,开始语音聊天;不同意,停止语音聊天。图3.2.2 语音聊天建立连接图3.3视频聊天过程分析用户1通过摄像头进行视频采集,经过压缩后,向用户2发送采集后的视频数据。用户2接收到用户1发送的视频数据并将其进行解压,然后在用户2的采集窗口上播放,这样视频的传输就完成了。视频模块数据传输流程如图3所示。图3.3.1 视频模块数据传输流程图在进行视频数据传输前,两台计算机必须先要建立连接,其原理和语音聊天建立连接的原理一致。用户1向用户2发送视频请求,用户2在接收到用户1的请求后,给用户1发送收到请求后的回应信息,如果同意用户1的
19、请求则用户1与用户2开始视频聊天,如果不同意就终止视频聊天。视频聊天建立连接如图7所示。图2.3.2 视频聊天建立连接图4.系统具体设计 4.1 语音视频聊天的实现在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,即用户与用户之间的数据传输。其套接字的使用如下图。图4.1 语音视频聊天套接字图 4.2 视频的捕捉利用VFW接口,视频捕获可以分为以下几个步骤:1. 建立视频采集窗口:该窗口用来接收视频捕捉驱动程序传来的数据和消息。2. 连接视频驱动程序:将建立的视频捕捉窗口与视频设备驱动程序相连。3. 视频捕获初始化。4. 视频捕捉设置:VFW下视频捕捉参数的设置可以通过调用函数或弹出
20、对话框的形式来实现。一般视频驱动程序允许设置的参数包括视频源选择、视频格式、视频显示格式等。5. 设置回调函数:通过回调函数来通知程序视频事件的发生,比如捕捉一帧图像成功的消息,捕捉出错的消息等。6. 结束捕捉:结束捕捉是应该有一些清除工作。如释放分配的内存,断开捕捉窗口与视频捕捉驱动程序的连接,清除视频捕捉窗口等。窗口类为捕获数字视频流及其相关操作提供了很大的方便,灵活编写其中的回调函数可满足实时视频传输的需要,例如应用程序可直接从缓冲中取得数字视频并对其进行压缩编码后实时地传到远端的客户端。在VC+中,采用VFW技术,客户端通过capSetCallbackOnFrame()注册回调函数,当
21、采集卡采集到一幅图像后,系统就会自动调用回调函数,然后再回调函数中使用ICSeqCompressFrame()函数进行压缩。然后再通过Winsock将压缩后的数据发送到另一客户端。该客户端接收完一帧以后,交给ICDecompress()解压,最后用SetDIBitsToDevice()将图像显示出来。基本的捕获设置包括设置捕获速度(每秒捕获多少帧)、是否同时捕获声频、捕获缓冲、允许最大丢失多少帧和是否使用DOS内存,以及使用键盘的哪个键或鼠标的哪个键来终止捕获等内容,这些设置使用CAPTUREPARAMS结构来描述,capCaptureGetSetup宏来得到当前的设置,然后改变此结构的成员变
22、量,再使用capCaptureSetSetup宏设置新的设置。设置捕获速度,通过使用capCaptureGetSetup宏来得到当前的捕捉速度,将当前的捕捉速度保存在CAPTUREPARAMS结构的dwRequestMicroSecPerFrame成员变量中,也可以通过设置此变量来改变当前设置值。设置终止捕获,同样通过使用capCaptureGetSetup宏来得到当前的设置,当前按键设置保存在CAPTUREPARAMS结构的vKeyAbort成员中,鼠标设置保存在fAbortLeftMouse和fAbortRightMouse成员中,通过修改可以设置新的热健或者鼠标左右键,修改完成后,使用c
23、apCaptureSetSetup宏来进行更新。捕获的时间限制,用CAPTUREPARAMS结构中的fLimitEnabled表示捕获是否有时间的限制,wTimeLimit用来设置指示捕获最大的持续时间,其单位为秒。使用capCaptureGetSetup宏来得到当前的设置值。 下面程序为设置CAPTUREPARAMS结构的实现代码:BOOL VideoCapture:SetCapturePara() CAPTUREPARMS CapParms=0; capCaptureGetSetup(m_capwnd,&CapParms,sizeof(CapParms); /得到当前的捕获速度 CapPa
24、rms.fAbortLeftMouse = FALSE; CapParms.fAbortRightMouse = FALSE; CapParms.fYield = TRUE; CapParms.fCaptureAudio = FALSE; CapParms.wPercentDropForError = 80; if(!capCaptureSetSetup(m_capwnd,&CapParms,sizeof(CapParms) / log.WriteString(n Failed to set the capture parameters ); return FALSE; / Set Video
25、 Format capGetVideoFormat(m_capwnd,&m_bmpinfo,sizeof(m_bmpinfo); m_bmpinfo.bmiHeader.biWidth=IMAGE_WIDTH; m_bmpinfo.bmiHeader.biHeight=IMAGE_HEIGHT; BOOL ret=capSetVideoFormat(m_capwnd,&n Video parameters set properly return ret;/终止一个捕获任务StopCapture() capCaptureStop(m_capwnd); capCaptureAbort(m_capw
26、nd); Sleep(500); return TRUE;4.3 窗口的捕捉在捕获前必须创建一个捕获窗口(Capture Widnow),下面介绍有关捕获窗口的情况:创建一个AVICap捕获窗口,用capCreateCaptureWindow函数并返回一个句柄。将捕获窗口连接至捕获设备,用capDriverConnect函数来使一个捕获窗口与一个捕获设备连接或关联连接上后,就可以通过捕获窗口向捕获设备发送各种消息,可以使用函数capGetDriverDescription来获得已安装的捕获设备名称及版本,将其列举在实现程序过程中。再利用capDriverGetName函数来得到捕获设备的名称将
27、获得的版本发送到capDriverGetVersion。如果断开捕获窗口与捕获设备的连接用capDriverDisconnect。捕获窗口的状态,用capGetStatus函数来获得当前捕获窗口的状态,得到一个CAPSTATUS结构的拷贝。该结构的内容包含了图片的尺寸、卷轴的当前位置、overlay和preview是否已设置。由于其信息是动态的,每当捕获的视频流的尺寸发生改变,程序应该在获取捕获设备的视频格式以后及时进行刷新。而捕获窗口尺寸的改变并不影响实际的捕获视频流的尺寸。该尺寸由视频捕获设备的格式和视频对话框决定。/捕获窗口Initialize() char devname128=0,d
28、evversion128=0; int index=0; BOOL ret = TRUE, ret1 = TRUE, ret2 = TRUE, ret3 = TRUE; TRACE(VideoCapture:Initializen /创建一个AVICap捕获窗口 m_capwnd = capCreateCaptureWindow(Capture,WS_POPUP,0,0,1,1,0,0);m_capwnd) return FALSE; /connect callback functions ret = capSetUserData(m_capwnd,this); /Change destroy
29、 functions also. ret1 = capSetCallbackOnVideoStream(m_capwnd,OnCaptureVideo); /得到已安装的捕获设备的名称及版本ret2 = capGetDriverDescription(index,devname,100,devversion,100); / Connect to webcam driver /使一个捕获窗口与一个捕获设备连接或关联 ret3 = capDriverConnect(m_capwnd,index);(ret & ret1 & ret2 & ret3) / Device may be open already or it may not have been / closed properly last time. AfxMessageBox(Unable to open Video Capture Device / log.WriteString(n Unable to connect driver to the window m_capwnd=NULL; / Set the capture parameters
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1