天天看點

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

繼續閱讀