清河网站建设设计,怎么弄自己的微信公众号,曲靖企业网站建设,塑胶 东莞网站建设语音视频聊天 UDP套接字的运用
在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。 图10 UDP套接字的使用 视频的捕获
利用VFW接口#xff0c;视频捕获可以分为以下几个步骤#xff1a;
建立视频采集窗口… 语音视频聊天 UDP套接字的运用
在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。 图10 UDP套接字的使用 视频的捕获
利用VFW接口视频捕获可以分为以下几个步骤
建立视频采集窗口该窗口用来接收视频捕捉驱动程序传来的数据和消息。连接视频驱动程序将建立的视频捕捉窗口与视频设备驱动程序相连。视频捕获初始化。视频捕捉设置VFW下视频捕捉参数的设置可以通过调用函数或弹出对话框的形式来实现。一般视频驱动程序允许设置的参数包括视频源选择、视频格式、视频显示格式等。设置回调函数通过回调函数来通知程序视频事件的发生比如捕捉一帧图像成功的消息捕捉出错的消息等。结束捕捉结束捕捉是应该有一些清除工作。如释放分配的内存断开捕捉窗口与视频捕捉驱动程序的连接清除视频捕捉窗口等。
窗口类为捕获数字视频流及其相关操作提供了很大的方便灵活编写其中的回调函数可满足实时视频传输的需要例如应用程序可直接从缓冲中取得数字视频并对其进行压缩编码后实时地传到远端的客户端。
在VC中采用VFW技术客户端通过capSetCallbackOnFrame()注册回调函数当采集卡采集到一幅图像后系统就会自动调用回调函数然后再回调函数中使用ICSeqCompressFrame()函数进行压缩。然后再通过Winsock将压缩后的数据发送到另一客户端。该客户端接收完一帧以后交给ICDecompress()解压最后用SetDIBitsToDevice()将图像显示出来。
基本的捕获设置包括设置捕获速度每秒捕获多少帧、是否同时捕获声频、捕获缓冲、允许最大丢失多少帧和是否使用DOS内存以及使用键盘的哪个键或鼠标的哪个键来终止捕获等内容这些设置使用CAPTUREPARAMS结构来描述capCaptureGetSetup宏来得到当前的设置然后改变此结构的成员变量再使用capCaptureSetSetup宏设置新的设置。
设置捕获速度通过使用capCaptureGetSetup宏来得到当前的捕捉速度将当前的捕捉速度保存在CAPTUREPARAMS结构的dwRequestMicroSecPerFrame成员变量中也可以通过设置此变量来改变当前设置值。
设置终止捕获同样通过使用capCaptureGetSetup宏来得到当前的设置当前按键设置保存在CAPTUREPARAMS结构的vKeyAbort成员中鼠标设置保存在fAbortLeftMouse和fAbortRightMouse成员中通过修改可以设置新的热健或者鼠标左右键修改完成后使用capCaptureSetSetup宏来进行更新。
捕获的时间限制用CAPTUREPARAMS结构中的fLimitEnabled表示捕获是否有时间的限制wTimeLimit用来设置指示捕获最大的持续时间其单位为秒。使用capCaptureGetSetup宏来得到当前的设置值。
下面程序为设置CAPTUREPARAMS结构的实现代码
BOOL VideoCapture::SetCapturePara()
{
CAPTUREPARMS CapParms{0};
capCaptureGetSetup(m_capwnd,CapParms,sizeof(CapParms)); //得到当前的捕获速度
CapParms.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 Format
capGetVideoFormat(m_capwnd,m_bmpinfo,sizeof(m_bmpinfo));
m_bmpinfo.bmiHeader.biWidthIMAGE_WIDTH;
m_bmpinfo.bmiHeader.biHeightIMAGE_HEIGHT;
BOOL retcapSetVideoFormat(m_capwnd,m_bmpinfo,sizeof(m_bmpinfo));
// log.WriteString(\n Video parameters set properly);
return ret;
}
//终止一个捕获任务
BOOL VideoCapture::StopCapture()
{
capCaptureStop(m_capwnd);
capCaptureAbort(m_capwnd);
Sleep(500); return TRUE;
} 捕获窗口
在捕获前必须创建一个捕获窗口Capture Widnow下面介绍有关捕获窗口的情况创建一个AVICap捕获窗口用capCreateCaptureWindow函数并返回一个句柄。将捕获窗口连接至捕获设备用capDriverConnect函数来使一个捕获窗口与一个捕获设备连接或关联连接上后,就可以通过捕获窗口向捕获设备发送各种消息,可以使用函数capGetDriverDescription来获得已安装的捕获设备名称及版本,将其列举在实现程序过程中。再利用capDriverGetName函数来得到捕获设备的名称将获得的版本发送到capDriverGetVersion。如果断开捕获窗口与捕获设备的连接用capDriverDisconnect。
捕获窗口的状态用capGetStatus函数来获得当前捕获窗口的状态得到一个CAPSTATUS结构的拷贝。该结构的内容包含了图片的尺寸、卷轴的当前位置、overlay和preview是否已设置。由于其信息是动态的每当捕获的视频流的尺寸发生改变程序应该在获取捕获设备的视频格式以后及时进行刷新。而捕获窗口尺寸的改变并不影响实际的捕获视频流的尺寸。该尺寸由视频捕获设备的格式和视频对话框决定。
//捕获窗口
BOOL VideoCapture::Initialize()
{ char devname[128]{0},devversion[128]{0}; int index0; BOOL ret TRUE, ret1 TRUE, ret2 TRUE, ret3 TRUE; TRACE(VideoCapture::Initialize\n); //创建一个AVICap捕获窗口 m_capwnd capCreateCaptureWindow(Capture,WS_POPUP,0,0,1,1,0,0);
if(!m_capwnd)
{
return FALSE;
}
//connect callback functions
ret capSetUserData(m_capwnd,this);
//Change destroy functions also........ ret1 capSetCallbackOnVideoStream(m_capwnd,OnCaptureVideo); //得到已安装的捕获设备的名称及版本 ret2 capGetDriverDescription(index,devname,100,devversion,100);
// Connect to webcam driver
//使一个捕获窗口与一个捕获设备连接或关联
ret3 capDriverConnect(m_capwnd,index);
if(!(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_capwndNULL;
return FALSE;
}
// Set the capture parameters
if(SetCapturePara()FALSE)
{
// log.WriteString(\n Setting capture parameters failed); capDriverDisconnect(m_capwnd); //使捕获窗口与一个捕获设备断开 return FALSE;
}
return TRUE;
} 视频捕获驱动
视频捕获必须具有视频捕获驱动才能进行其相关内容如下
视频捕获驱动的性能capDriverGetCap函数得到当前连接视频驱动的硬件性能该信息保存在CAPDRIVERCAPS结构中视频对话框每个视频驱动能够提供4个对话框来控制视频捕获和数字化处理视频对话框定义的视频压缩率和图像品质等。视频对话框都在视频捕获驱动中定义。这个四个对话框分别为Video Source对话框用于控制选择视频来源capDlgVideoSourceVideo Format对话框定义视频帧的尺寸和精度以及视频捕获卡的压缩设置(capDlgVideoFormat)Video Display对话框控制在视频捕获期间相关显示器上的显示(capDlgVideoDisplay)Video Compression对话框控制压缩和图像品质(caoDlgVideoCompression)。 语音录制
在音频的录制和播放时采用的用户界面线程来处理是CWinThread对象根据前面线程的介绍一步一步的来实现。录音用的一个CWinThread对象CAudioRec来实现,部分实现代码
LRESULT CAudioRec::OnStartRecording(WPARAM wp, LPARAM lp)
{
if(recording) return FALSE;
//打开录音设备
MMRESULT mmReturn ::waveInOpen( m_hRecord, WAVE_MAPPER, m_WaveFormatEx, ::GetCurrentThreadId(), 0, CALLBACK_THREAD);
if(mmReturn!MMSYSERR_NOERROR ) return FALSE;
if(mmReturnMMSYSERR_NOERROR )
{
for(int i0; i MAXRECBUFFER ; i)
{
//为录音设备准备缓存
mmReturn ::waveInPrepareHeader(m_hRecord,
rechead[i], sizeof(WAVEHDR));
//给输入设备增加一个缓存
mmReturn ::waveInAddBuffer(m_hRecord,
rechead[i], sizeof(WAVEHDR));
}
mmReturn ::waveInStart(m_hRecord); //开始录音
if(mmReturnMMSYSERR_NOERROR ) recordingTRUE;
}
return TRUE;
} 语音回放
相对录音而言播放就简单多了同样用的一个CWinThread对象CAudioPlay来实现部分实现代码
LRESULT CAudioPlay::OnWriteSoundData(WPARAM wParam, LPARAM lParam)
{
// TRACE(CAudioPlay::OnWriteSoundData\n);
MMRESULT mmResult FALSE;
char *pNULL;
int length(int) wParam;
if(PlayingFALSE) return FALSE;
if(length0) return FALSE;
WAVEHDR *lpHdrnew WAVEHDR;
if(!lpHdr) return FALSE;
pnew char [length];
if(!p) {delete lpHdr; return FALSE;}
ZeroMemory(lpHdr,sizeof(WAVEHDR));
ZeroMemory(p,length);
CopyMemory(p,(char*)lParam,length);
lpHdr-lpDatap;
lpHdr-dwBufferLength length;
mmResult ::waveOutPrepareHeader(m_hPlay, lpHdr, sizeof(WAVEHDR));
//为回放设备准备内存块
if(mmResult)
{
delete lpHdr;delete p;
return mmResult;
}
mmResult ::waveOutWrite(m_hPlay, lpHdr, sizeof(WAVEHDR));//写数据(放音)
if(mmResult){delete lpHdr;delete p; return mmResult; }
m_Count;
return MMSYSERR_NOERROR;
}