文章分类:网络、视频,聊天
文章作者:廖长科
(转贴请注明原创作者)
笔者序:也许在写这编文章时,有很多朋友正被老板要求做类似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