天天看点

C# 视频监控系列(3):客户端——连接服务器并预览

前言

     近一个星期在写服务器端,一直没有成功,就没有继续往下写文章,可喜的是这一局面在今天下午得到改变(客户端已经能够连接我自己写的服务器端了!),顺便说下客户端大概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按钮事件能找到关键的连接上服务器,如下:

C# 视频监控系列(3):客户端——连接服务器并预览

    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);

C# 视频监控系列(3):客户端——连接服务器并预览

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

C# 视频监控系列(3):客户端——连接服务器并预览

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());

C# 视频监控系列(3):客户端——连接服务器并预览

          需要注意的是,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

继续阅读