基于vfw的局域网语音聊天室系统源码论文

news/2024/4/25 18:46:30/文章来源:https://blog.csdn.net/2301_76965813/article/details/130326171
    1. 语音视频聊天
      1. UDP套接字的运用

在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。

 

图10 UDP套接字的使用

      1. 视频的捕获

利用VFW接口,视频捕获可以分为以下几个步骤:

  1. 建立视频采集窗口:该窗口用来接收视频捕捉驱动程序传来的数据和消息。
  2. 连接视频驱动程序:将建立的视频捕捉窗口与视频设备驱动程序相连。
  3. 视频捕获初始化。
  4. 视频捕捉设置:VFW下视频捕捉参数的设置可以通过调用函数或弹出对话框的形式来实现。一般视频驱动程序允许设置的参数包括视频源选择、视频格式、视频显示格式等。
  5. 设置回调函数:通过回调函数来通知程序视频事件的发生,比如捕捉一帧图像成功的消息,捕捉出错的消息等。
  6. 结束捕捉:结束捕捉是应该有一些清除工作。如释放分配的内存,断开捕捉窗口与视频捕捉驱动程序的连接,清除视频捕捉窗口等。

窗口类为捕获数字视频流及其相关操作提供了很大的方便,灵活编写其中的回调函数可满足实时视频传输的需要,例如应用程序可直接从缓冲中取得数字视频并对其进行压缩编码后实时地传到远端的客户端。

在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.biWidth=IMAGE_WIDTH;

m_bmpinfo.bmiHeader.biHeight=IMAGE_HEIGHT;

BOOL ret=capSetVideoFormat(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;

}

      1. 捕获窗口

在捕获前必须创建一个捕获窗口(Capture Widnow),下面介绍有关捕获窗口的情况:创建一个AVICap捕获窗口,用capCreateCaptureWindow函数并返回一个句柄。将捕获窗口连接至捕获设备,用capDriverConnect函数来使一个捕获窗口与一个捕获设备连接或关联连接上后,就可以通过捕获窗口向捕获设备发送各种消息,可以使用函数capGetDriverDescription来获得已安装的捕获设备名称及版本,将其列举在实现程序过程中。再利用capDriverGetName函数来得到捕获设备的名称将获得的版本发送到capDriverGetVersion。如果断开捕获窗口与捕获设备的连接用capDriverDisconnect。

捕获窗口的状态,用capGetStatus函数来获得当前捕获窗口的状态,得到一个CAPSTATUS结构的拷贝。该结构的内容包含了图片的尺寸、卷轴的当前位置、overlay和preview是否已设置。由于其信息是动态的,每当捕获的视频流的尺寸发生改变,程序应该在获取捕获设备的视频格式以后及时进行刷新。而捕获窗口尺寸的改变并不影响实际的捕获视频流的尺寸。该尺寸由视频捕获设备的格式和视频对话框决定。

//捕获窗口

BOOL VideoCapture::Initialize()

{

 char devname[128]={0},devversion[128]={0};

     int index=0;

     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_capwnd=NULL;

return FALSE;

}

// Set the capture parameters

if(SetCapturePara()==FALSE)

{

//   log.WriteString("\n Setting capture parameters failed");

     capDriverDisconnect(m_capwnd); //使捕获窗口与一个捕获设备断开

     return FALSE;

}

return TRUE;

}

      1. 视频捕获驱动

视频捕获必须具有视频捕获驱动才能进行,其相关内容如下:

视频捕获驱动的性能,capDriverGetCap函数得到当前连接视频驱动的硬件性能,该信息保存在CAPDRIVERCAPS结构中;视频对话框,每个视频驱动能够提供4个对话框来控制视频捕获和数字化处理视频对话框定义的视频压缩率和图像品质等。视频对话框都在视频捕获驱动中定义。这个四个对话框分别为:Video Source对话框用于控制选择视频来源(capDlgVideoSource);Video Format对话框定义视频帧的尺寸和精度,以及视频捕获卡的压缩设置(capDlgVideoFormat);Video Display对话框控制在视频捕获期间相关显示器上的显示(capDlgVideoDisplay);Video Compression对话框控制压缩和图像品质(caoDlgVideoCompression)。

      1. 语音录制

在音频的录制和播放时,采用的用户界面线程来处理,是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(mmReturn==MMSYSERR_NOERROR )

