前言
近一个星期在写服务器端,一直没有成功,就没有继续往下写文章,可喜的是这一局面在今天下午得到改变(客户端已经能够连接我自己写的服务器端了!),顺便说下客户端大概2-3篇文章,接下来就会写关于服务器的文章了,感谢关注,也希望能帮助得到你: )
推荐文章
注意
本系列文章限于学习交流,注重过程,由于涉及公司,所以不提供源代码下载,非常抱歉!!但是请大家放心,核心、实现以及其他能够贴出来的代码我都会贴出来,并且争取尽所能的回答评论里的每一个问题,感谢大家关注,欢迎交流 :)
系列
正文
1. 将以下四个dll拷贝到system32目录下,这几个文件均在根目录的bin目录下
ds40xxsdk.dll
hikclient.dll
hikplaym4.dll
hikserver.dll
2. 先用自带的客户端net client demo(soft decdoe)运行下确认没有问题再根据vc++客户端的例子写对应的c#代码。
3. 最好装一个microsoft visual c++ 6.0,这样能把vc++的例子跑起来并调试。注意他是win32 release的,需要切换至win32 debug模式才能断点调试!!
4. 打开api文档hikvision 板卡网络开发包编程手册v4.7,在doc目录下。
5. 代码分析和编写对应的c#代码
5.1 第二章编程说明中第六条我们可以看到api依次调用的顺序,可以根据函数名直接在代码中搜索调用顺序,不难发现,在hkvisiondlg.cpp的oninitdialog方法能看到如下两行代码:
mp4_clientsetnetport(5050,6050);
mp4_clientstartup(wm_mycommand,this->m_hwnd);
很明显这是调用了api,其他代码就不用管了,那么我把这代码翻译到c# winform的form1_load事件里面,并且也这样调用api(封装好的sdk请看上篇文章):
pchikclient.mp4_clientsetnetport(5050, 6050);
pchikclient.mp4_clientstartup(pchikclient.wm_user + 1, this.handle);
5.2 根据界面上start按钮事件能找到关键的连接上服务器,如下:

if (m_showmode == 0)
{
mp4_clientsetshowmode(normalmode,0);
}
else
mp4_clientsetshowmode(overlaymode,colorref(0xff00ff));
nn1=nn2=nn3=nn4 = -1;
int itemp = m_shownum;
char ips[256];
sprintf(ips,"%s",m_ipadd);
hwnd5 = m_video5.getsafehwnd();//
aa5.m_bremotechannel = 0;
switch(m_linktype)
case 0:
aa5.m_bsendmode = tcpmode;
break;
case 1:
aa5.m_bsendmode = udpmode;
case 2:
aa5.m_bsendmode = multimode;
case 3:
aa5.m_bsendmode = dialing;
case 4:
aa5.m_bsendmode = audiodetach;
default:
aa5.m_sipaddress = ips;
//2003.12.2
//如果想只录像,而不进行解码,可以将m_hshowvideo设置成null
//if you just want to record without decode on client side,
//please set m_hshowvideo as null
#if defined record_only
aa5.m_hshowvideo = null;
#else
aa5.m_hshowvideo = hwnd5;
#endif
// add 2003.12.2
//m_nimgformat 指明想要获取的图像格式
//依赖服务器端的设置。如果不设置,获取的是服务器的缺省格式
//m_nimgformat indicates the picture format you get on the client side,
//it depends on the setting of server side.
aa5.m_nimgformat = 0; // request cif format
// aa5.m_nimgformat = 1; // request qcif format
aa5.m_susername = "123";
aa5.m_suserpassword="w";
aa5.m_busercheck = true;
mp4_clientsetttl(64);
nn1 = mp4_clientstart(&aa5,readdatacallback);
if (nn1 == -1)
messagebox("error");
return;
//
bool breturn;
breturn = mp4_clientrigisterdrawfun(nn1,drawfun,0);
switch(m_delaytype)
mp4_clientsetbuffernum(nn1,40);
mp4_clientsetplaydelay(nn1,580);
mp4_clientsetbuffernum(nn1,15);
mp4_clientsetplaydelay(nn1,40);
mp4_clientsetplaydelay(nn1,0);
mp4_clientsetbuffernum(nn1,0);
// mp4_clientthrowbframe(nn1,m_bframenum);
mp4_clientsetcappiccallback(nn1,cappicfun);

有vc++代码可以看得出来接下来代码都和这差不多,应该就是初始化显示四个窗口的代码了,那我们就不需要把这个方法里面的代码全部翻译了,只需要达到连接一个视频窗口的目的就可以了,翻译的过程中可以自己先临时设置一些变量来让代码跑起来,翻译过程中每次都执行到mp4_clientrigisterdrawfun方法的时候就报错了,但是画面确已经出来了,所有我就从这里截断了,先达到目的再说,请看翻译对象的c#代码:

int cs;
private void button1_click(object sender, eventargs e)
{
client_videoinfo cvideo = new client_videoinfo();
//对应服务端通道号
cvideo.m_bremotechannel = (byte)0;
//网络连接模式
cvideo.m_bsendmode = (byte)send_mode.tcpmode;
//服务端ip地址
cvideo.m_sipaddress = "192.168.0.188";
//显示区域
cvideo.m_hshowvideo = pvideo.handle;//(intptr)null;
//图像格式
cvideo.m_nimgformat = (byte)0;
//用户名
cvideo.m_susername = "123";
//密码
cvideo.m_suserpassword = "w";
//是否需要发生密码
cvideo.m_busercheck = true;
//设置多播的ttl参数
pchikclient.mp4_clientsetttl((char)64);
//启动客户端
cs = pchikclient.mp4_clientstart(ref cvideo, new readdatacallback(myrealdatacallback1));
}
private void myrealdatacallback1(ulong port, [marshalas(unmanagedtype.lparray)] byte[] pbuffer, ulong psize)
messagebox.show(pbuffer.length.tostring());

需要注意的是,vc++里面的指针类型,如hwnd一般可以对应c#里面的intptr数据类型,readdatacallback是回调函数,但是没有执行,不过至此画面已经能够显示出来!!
那么接下来做画面切割,右键事件什么的都只需要你winform的开发经验了,我是用的四个面板(panel)切换隐藏显示的;pvideo是panel控件;用户名和密码随便设置也能连得上。
5.3 关闭连接
同样找到vc++代码:
if (nn1 >= 0)
mp4_clientstopcapture(nn1);
mp4_clientstop(nn1);
对应c#代码:
private void close()
pchikclient.mp4_clientstopcapture(cs);
pchikclient.mp4_clientstop(cs);
pvideo.invalidate(true);
需要注意的是这个cs变量,在连接的时候mp4_clientstart返回值,需要拿全局变量保存起来,以便这里关闭的时候需要,从api文章里面我们也能看到这样的说明。这段代码最好在窗体关闭的时候也加上!!
摘抄:
在piii 833的计算机上,可以比较流畅的软解码4路普通的实时图象;在piv 2g的计算机上,可以比较流畅的软解码8-9路普通的实时图象;如果用我们公司的硬解码卡,只要显卡支持overlay功能,就可以支持最多达24路的实时图象,并且支持videoout功能,可以上电视墙。
结束
如果本文能带你实现预览的功能,将使你信心百倍,效果才是最有说服力的,并祝你好运: )
转载:http://www.cnblogs.com/over140/archive/2009/02/23/1396571.html