C++編寫的程序,已經可以成功預覽到視頻了,所以接下來用C#編寫流媒體客戶端自信了不少。因爲通過C++代碼測試,可以大概瞭解難懂的回調函數運作機理,這對於C#編寫流媒體客戶端的查錯打下了良好的基礎。不過,C#調用C++封裝的DLL,重點在於數據類型的轉換。關於數據類型的轉換,網絡上有較多博文,大家可以參考,這裏直接進入C#流媒體客戶端開發了哦。
1. C#新建windowsApplication,名爲HKPlay
2. 拖入button,picturebox 控件(或EditBox控件,這裏做測試,URL固定)
3. 新建類,命名hkclient.cs,編寫導入海康client.dll接口函數
using System.Runtime.InteropServices;
namespace HKPlay
{
public interface IHikClientAdviseSink
{
int OnPosLength(UInt32 nLength);
int OnPresentationOpened(int success);
int OnPresentationClosed();
int OnPreSeek(UInt32 uOldTime, UInt32 uNewTime);
int OnPostSeek(UInt32 uOldTime, UInt32 uNewTime);
int OnStop();
int OnBegin(UInt32 uTime);
int OnRandomBegin(UInt32 uTime);
int OnContacting(string pszHost);
int OnPutErrorMsg(string pError);
int OnBuffering(UInt32 uFlag, UInt16 uPercentComplete);
int OnChangeRate(int flag);
int OnDisconnect();
};
public delegate int pDataRec(int sid, int iusrdata, int idatatype, IntPtr pdata, int ilen);
public delegate int pMsgBack(int sid, int opt, int param1, int param2);
public class hkclient
{
#region
[DllImport("client.dll",
SetLastError = true)]
public static extern int InitStreamClientLib();
[DllImport("client.dll")]
public static extern int FiniStreamClientLib();
[DllImport("client.dll",
SetLastError = true)]
public static extern int HIKS_CreatePlayer(IHikClientAdviseSink pSink, IntPtrpWndSiteHandle, pDataRec pRecFunc, pMsgBack pMsgFunc, int TransMethod);
[DllImport("client.dll",
SetLastError = true, CharSet = CharSet.Ansi)]
public static extern int HIKS_OpenURL(int hSession, string pszURL, int iusrdata);
//public
static extern int HIKS_OpenURL(int hSession, byte[] pszURL, int iusrdata);
[DllImport("client.dll",
SetLastError = true, CharSet = CharSet.Auto)]
public static extern int HIKS_Play(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_RandomPlay(int hSession, int timepos);
[DllImport("client.dll")]
public static extern int HIKS_Pause(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_Resume(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_Stop(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_GetCurTime(int hSession, ref ushort uTime);
[DllImport("client.dll")]
public static extern int HIKS_ChangeRate(int hSession, int H_scale);
[DllImport("client.dll")]
public static extern int HIKS_Destroy(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_GetVideoParams(int hSession, ref int ibri, ref int icon,ref int isat, ref int ihue);
[DllImport("client.dll")]
public static extern int HIKS_SetVideoParams(int hSession, int ibri, int icon, int isat,int ihue);
[DllImport("client.dll")]
public static extern int HIKS_PTZControl(int hSession, ushort ucommand, int iparaml, intiparam2, int iparam3, int iparam4);
[DllImport("client.dll")]
public static extern int HIKS_SetVolume(int hSession, ushort volume);
[DllImport("client.dll")]
public static extern int HIKS_OpenSound(int hSession, bool bExclusive);
[DllImport("client.dll")]
public static extern int HIKS_CloseSound(int hSession);
[DllImport("client.dll")]
public static extern int HIKS_ThrowBFrameNum(int hSession, uint nNum);
[DllImport("client.dll")]
public static extern int HIKS_GrabPic(int hSession, string szPicFileName, ushortbyPicType);
#endregion }
}
4. 窗體Form1.cs添加如下代碼
using System.Runtime.InteropServices;
namespace HKPlay
{
public partial class Form1 : Form,IHikClientAdviseSink
{
在Form1.cs實現接口IHikClientAdviseSink
#region IHikClientAdviseSink
int IHikClientAdviseSink.OnPosLength(UInt32 nLength)
{
return 0;
}
int IHikClientAdviseSink.OnPresentationOpened(int success)
{
m_opened = success;
return 0;
}
int IHikClientAdviseSink.OnPresentationClosed()
{
return 0;
}
int IHikClientAdviseSink.OnPreSeek(UInt32 uOldTime, UInt32 uNewTime)
{
return 0;
}
int IHikClientAdviseSink.OnPostSeek(UInt32 uOldTime, UInt32 uNewTime)
{
return 0;
}
int IHikClientAdviseSink.OnStop()
{
return 0;
}
int IHikClientAdviseSink.OnBegin(UInt32 uTime)
{
return 0;
}
int IHikClientAdviseSink.OnRandomBegin(UInt32 uTime)
{
return 0;
}
int IHikClientAdviseSink.OnContacting(string pszHost)
{
return 0;
}
int IHikClientAdviseSink.OnPutErrorMsg(string pError)
{
return 0;
}
int IHikClientAdviseSink.OnBuffering(UInt32 uFlag, UInt16 uPercentComplete)
{
return 0;
}
int IHikClientAdviseSink.OnChangeRate(int flag)
{
return 0;
}
int IHikClientAdviseSink.OnDisconnect()
{
return 0;
}
#endregion
5. 在Form1.cs中初始化添加InitStreamClientLib(),關閉窗口添加FiniStreamClientLib()
6. 編寫Button事件
int nRet;
string pszURL = "rtsp://15.12.111.70/15.12.111.40:8000:HIK-DS8000HC:11:0:admin:12345/av_stream";
if (m_hSesssion >=
0)
{
nRet
= hkclient.HIKS_Stop(m_hSesssion);
m_opened
= -1;
}
pDataRec MypDataRec
= new pDataRec(pDataRec1); ///回調函數在C#創建委託,需實例化
pMsgBack
MypMsgBack = new pMsgBack(pMsgBack1);
m_hSesssion = hkclient.HIKS_CreatePlayer(null,
pictureBox1.Handle, MypDataRec,MypMsgBack,
0);
if (m_hSesssion !=
-1)
{
nRet
= hkclient.HIKS_OpenURL(m_hSesssion, pszURL, 0);
if
(nRet != 1)
{
hkclient.HIKS_Destroy(m_hSesssion);
m_hSesssion
= -1;
m_opened
= -1;
return;
}
}
while (m_opened <
0)
{
Thread.Sleep(100);
}
nRet =
hkclient.HIKS_Play(m_hSesssion);
if (nRet != 1)
{
hkclient.HIKS_Stop(m_hSesssion);
m_hSesssion
= -1;
m_opened
= -1;
}
7. 編寫回調函數
#region pDataFunc ,pMsgBack
private int pDataRec1(int sid, int iusrdata,
int idatatype, IntPtr pdata, int ilen)
{
using (FileStream
fs = new FileStream("D:\\1.264", FileMode.OpenOrCreate))
{
BinaryWriter
bw = new BinaryWriter(fs);
byte[]
bytefs = new byte[ilen];
Marshal.Copy(pdata,
bytefs, 0, ilen);
bw.Write(bytefs);
bw.Flush();
bw.Close();
}
return 0;
}
private
int pMsgBack1(int sid, int opt, int param1, int param2)
{
Console.WriteLine("msgBack:sid={0},opt={1},param1={2},param2={3}",
sid, opt, param1, param2);
//int len = -1;
switch (opt)
{
case
1:
break;
case
2:
m_opened
= param1;
break;
case
3:
break;
case
4:
break;
case
5:
break;
case
6:
break;
case
7:
// this.m_Pause
= 1;
break;
case
8:
break;
case
9:
break;
case
10:
break;
case
11:
break;
case
12:
break;
case
13:
break;
case
14:
break;
default:
break;
}
return 0;
}
#endregion
注意:
(1)將client.dll,playm4.cll放到debug目錄下,playCtrl.dll放到與bin同目錄中。