天天看点

C# 视频监控系列(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文章里面我们也能看到这样的说明。这段代码最好在窗体关闭的时候也加上!!

下一篇: SSH使用指南

继续阅读