{

for(int i=0; i < MAXRECBUFFER ; i++)

{

//为录音设备准备缓存

mmReturn = ::waveInPrepareHeader(m_hRecord,

rechead[i], sizeof(WAVEHDR));

//给输入设备增加一个缓存

mmReturn = ::waveInAddBuffer(m_hRecord,

rechead[i], sizeof(WAVEHDR));

}

mmReturn = ::waveInStart(m_hRecord);   //开始录音

if(mmReturn==MMSYSERR_NOERROR ) recording=TRUE;

}

return TRUE;

}

      1. 语音回放

相对录音而言,播放就简单多了,同样用的一个CWinThread对象CAudioPlay来实现,部分实现代码:

LRESULT CAudioPlay::OnWriteSoundData(WPARAM wParam, LPARAM lParam)

{

// TRACE("CAudioPlay::OnWriteSoundData\n");

MMRESULT mmResult = FALSE;

char *p=NULL;

int length=(int) wParam;

if(Playing==FALSE) return FALSE;

if(length<=0) return FALSE;

WAVEHDR *lpHdr=new WAVEHDR;

if(!lpHdr) return FALSE;

p=new char [length];

if(!p) {delete lpHdr;

     return FALSE;}

ZeroMemory(lpHdr,sizeof(WAVEHDR));

ZeroMemory(p,length);

CopyMemory(p,(char*)lParam,length);

lpHdr->lpData=p;

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;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102298.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32在SDIO模式下SD写入错误的问题

1、问题描述 使用FAT32 f_write 多次执行写操作时&#xff0c;会报FR_DISK_ERR错误&#xff0c;而且是刚开始写不报错&#xff0c;写几次后会一直报错。 设断点跟踪到HAL_SD_WriteBlocks中&#xff0c;在调用SDMMC_CmdWriteMultiBlock时&#xff0c;会报SDMMC_ERROR_TX_UNDERR…

【MYSQL】Java的JDBC编程(idea连接数据库)

1. 配置 &#xff08;1&#xff09;新建一个项目 &#xff08;2&#xff09;Build System 那里选择Maven,下一步Create &#xff08;3&#xff09;配置pom.xml文件 首先查看自己的MYSQL版本&#xff1a;进入MySQL命令窗口 我的MYSQL版本是8.0版本的. 下一步&#xff0c;…

C/C++占位符,%x和%p的区别

遇到的问题 今天遇到了一个很奇怪的问题&#xff0c;当使用malloc分配了一个堆空间后&#xff0c;分别尝试用cout和printf尝试打印该地址&#xff0c;出现了两个地址不一样的情况&#xff1a; int *pp (int*)malloc(10*sizeof(int)); *pp 1234; cout << pp << …

常用数据加密

一、加密和解密 1、 加密 数据加密的基本过程&#xff0c;就是对原来为明 的文件或数据按某种算法进行处理&#xff0c;使其成为不可读的一段代码&#xff0c;通常称为 “密文”。通过这样的途径&#xff0c;来达到保护数据不被 非法人窃取、阅读的目的。 2、解密 加密的逆…

2023年,人工智能和数据训练呈现哪些新趋势?

最近&#xff0c;多才多艺的“全能网友”ChatGPT一次次火出圈。未来人工智能将以多快的速度、发展到何种地步&#xff1f;人们已经开始坐下来认真地探讨和思考。 我们生活在这个日新月异的时代。新的一年&#xff0c;人工智能的真正能力和应用场景又发生了哪些演进&#xff1f;…

Java性能优化之序列化优化

1、Java 序列化及其缺陷 Java 提供了一种序列化机制&#xff0c;这种机制能够将一个对象序列化为二进制形式&#xff08;字节数组&#xff09;&#xff0c;用于写入磁盘或输出到网络&#xff0c;同时也能从网络或磁盘中读取字节数组&#xff0c;反序列化成对象&#xff0c;在程…

java Excel清除表格条件格式规则

© Ptw-cwl 目录 文章目录 目录Excel清除表格条件格式规则1.开始 -> 条件格式2.条件格式 -> 清除规则3.管理规则也能删除 代码报java.lang.IllegalArgumentException: Specified CF index 43 is outside the allowable range (0..42)如何解决源码 Excel清除表格条件…

GitHub 开源神器 Bark模型,让文本转语音更简单

今天跟大家分享一个文本转语音的开源模型&#xff1a;Bark Bark 是由Suno创建的基于转换器的文本到音频模型。Bark 可以生成高度逼真的多语言语音以及其他音频 - 包括音乐、背景噪音和简单的音效。该模型还可以产生非语言交流&#xff0c;如大笑、叹息和哭泣。 该项目刚开源不…

JQuery-原理示意图-- 选择器-- 选择器综合代码--jQuery 的 DOM 操作--增删改查节点--常用遍历节点方法--多选框应用--全部综合代码

目录 JQuery 基本介绍 jQuery 的原理示意图 JQuery 基本开发步骤 说明: jQuery简单示例 jQuery 对象和 DOM 对象 什么是 jQuery 对象 DOM 对象转成 jQuery 对象 应用实例 jQuery 对象转成 DOM 对象 代码演示 jQuery 选择器 jQuery 选择器介绍 jQuery 选择器的优…

根据cadence设计图学习硬件知识 day03 了解 一些芯片 和 数据手册下载的地方

1. MT53D512M32D2DS 芯片&#xff08;动态随机存取存储器&#xff09;的技术指标 1.1 16n Prefetch (预加载) (n --芯片位宽) DDR 体系 链接&#xff1a;DDR扫盲—-关于Prefetch(预取)与Burst(突发)的深入讨论_ddr prefetch_qq_25814297-npl的博客-CSDN博客 1.2 每个通…

webhub123 前端技术社区和技术交流学习网站导航

整理了学习前端技术可以参考学习和技术交流的一些网站集合&#xff0c;全部收录到 webhub123 前端技术社区和技术交流学习网站导航http://​www.webhub123.com/#/home/detail?projectHashid30929575&ownerUserid22053727 整理后的效果如下&#xff0c;我们已经按照不同类…

【Springboot系列】Springboot整合Swagger3不简单

1、缘由 Swagger是一个根据代码注解生成接口文档的工具&#xff0c;减少和前端之间的沟通&#xff0c;前端同学看着文档就可以开发了&#xff0c;提升了效率&#xff0c;之前很少写swagger&#xff0c;这次自己动手写&#xff0c;还是有点麻烦&#xff0c;不怎么懂&#xff0c;…

vue3中其他的变化

1.全局API的转移 Vue 2.x 有许多全局 API 和配置。 - 例如&#xff1a;注册全局组件、注册全局指令等。 //注册全局组件 Vue.component(MyButton, {data: () > ({count: 0}),template: <button click"count">Clicked {{ count }} times.</button> …

[读书笔记] 从问题和公式角度理解 Diffusion Model

[小全读书笔记] 从问题和公式角度理解 Diffusion Model 1. Diffusion Model的结构1.1 定义与限制1.2 定义与限制的数学体现 2. Diffusion Model的模型训练2.1 似然函数转换成ELBO2.2 拆解ELBO2.3 求解关键&#xff1a; q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t,x_0) q(xt−1…

CompletableFuture的基本使用和原理

CompletableFuture CompletableFuture是对Future的扩展和增强。CompletableFuture实现了Future接口&#xff0c;并在此基础上进行了丰富的扩展&#xff0c;完美弥补了Future的局限性&#xff0c;同时CompletableFuture实现了对任务编排的能力。借助这项能力&#xff0c;可以轻…

web事件循环

事件循环的应用&#xff1a;计时器 promise ajax node 单线程是异步产生的原因&#xff0c;事件循环时异步的实现方式 1.浏览器进程模型 进程&#xff1a;程序运行需要自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程。 每个应用至少又一个进程&#xff…

模板方法设计模式解读

目录 豆浆制作问题 模板方法模式基本介绍 基本介绍 模板方法模式的原理类图 模板方法模式解决豆浆制作问题 应用实例要求 思路分析和图解(类图) 模板方法模式的钩子方法 模板方法模式的注意事项和细节 豆浆制作问题 编写制作豆浆的程序&#xff0c;说明如下: 1) 制作豆…

【LeetCode】剑指 Offer 67. 把字符串转换成整数 p318 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/ 1. 题目介绍&#xff08;67. 把字符串转换成整数&#xff09; 写一个函数 StrToInt&#xff0c;实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 …

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案

研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 目录 研究生考试 之 计算机网络第七版(谢希仁) 第一章 课后答案 一、简单介绍 二、计算机网络第七版(谢希仁) 第一章 课后答案 1、 计算机网络向用户可以提供哪些服务&#xff1f; 2、 试简述分组交换的要点。 3…

Kali下部署-Nessus漏扫工具

Nessus 是全世界最多人使用的系统漏洞扫描与分析软件。总共有超过75,000个机构使用Nessus 作为扫描该机构电脑系统的软件。 特点&#xff1a; 1、提供完整的电脑漏洞扫描服务&#xff0c;并随时更新漏洞库。 2、可以在本机或者是远端上进行遥控&#xff0c;进行系统的漏洞扫…