首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> ASP教程
在网络上进行摄像头视频通讯_delphi教程
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

    文章分类:网络、视频,聊天
   
文章作者:廖长科
    (转贴请注明原创作者)

    笔者序:也许在写这编文章时,有很多朋友正被老板要求做类似QQ一样的视频聊天软件,在这里,我把自己的一些经验和代码写出来与大家一起分享,高手不要笑我哈!看了这编文章后,你也可以自己做一个简单的网络视频通讯软件,如果自己家里上了网,就可以在公司和家人进行可视通讯了,多爽,不用给电话费了。

      本例子使用的是简的老技术(VFW),开发起来相对简单,以下是Delphi代码,你需要先加入VFW.PAS文件,没有这个文件你可以在网上找一下。作者从Delphi4就开始编程,其实Delphi可以做很多事情,只是太多Delphi程序员没有深专技术和思想,没有超越自己,Delphi只是一个开发工具,代码思想是的设计的精髓。
      下面让我们一起来讲解一下:

      在程序的开始,你需要用capCreateCaptureWindow来创建一个摄像头句柄,
      CapWnd := capCreateCaptureWindow(预览窗口,WS_VISIBLE or WS_CHILD,0,0,320,240,PrevWnd,1);
      在后面的参数:PrevWnd代表预览窗口的句柄,你可以指定一个Panel的句柄;320和240代表了窗口的长宽。
    
      if CapWnd = 0 then exit;
      capDriverConnect(CapWnd,0);   //连接摄像头设备

      capDlgVideoFormat(CapWnd);  //显示视频设置对话框,进行配置视频的大小、颜色位数等。
      capGetVideoFormat(CapWnd,@BmpInInfo,sizeof(BITMAPINFO));  //取得视频图像数据头,后面压缩时需要用到

      capPreviewRate(CapWnd, 33);  //设置预览视频的频率,33代表第秒30帧。
      capPreview(CapWnd, TRUE);

      capSetCallbackOnFrame(CapWnd,FrameCallBack); 
     
      InitCaptureParams;
     
      最后一句是设置视频压缩参数, 后面会进行说明。其中的capSetCallbackOnFrame(CapWnd,FrameCallBack)是设置每帧视频数据的回调函数,我们就可以将回调时的视频数据通过网络进行传输,这样的就实现了视频聊天的核心了。

    回调函数如下的格式:

    function  FrameCallBack(hWnd: HWND; lpVHdr: PVIDEOHDR): DWORD; stdcall;
    var
       bKeyFrame : BOOL ;
       Buf : PBYTE;
       VideoData : TVIDEO_DATA;
       OutActSize : dword;
       i : integer;
    begin
       OutActSize := BmpInInfo.bmiHeader.biSizeImage;
       Buf := ICSeqCompressFrame(@CapVar,0,lpVHdr.lpData,@bKeyFrame,@OutActSize);
      
       //在这里, OutActSize代表压缩后的视频数据大小
       //  form1.Label3.Caption := Compressed size:+inttostr(OutActSize);


       //我用的是UDP方式, 因为UDP数据包大小限制, 所以我控制了数据大小, 超出的数据会发生丢帧
       if (OutActSize <= sizeof(videodata.Buf) ) then
       begin
         zeromemory(@VideoData ,sizeof(TVIDEO_DATA));
        
         //记录是否为关键帧
         VideoData.bKeyFrame:=bKeyFrame;


         copymemory(@VideoData.Buf, Buf, OutActSize);
        
         VideoData.SampleNum:=SampleNum; //我们可以记录下帧数, 可以做扩展用
         VideoData.BufSize:=OutActSize;  //记录数据大小, 传输时用
        
         //在这里, 你可以用你喜欢的网络方式传输视频数据,
        
         //cc1.SendBuffer(VideoData,sizeof(TVIDEO_DATA)-SendBufferSize+Outactsize);

         inc(SampleNum);
       end;     
       result := 0;
    end;

    其中,PVIDEOHDR类型可以从VFW中看到其定义:
    TVIDEOHDR               = record
        lpData              : PBYTE;  // 视频数据buffer
        dwBufferLength      : DWORD;  // 数据buffer长度
        dwBytesUsed         : DWORD;               
        dwTimeCaptured      : DWORD;  // 时间长度(毫秒)
        dwUser              : DWORD;               
        dwFlags             : DWORD;               
        dwReserved          : array[0..3] of DWORD;
    end;
    
    在回调函数中, 只用到了视频函数: ICSeqCompressFrame,可以看到此函数传入了CapVar参数,这个参数是由我们先前看到的InitCaptureParams函数产生,下面代码来实现:
    function InitCaptureParams : boolean;
    begin
      result := False;
 
      //初始化CapVar
      zeromemory(@CapVar,sizeof(TCOMPVARS));

      CapVar.cbSize:=sizeof(CapVar); //必须指定cbSize为TCOMPVARS结构大小
      CapVar.dwFlags:=ICMF_COMPVARS_VALID;

      CapVar.cbState:=0;
 
      //fccHandler代表压缩编码类型,我们使用的是DIVX的编码器
      CapVar.fccHandler:=mmioFOURCC(d,i,v,x);
      CapVar.fccType:=ICTYPE_VIDEO;

     
      //正式连接编码器
      CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS);
    
      if (CapVar.hic>0) then
      begin

        OutFormatSize:=ICCompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);
        getmem(BmpOutInfo,OutFormatSize);
        
        //我们可以通过初始化时得到的BmpInInfo来获取压缩传出图像头BmpOutInfo
        ICCompressGetFormat(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
        OutBufferSize:=ICCompressGetSize(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
        ICSeqCompressFrameStart(@CapVar, @BmpInInfo);
        result := True;
      end
      else
      begin
        ShowMsg(请先安装视频压缩编码器);
        Exit;
      end
    end;

    使用之后,如果要断开编码器连接,是这样调用的:
    if (CapVar.hic > 0) then
    begin
       ICSeqCompressFrameEnd(@CapVar);
       ICCompressorFree(@CapVar);
       ICClose(CapVar.hic);
    end;

    于是,服务端的摄像头数据捕捉连接就完成了,那么对于客户端是乍样进行视频数据解压呢?这个问题当然还是通过IC函数解决,但你必须先把服务端上的BmpOutinfo和CapVar传输到客户端才行。
   
    接着,一起来看看客户端的图像显示过程:
    //先用取得的CapVar来连接视频编码器
    CapVar.hic := ICOpen(CapVar.fccType,CapVar.fccHandler,ICMODE_DECOMPRESS);
   
    //成功后,用服务器传来的BmpOutInfo当作客户端的BmpInInfo来取得解压输出的图像头BmpOutInfo

    OutFormatSize:=ICDecompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);
    GetMem(BmpOutInfo,OutFormatSize);
    zeromemory(BmpOutInfo,OutFormatSize);

    ICDecompressGetFormat(CapVar.hic, @BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);

    OutBufferSize:=BmpOutInfo^.bmiHeader.biSizeImage;
    getmem(OutBuffer,OutBufferSize);

    zeromemory(OutBuffer,OutBufferSize);
    ICDecompressBegin(CapVar.hic,@BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);


    最后,当然是视频数据的解压过程

    if VIDEO_DATA.bKeyFrame then
       Result:=ICDecompress(CapVar.hic,0,@BmpInInfo,@VIDEO_DATA.Buf,
                   @BmpOutInfo.bmiHeader,OutBuffer)
    else
       Result:=ICDecompress(CapVar.hic,ICDECOMPRESS_NOTKEYFRAME,@BmpInInfo,@VIDEO_DATA.Buf,
                   @BmpOutInfo.bmiHeader,OutBuffer);
    if (Result=ICERR_OK) then
    begin
       SetDIBitsToDevice(Canvas.Handle,0,0,bmptmp.Width,bmptmp.Height,0,0,0,BmpOutInfo^.bmiHeader.biHeight ,
                  OutBuffer,BmpOutInfo^,DIB_RGB_COLORS);
    end;

    这样,传送过来的视频数据变直接画到了Canvas.Handle上了。
    还忘记了服务端关闭摄像头的方法,调用capDriverDisconnect(CapWnd) 就OK了。

    全文就Over了,jasonke还要说的就是,这个方法是用的微软的老函数,不过实现起来很简单,相信会点API的都能开发出来,还有一种方法当然是用DirectShow了哟,这需要你开发Filter,要搞明白微软的几个接口,你可以看看DShowNetwork例子。这个方法也有很多C++的兄弟在痛苦的实现,想一想DirectShow的功能真是强大哟,哈哈。

欢迎大家光临《黑雨共享软件》,谢谢大家对中国共享软件的支持

http://brsoft.0033.cn 
http://brsoft.008.net


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·在ASP.NET中使用Office Web Components (OWC)创建统计图-.NET教程,数据库应用
·windows系统下jsp+mysql+tomcat的配置-JSP教程,Application/Applet
·把aspx文件编译成DLL文件-.NET教程,Asp.Net开发
·Haneng.com的简单留言板制作源程序例子-ASP教程,ASP应用
·使用VB实现邮箱自动注册(一):表单自动提交-.NET教程,VB.Net语言
·VS.NET安装指南(To菜鸟)-.NET教程,Asp.Net开发
·web下水晶报表的使用!-.NET教程,Web Service开发
·C# 静态成员和方法的学习小结-.NET教程,数据库应用
·IIS的使用-ASP教程,ASP基础
·asp讲座之二:读取通过表单发送的数据
最新文章
·photoshop鼠绘实例:浪漫夏夜壁纸_photoshop教程
·买卖中小网站交易的一些细节问题_站长心得
·七招打造最安全的windows xp操作系统_windows xp
·做google adsense最佳和最重要的要诀_网赚技巧
·上下文关联广告清单(内文广告)推荐_网赚技巧
·广告联盟,痛定思痛_网赚技巧
·insenz首批广告费发放给站长_网赚技巧
·李彦宏:三分之一时间用在寻找人才_站长访谈
·中国汽车资源网杨锁民:网络寒冬时下海_站长访谈
·做it新闻资讯网站应先学新浪_站长心得
相关主题
西部数码虚拟主机

友情链接
CNNIC 西部数码
万网 自助建站
虚拟主机 asp空间
域名注册 域名
域名申请 主页空间
论坛空间 网站空间
国际域名 虚拟空间
空间租用 DDOS防火墙
成都主机托管 四川主机托管
主机租用 服务器租用
网站目录 自助建站
虚拟主机 网址大全
软件下载
自助链接
虚拟主机资讯 特价虚拟主机
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论 打印  刷新     关闭