目前使用的海康SDK包括IPC_SDK(硬件設備),Plat_SDK(平臺),其中兩套SDK都需單獨調用海康播放庫PlayCtrl.dll來解碼視頻流,返回視頻信息和角度信息。本文僅對視頻監控經常使用功能的使用進行說明,其它未實現功能請參看設備網絡SDK使用手冊和播放庫編程指南V7.2。前端
因爲IPC_SDK沒有SDK安裝程序,因此需手工把下面圖表中的DLL放入Debug或者Release文件夾的根目錄下供程序調用,或者加入系統環境變量Path下。編程
名稱api |
版本號數組 |
說明網絡 |
AudioIntercom.dll數據結構 |
1.1.0.5ide |
|
AudioRender.dll函數 |
1.0.0.2ui |
|
DsSdk.dllthis |
6.0.10.922 |
|
gdiplus.dll |
|
微軟庫 |
HCNetSDK.dll |
4.3.0.6 |
網絡功能調用,大量功能調用此庫 |
OpenAL32.dll |
|
|
PlayCtrl.dll |
7.2.0.0 |
播放庫,定製版本,增長返角回調及數據結構 |
QosControl.dll |
1.0.0.1 |
|
StreamTransClient.dll |
1.1.2.12 |
|
SuperRender.dll |
1.0.1.0 |
|
SystemTransform.dll |
2.4.0.3 |
設備信息轉發,根據播放庫修改過 |
首先在C#語言源程序中聲明外部方法,其基本形式是:
[DLLImport(「DLL文件」)]
修飾符 extern 返回變量類型 方法名稱 (參數列表)
例如:
using System.Runtime.InteropServices; [DllImport("HCNetSDK.dll")] public static extern bool NET_DVR_Init();
注意:
1) 須要在程序聲明中使用System.Runtime.InteropServices命名空間。 DllImport只能放置在方法聲明上。
2) DLL文件必須位於程序當前目錄或系統定義的查詢路徑中(即:系統環境變量中Path所設置的路徑)。
3) 返回變量類型、方法名稱、參數列表必定要與DLL文件中的定義相一致。
4) 若要使用其它函數名,可使用EntryPoint屬性設置,如:[DllImport("user32.dll", EntryPoint="MessageBoxA")]
static extern int MsgBox(int hWnd, string msg, string caption, int type);
5) 其它可選的 DllImportAttribute 屬性:
CharSet 指示用在入口點中的字符集,如:CharSet=CharSet.Ansi;
SetLastError 指示方法是否保留 Win32"上一錯誤",如:SetLastError=true;
ExactSpelling 指示 EntryPoint 是否必須與指示的入口點的拼寫徹底匹配,
如:ExactSpelling=false;
PreserveSig指示方法的簽名應當被保留仍是被轉換, 如:PreserveSig=true;
CallingConvention指示入口點的調用約定, 如:CallingConvention=CallingConvention.Winapi;
Win32 Types |
CLR Type |
char,INT8,SBYTE,CHAR |
System.SByte |
short,short int,INT16,SHORT |
System.Int16 |
int,long,long int,INT32,LONG32,BOOL,INT |
System.Int32 |
_int64,INT64,LONGLONG |
System.Int64 |
unsigned char,UINT8,UCHAR,BYTE |
System.Byte |
unsigned short,UINT16,USHORT,WORD,ATOM,WCHAR,__wchar_t |
System.UInt16 |
unsigned,unsigned int,UINT32,ULONG32,DWORD32,ULONG,DWORD,UINT |
System.UInt32 |
unsigned __int64,UINT64,DWORDLONG,ULONGLONG |
System.UInt64 |
float,FLOAT |
System.Single |
double,long double,DOUBLE |
System.Double |
BSTR |
StringBuilder |
LPCTSTR |
StringBuilder |
LPCWSTR |
IntPtr |
handle |
IntPtr |
hwnd |
IntPtr |
char * |
string |
int * |
ref int |
int & |
ref int |
void * |
IntPtrs |
unsigned char * |
ref byte |
BOOL —— |
bool |
DWORD |
uint或int |
注意:
例如:[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)],具體長度需參看SDK中改結構體的說明文檔
或者
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64, ArraySubType = UnmanagedType.I1)]
1) 結構體轉換爲指針
Hik.NET_DVR_IPPARACFG_V40 ipParaCfgV40 = new Hik.NET_DVR_IPPARACFG_V40();//初始化結構體結構體
Int32 size = Marshal.SizeOf(ipParaCfgV40);//返回結構體字節數
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal(size);//定義指針字節數
Marshal.StructureToPtr(ipParaCfgV40, ptrIpParaCfgV40, false);//將結構體封裝到內存指針中
//調用須要指針的方法
Marshal.FreeHGlobal(ptrIpParaCfgV40);//釋放指針
2) 指針轉換爲結構體
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg = new Hik.NET_DVR_CAMERAPARAMCFG_EX();//實例化結構體
Int32 size = Marshal.SizeOf(cameraParamCfg );//獲取結構體字節數
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//爲指針分配空間
//調用獲取指針的方法
cameraParamCfg = (Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg, typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//把指針轉換爲結構體
Marshal.FreeHGlobal(ptrCfg);//釋放指針
3) 指針轉換爲結構體精簡寫法
Int32 size = Marshal.SizeOf(typeof(Hik.NET_DVR_PTZPOS));
IntPtr ptrPTZ = Marshal.AllocHGlobal(size);
//調用獲取指針的方法
Hik.NET_DVR_PTZPOS PTZPos = (Hik.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPTZ, typeof(Hik.NET_DVR_PTZPOS));//指針轉換爲結構體
Marshal.FreeHGlobal(ptrPTZ);//釋放指針
對第2點和第3點的說明:當一個方法的參數爲一個結構體的指針時,而且執行方法後此指針會返回結構體信息時,能夠有兩種方式來初始化這個指針,第二種更爲簡潔些。
對IPC_SDK的C#封裝類見附件Hik.cs,可參考此基礎類文件進行程序功能編寫。
Hik.NET_DVR_GetLastError();//獲取錯誤碼
使用方式:若是每一個非託管函數方法返回結果爲false,則調用此方法獲取錯誤碼。
例如:
ret = Hik.NET_DVR_Init();
if (ret != true)
throw new HikException(Hik.NET_DVR_GetLastError());//HikException爲自定義異常調用類,用來解析錯誤碼拋出異常
1) 用戶註冊
Hik.NET_DVR_Init();//初始化SDK,屢次初始化會拋出錯誤
Hik.NET_DVR_SetConnectTime(2000, 1);//設置超時時間
Hik.NET_DVR_SetReconnect(10000, 1);//設置重連時間
Hik.NET_DVR_DEVICEINFO_V30 _deviceInfo = new Hik.NET_DVR_DEVICEINFO_V30();//登陸參數結構體,能夠返回設備信息
String userId = Hik.NET_DVR_Login_V30(IP,Port,UserName,Password,ref _deviceInfo);//登陸後,獲取用戶ID和設備信息供後續方法調用
2) 用戶註銷
Hik.NET_DVR_StopRealPlay(_realHandle);//若是有預覽視頻,則根據其播放句柄關閉視頻
Hik.NET_DVR_Logout(_userId);//根據用戶ID註銷用戶登陸
Hik.NET_DVR_Cleanup();//必須執行的釋放IPC_SDK
因爲IPC_SDK同時支持IPC與NVR,因此二者獲取通道號的方式有所不一樣。
1) 獲取IPC設備通道號
若是Hik.NET_DVR_DEVICEINFO_V30結構體中byChanNum模擬通道數量屬性值大於0,則表明登陸設備爲IPC設備,須要獲取其模擬通道號byStartChan屬性的值。每組模擬通道號範圍爲0-32。
for (Int32 i = 0; i < _deviceInfo.byChanNum; i++)//一個IPC設備能夠設置多個模擬通道號,默認爲一個模擬通道號
{
Int channelId = _deviceInfo.byStartChan
}
2) 獲取NVR設備通道號
若是Hik.NET_DVR_DEVICEINFO_V30結構體中byIPChanNum數字通道數量屬性值大於0,則表明登陸設備爲NVR設備,須要獲取其數字通道號,其獲取方法要比獲取IPC設備通道號複雜。每組數字通道號範圍爲33-64。
public void InfoIPChannel()
{
Hik.NET_DVR_IPPARACFG_V40 ipParaCfgV40 = new Hik.NET_DVR_IPPARACFG_V40();
Int32 size = Marshal.SizeOf(ipParaCfgV40);
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(ipParaCfgV40, ptrIpParaCfgV40, false);
UInt32 result = 0;
Int32 groupNo = 0;
Boolean ret = Hik.NET_DVR_GetDVRConfig(_userId, Hik.NET_DVR_GET_IPPARACFG_V40, groupNo, ptrIpParaCfgV40, (UInt32)size, ref result);//獲取配置信息
if (ret)
{
ipParaCfgV40 = (Hik.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(Hik.NET_DVR_IPPARACFG_V40));
byte byStreamType;
for (Int32 i = 0; i < ipParaCfgV40.dwDChanNum; i++)
{
byStreamType = ipParaCfgV40.struStreamMode[i].byGetStreamType;
size = Marshal.SizeOf(ipParaCfgV40.struStreamMode[i].uGetStream);
switch (byStreamType)
{
//目前NVR僅支持直接從設備取流 NVR supports only the mode: get stream from device directly
case 0:
IntPtr ptrChanInfo = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(ipParaCfgV40.struStreamMode[i].uGetStream, ptrChanInfo, false);
Hik.NET_DVR_IPCHANINFO _struChanInfo = (Hik.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(Hik.NET_DVR_IPCHANINFO));
Int32 deviceId = _struChanInfo.byIPID + _struChanInfo.byIPIDHigh * 256 - groupNo * 64 - 1;
if (deviceId == -1)
continue;
_channelInfoList.Add(new ChannelInfo() { DeviceID = deviceId, ChannelID = i + (Int32)ipParaCfgV40.dwStartDChan, State = (Int32)_struChanInfo.byEnable, IP = ipParaCfgV40.struIPDevInfo[i].struIP.sIpV4 });//獲取數字通道信息封裝到自定義通道類中
Marshal.FreeHGlobal(ptrChanInfo);
break;
default:
break;
}
}
}
Marshal.FreeHGlobal(ptrIpParaCfgV40);
}
1) 初始化預覽結構體
Hik.NET_DVR_PREVIEWINFO previewInfo = new Hik.NET_DVR_PREVIEWINFO();
previewInfo.lChannel = channelId;//預覽的設備通道 the device channel number
previewInfo.dwStreamType = 0;//碼流類型:0-主碼流,1-子碼流,2-碼流3,3-碼流4,以此類推
previewInfo.dwLinkMode = 0;//鏈接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
previewInfo.hPlayWnd = IntPtr.Zero;//預覽窗口,若是不使用回調顯示視頻流,則此處能夠設置顯示窗口句柄
previewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流
2) 獲取實時視頻流和視頻句柄
_realHandle = Hik.NET_DVR_RealPlay_V40(UserId, ref previewInfo, realData, IntPtr.Zero);//返回實時流句柄供後續方法調用
參數說明:
UserID爲登陸後返回的用戶句柄,
previewInfo爲已實例化的預覽結構體
realData爲預覽實時流回調函數,若是直接在窗口顯示實時流而不經過回調方式,則此參數能夠設置爲null
3) 實時流回調函數的使用
/// <summary>
/// 預覽實時流回調函數
/// </summary>
/// <param name="lRealHandle">當前的預覽句柄</param>
/// <param name="dwDataType">數據類型:1系統頭數據,2流數據(包括複合流或音視頻分開的視頻流數據),3音頻數據</param>
/// <param name="pBuffer">存放數據的緩衝區指針</param>
/// <param name="dwBufSize">緩衝區大小</param>
/// <param name="pUser">用戶數據</param>
public delegate void REALDATACALLBACK(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser);
注意:實例化實時流回調函數時,不能在方法內聲明並實例化,不然會被回收機制提早釋放實例化對象,致使程序錯誤。須要在最外部調用類中做爲字段預先聲明。例如:
private Hik.REALDATACALLBACK _callback;//實時流回調,做爲字段聲明
public override int IncreaseClient()
{
if (_callback == null)
_callback = new Hik.REALDATACALLBACK(RealDataCallBack);
Hik.StartPlay(Hik.ChannelInfoList[0].ChannelID, _callback);//播放實時流視頻
}
簡易流程描述爲實時流回調函數返回實時視頻流,而後把實時視頻流傳入到播放庫解碼,經過播放庫的兩個回調函數來返回解析後的視頻流和角度。角度回調信息的格式爲我公司定製協議,具體內容參看角度信息私有數據格式,59個字節長度的16進制字符串。
private Hik.DECCBFUN _displayCallback;//解碼回調
private Hik.ADDITIONDATACBFUN _additionDataDisplayCallback;//角度回調
獲取播放庫錯誤碼
Int port;
PlayM4_GetPort(ref port);//首先需獲取播放句柄
PlayM4_GetLastError(port);//獲取播放庫錯誤碼
具體回調以下:
int port;播放庫端口號
switch (dwDataType)
{
case 1: // sys head 系統頭數據
if (dwBufSize > 0)
{
//獲取播放句柄 Get the port to play
PlayM4_GetPort(ref _port);
//設置流播放模式
PlayM4_SetStreamOpenMode(_port, 0);
//打開碼流,送入頭數據 Open stream
PlayM4_OpenStream(_port, pBuffer, dwBufSize, 2 * 1024 * 1024);
//設置顯示緩衝區個數
PlayM4_SetDisplayBuf(_port, 15);
//設置解碼回調函數,獲取解碼後音視頻原始數據 Set callback function of decoded data
PlayM4_SetDecCallBackEx(_port, displayFun, IntPtr.Zero, 0);
//設置角度回調函數,獲取解碼前角度信息
PlayM4_SetAdditionDataCallBack(_port, 0x1004, additionDataDisplayFun, IntPtr.Zero);
//開始解碼 Start to play
PlayM4_Play(_port, IntPtr.Zero);//最後一個參數表示播放窗體的指針
}
break;
case 2: // video stream data 視頻流數據(包括複合流和音視頻分開的視頻流數據)
if (dwBufSize > 0 && _port != -1)
{
for (Int32 i = 0; i < 999; i++)
{
//送入碼流數據進行解碼 Input the stream data to decode
if (!PlayM4_InputData(_port, pBuffer, dwBufSize))
Thread.Sleep(2);
else
break;
}
}
break;
default:
if (dwBufSize > 0 && _port != -1)
{
//送入其餘數據 Input the other data
for (Int32 i = 0; i < 999; i++)
{
if (!PlayM4_InputData(_port, pBuffer, dwBufSize))
Thread.Sleep(2);
else
break;
}
}
break;
}
4) 中止預覽
Hik.NET_DVR_StopRealPlay(_realHandle);//_realHandle爲播放句柄
1) 雲臺操做命令
SET_PRESET = 8,// 設置預置點
CLE_PRESET = 9,// 清除預置點
Up = 21,/* 雲臺以SS的速度上仰 */
Down = 22,/* 雲臺以SS的速度下俯 */
Left = 23,/* 雲臺以SS的速度左轉 */
Right = 24,/* 雲臺以SS的速度右轉 */
UpLeft = 25,/* 雲臺以SS的速度上仰和左轉 */
UpRight = 26,/* 雲臺以SS的速度上仰和右轉 */
DownLeft = 27,/* 雲臺以SS的速度下俯和左轉 */
DownRight = 28,/* 雲臺以SS的速度下俯和右轉 */
Auto = 29,/* 雲臺以SS的速度左右自動掃描 */
ZOOM_IN = 11,/* 焦距以速度SS變大(倍率變大) */
ZOOM_OUT = 12,/* 焦距以速度SS變小(倍率變小) */
FOCUS_NEAR = 13, /* 焦點以速度SS前調 */
FOCUS_FAR = 14, /* 焦點以速度SS後調 */
IRIS_OPEN = 15, /* 光圈以速度SS擴大 */
IRIS_CLOSE = 16, /* 光圈以速度SS縮小 */
GOTO_PRESET = 39/* 快球轉到預置點 */
2) 雲臺操做方法
根據定製協議,雲臺控制速度爲1-160。可是需保證球機的升級包版本爲IPD_R3_STD_5.2.0_141111。
/// <summary>
/// 帶速度的雲臺控制操做(需先啓動圖像預覽)
/// </summary>
/// <param name="lRealHandle">NET_DVR_RealPlay_V40的返回值</param>
/// <param name="dwPTZCommand">雲臺控制命令</param>
/// <param name="dwStop">雲臺中止動做或開始動做:0- 開始;1- 中止</param>
/// <param name="dwSpeed">雲臺控制的速度,用戶按不一樣解碼器的速度控制值設置。取值範圍[1,160]</param>
/// <returns>TRUE表示成功,FALSE表示失敗</returns>
bool NET_DVR_PTZControlWithSpeed(int lRealHandle, uint dwPTZCommand, uint dwStop, uint dwSpeed);
1) 預置位命令
SET_PRESET = 8,// 設置預置點
CLE_PRESET = 9,// 清除預置點
GOTO_PRESET = 39// 轉到預置點
2) 預置位操做
/// <summary>
/// 設置預置位
/// </summary>
/// <param name="lRealHandle">NET_DVR_RealPlay_V40的返回值</param>
/// <param name="dwPTZPresetCmd">預置位控制命令</param>
/// <param name="dwPresetIndex">預置位編號最多支持255個預置點</param>
/// <returns>TRUE表示成功,FALSE表示失敗</returns>
bool NET_DVR_PTZPreset(int lRealHandle, uint dwPTZPresetCmd, uint dwPresetIndex);
3) 反向操做
Hik.NET_DVR_PTZPreset(_realHandle, (uint)8, 33);
在設定某些配置時,需預先執行此方法來獲取相關配置信息的結構體。
/// <summary>
/// 獲取設備的配置信息
/// </summary>
/// <param name="lUserID">NET_DVR_Login_V30的返回值</param>
/// <param name="dwCommand">設備配置命令</param>
/// <param name="lChannel">通道號或者組號,不一樣的命令對應不一樣的取值</param>
/// <param name="lpOutBuffer">接收數據的緩衝指針</param>
/// <param name="dwOutBufferSize">接收數據的緩衝長度(以字節爲單位),不能爲0</param>
/// <param name="lpBytesReturned">實際收到的數據長度指針,不能爲NULL</param>
/// <returns></returns>
bool NET_DVR_GetDVRConfig(int lUserID, uint dwCommand, int lChannel, IntPtr lpOutBuffer, uint dwOutBufferSize, ref uint lpBytesReturned);
具體調用見下面操做示例
/// <summary>
/// 設置設備的配置信息
/// </summary>
/// <param name="lUserID">NET_DVR_Login_V30的返回值</param>
/// <param name="dwCommand">設備配置命令</param>
/// <param name="lChannel">通道號或者組號,不一樣的命令對應不一樣的取值
<param>
/// <param name="lpInBuffer">輸入數據的緩衝指針</param>
/// <param name="dwInBufferSize">輸入數據的緩衝長度(以字節爲單位)</param>
/// <returns></returns>
bool NET_DVR_SetDVRConfig(int lUserID, uint dwCommand, int lChannel, IntPtr lpInBuffer, uint dwInBufferSize);
具體調用見下面操做示例
1) 設備配置命令
3369; //IPC設置CCD參數配置
3368; //IPC獲取CCD參數配置
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg = new Hik.NET_DVR_CAMERAPARAMCFG_EX();//實例化前端參數結構體
Int32 nSize = Marshal.SizeOf(cameraParamCfg );//獲取結構體空間大小
IntPtr ptrCfg = Marshal.AllocHGlobal(nSize);//設置指針大小
Hik.NET_DVR_GetDVRConfig(_userId,3368, _channelId, ptrCfg, (UInt32)nSize, ref dwReturn);//獲取配置信息的指針
cameraParamCfg = (Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg, typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//指針轉換爲數據結構
Marshal.FreeHGlobal(ptrCfg);//釋放指針
4) 日夜切換命令
0白天
1夜晚
2自動
5) 日夜切換結構體
NET_DVR_DAYNIGHT struDayNight;/*日夜轉換*/
6) 設置配置信息
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg=獲取配置信息();
Int32 size = Marshal.SizeOf(cameraParamCfg);//獲取結構體大小
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//設置指針空間大小
cameraParamCfg.struDayNight.byDayNightFilterType = (byte)日夜切換命令;
Marshal.StructureToPtr(cameraParamCfg, ptrCfg, false);//結構體轉換爲指針
Hik.NET_DVR_SetDVRConfig(_userId, 3369, _channelId, ptrCfg, (uint)size);//設置參數
Marshal.FreeHGlobal(ptrCfg);//釋放指針
1) 設備配置命令
3369; //IPC設置CCD參數配置
3368; //IPC獲取CCD參數配置
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg = new Hik.NET_DVR_CAMERAPARAMCFG_EX();//實例化前端參數結構體
Int32 nSize = Marshal.SizeOf(cameraParamCfg );//獲取結構體空間大小
IntPtr ptrCfg = Marshal.AllocHGlobal(nSize);//設置指針大小
Hik.NET_DVR_GetDVRConfig(_userId,3368, _channelId, ptrCfg, (UInt32)nSize, ref dwReturn);//獲取配置信息的指針
cameraParamCfg = (Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg, typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//指針轉換爲數據結構
Marshal.FreeHGlobal(ptrCfg);//釋放指針
4) 透霧切換命令
0關閉
2開啓
5) 透霧切換結構體
NET_DVR_DEFOGCFG struDefogCfg;//透霧參數
6) 設置配置信息
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg=獲取配置信息();
Int32 size = Marshal.SizeOf(cameraParamCfg);//獲取結構體大小
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//設置指針空間大小
cameraParamCfg.struDefogCfg.byMode = (byte)透霧切換命令;
cameraParamCfg.struDefogCfg.byLevel = (byte)100;//透霧級別
Marshal.StructureToPtr(cameraParamCfg, ptrCfg, false);//結構體轉換爲指針
Hik.NET_DVR_SetDVRConfig(_userId, 3369, _channelId, ptrCfg, (uint)size);//設置參數
Marshal.FreeHGlobal(ptrCfg);//釋放指針
1) 設備配置命令
3306; //設置快球聚焦模式參數
3305; //獲取快球聚焦模式參數
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_FOCUSMODE_CFG focusModeCfg = new Hik.NET_DVR_FOCUSMODE_CFG();//實例化聚焦模式結構體
Int32 size = Marshal.SizeOf(focusModeCfg);//獲取結構體大小
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//設置指針空間大小
Hik.NET_DVR_GetDVRConfig(_userId, 3305, _channelId, ptrCfg, (UInt32)size, ref dwReturn);//獲取聚焦模式信息的指針
focusModeCfg = (Hik.NET_DVR_FOCUSMODE_CFG)Marshal.PtrToStructure(ptrCfg, typeof(Hik.NET_DVR_FOCUSMODE_CFG));//指針轉換爲聚焦模式結構體
Marshal.FreeHGlobal(ptrCfg);//釋放指針
4) 聚焦模式切換命令
0自動
1手動
2半自動
5) 聚焦模式切換結構體
NET_DVR_FOCUSMODE_CFG
6) 設置配置信息
Hik.NET_DVR_FOCUSMODE_CFG focusModeCfg = 獲取配置信息();
Int32 size = Marshal.SizeOf(focusModeCfg);//獲取結構體大小
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//設置指針空間大小
focusModeCfg.byFocusMode = (byte)聚焦模式命令;
Marshal.StructureToPtr(focusModeCfg, ptrCfg, false);//結構體轉換爲指針
Hik.NET_DVR_SetDVRConfig(_userId, Hik.NET_DVR_SET_FOCUSMODECFG, _channelId, ptrCfg, (uint)size);//設置聚焦模式
Marshal.FreeHGlobal(ptrCfg);//釋放指針
1) 設備配置命令
1030;//獲取疊加字符操做命令
1031;//設置疊加字符操做命令
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_SHOWSTRING_V30 struShowStrCfg = new Hik.NET_DVR_SHOWSTRING_V30();//初始化疊加字符結構體
Int32 size = Marshal.SizeOf(struShowStrCfg);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針大小
Hik.NET_DVR_GetDVRConfig(_userId, 1030, _channelId, ptr, (UInt32)size, ref dwReturn);//獲取配置信息
struShowStrCfg = (Hik.NET_DVR_SHOWSTRING_V30)Marshal.PtrToStructure(ptr, typeof(Hik.NET_DVR_SHOWSTRING_V30));//指針轉換爲結構體
Marshal.FreeHGlobal(ptr);//釋放指針
4) 疊加字符結構體
NET_DVR_SHOWSTRINGINFO struStringInfo;/* 要顯示的字符內容 */
說明:設置疊加字符須要爲其屬性賦值。
5) 設置配置信息
Hik.NET_DVR_SHOWSTRING_V30 struShowStrCfg =獲取疊加字符配置信息();
Int32 size = Marshal.SizeOf(struShowStrCfg);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針空間大小
String osd = "海康智能監控視頻一";
struShowStrCfg.struStringInfo[0].wShowString = 1;//1爲顯示,0爲不顯示
struShowStrCfg.struStringInfo[0].sString = osd;//疊加的字符串
struShowStrCfg.struStringInfo[0].wStringSize = (ushort)(osd.Length * 2);//字符串大小
struShowStrCfg.struStringInfo[0].wShowStringTopLeftX = 0;//座標
struShowStrCfg.struStringInfo[0].wShowStringTopLeftY = 0;//座標
Marshal.StructureToPtr(struShowStrCfg, ptr, false);//街頭體轉換爲指針
Hik.NET_DVR_SetDVRConfig(_userId, 1031, _channelId, ptr, (UInt32)size);//設置配置信息
Marshal.FreeHGlobal(ptr);//釋放指針
說明:能夠疊加顯示多個字符串。
1) 設備配置命令
3270;//獲取PTZ基本參數信息
3271;//設置PTZ基本參數信息
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_PTZ_BASICPARAMCFG basicParamCfg = new Hik.NET_DVR_PTZ_BASICPARAMCFG();//初始化PTZ基本參數結構體
Int32 size = Marshal.SizeOf(basicParamCfg);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針大小
Hik.NET_DVR_GetDVRConfig(userId, 3270, _channelId, ptr, (UInt32)size, ref bytesReturned);//獲取配置參數指針
basicParamCfg = (Hik.NET_DVR_PTZ_BASICPARAMCFG)Marshal.PtrToStructure(ptr, typeof(Hik.NET_DVR_PTZ_BASICPARAMCFG));//指針轉換爲結構體
Marshal.FreeHGlobal(ptr);//釋放指針
4) 球機定位速度命令
1-8
5) 球機定位速度結構體
Hik.NET_DVR_PTZ_BASICPARAMCFG basicParamCfg
6) 設置配置信息
Hik.NET_DVR_PTZ_BASICPARAMCFG basicParamCfg = 獲取配置信息();
Int32 size = Marshal.SizeOf(basicParamCfg);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針空間大小
basicParamCfg.byPresetSpeed = (byte)速度值;
Marshal.StructureToPtr(basicParamCfg, ptr, false);//結構體轉換爲指針
Hik.NET_DVR_SetDVRConfig(userId, 3271, _channelId, ptr, size);//設置配置信息
Marshal.FreeHGlobal(ptr);//釋放指針
1) 設備配置命令
294;//雲臺獲取PTZ範圍
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
Hik.NET_DVR_PTZSCOPE PTZScope = new Hik.NET_DVR_PTZSCOPE();//初始化球機範圍信息結構體
Int32 size = Marshal.SizeOf(PTZScope);//獲取結構體空間大小
IntPtr ptrScope = Marshal.AllocHGlobal(size);//設置指針空間大小
Hik.NET_DVR_GetDVRConfig(_userId, 294, _channelId, ptrScope, (UInt32)size, ref result);//獲取配置信息
PTZScope = (Hik.NET_DVR_PTZSCOPE)Marshal.PtrToStructure(ptrScope, typeof(Hik.NET_DVR_PTZSCOPE));//指針轉換爲結構體
Marshal.FreeHGlobal(ptrScope);//釋放指針
4) 球機轉動範圍結構體
Hik.NET_DVR_PTZSCOPE PTZScope
使用球機定位功能前,需先設置球機定位速度和獲取球機轉動範圍,再根據球機轉動範圍信息來操做球機定位功能。
1) 設備配置命令
292;//雲臺設置PTZ位置
293;//雲臺獲取PTZ位置
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 獲取配置信息
//用精簡方式實現
Int32 size = Marshal.SizeOf(typeof(Hik.NET_DVR_PTZPOS));//獲取球機位置信息結構體大小
IntPtr ptrPTZ = Marshal.AllocHGlobal(size);//設置指針空間大小
Hik.NET_DVR_GetDVRConfig(_userId, 293, _channelId, ptrPTZ, (UInt32)size, ref result);//獲取球機位置配置信息
Hik.NET_DVR_PTZPOS PTZPos = (Hik.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPTZ, typeof(Hik.NET_DVR_PTZPOS));//指針轉換爲結構體
Marshal.FreeHGlobal(ptrPTZ);//釋放指針
4) 透霧切換結構體
Hik.NET_DVR_PTZPOS PTZPos
5) 設置配置信息
Hik.NET_DVR_PTZPOS PTZPos = 獲取球機位置信息();
Int32 size = Marshal.SizeOf(PTZPos);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針空間大小
PTZPos.wAction = 1;//-表示定位PTZ參數
//本結構體中的wAction參數是設置時的操做類型,所以獲取時該參數無效。實際顯示的PTZ值是獲取到的十六進制值的十分之一,如獲取的水平參數P的值是0x1750,實際顯示的P值爲175度;獲取到的垂直參數T的值是0x0789,實際顯示的T值爲78.9度;獲取到的變倍參數Z的值是0x1100,實際顯示的Z值爲110度。
String temp = "0x" + Convert.ToString(horAngle * 10);//實際顯示的PTZ值是獲取到的十六進制值的十分之一,因此須要把輸入的數值乘以10再拼成十六進制字符串
PTZPos.wPanPos = Convert.ToUInt16(temp, 16);//轉換爲16進制水平角度
if (pitAngle >= 0)//判斷俯仰角度的正負。因爲零方位角的設置不一樣,會致使出現負的俯仰角度,因此處理方式不一樣
PTZPos.wTiltPos = Convert.ToUInt16("0x" + Convert.ToString(pitAngle * 10), 16);
else
PTZPos.wTiltPos = Convert.ToUInt16("0x" + Convert.ToString((pitAngle + 360) * 10), 16);
PTZPos.wZoomPos = Convert.ToUInt16("0x" + Convert.ToString(viewAngle * 10), 16);
Marshal.StructureToPtr(PTZPos, ptr, false);//結構體轉換爲指針
Hik.NET_DVR_SetDVRConfig(_userId, 292, _channelId, ptr, (uint)size);//設置配置
Marshal.FreeHGlobal(ptr);//釋放指針
1) 設備配置命令
3283;// 零方位角控制
2) 通道號或者組號
ChannelId//登陸IPC設備時獲取的通道號
3) 零方位角控制命令
SET = 0,//設置
GOTO = 1,//調用
CLE = 2//清除
4) 零方位角控制結構體
Hik.NET_DVR_INITIALPOSITIONCTRL initialPositionCtrl
5) 設置控制信息
Hik.NET_DVR_INITIALPOSITIONCTRL initialPositionCtrl = new Hik.NET_DVR_INITIALPOSITIONCTRL();//初始化零方位角控制結構體
Int32 size = Marshal.SizeOf(initialPositionCtrl);//獲取結構體空間大小
IntPtr ptr = Marshal.AllocHGlobal(size);//設置指針大小
initialPositionCtrl.dwSize = (uint)size;//結構體大小
initialPositionCtrl.dwChan = (uint)_channelId;//播放通道號
initialPositionCtrl.byWorkMode = (byte)command;//零方位角控制命令
Marshal.StructureToPtr(initialPositionCtrl, ptr, false);//結構體轉換爲指針
Hik.NET_DVR_RemoteControl(_userId, (uint)3283, ptr, (uint)size);//零方位角控制
Marshal.FreeHGlobal(ptr);//釋放指針
此功能須要硬盤錄像機支持。須要先登陸NVR設備。在登陸和獲取數字通道號後,根據設備所對應的通道號操做相關IPC設備的一些基礎功能。
1) 設備配置命令
1;//開始播放
2;//中止播放
3;//暫停播放
4;//恢復播放
5;//快放
6;//慢放
7;//正常速度
8;//單幀放
9;//打開聲音
10;//關閉聲音
11;//調節音量
12;//改變文件回放的進度
13;//獲取文件回放的進度
14;//獲取當前已經播放的時間(按文件回放的時候有效)
15;//獲取當前已經播放的幀數(按文件回放的時候有效)
16;//獲取當前播放文件總的幀數(按文件回放的時候有效)
17;//獲取當前播放文件總的時間(按文件回放的時候有效)
20;//丟B幀
24;//設置碼流速度
25;//保持與設備的心跳(若是回調阻塞,建議2秒發送一次)
26;//按絕對時間定位
27;//獲取按時間回放對應時間段內的全部文件的總長度
29;//倒放切換爲正放
30;//正放切換爲倒放
32;//設置轉封裝類型
33;//正放切換爲倒放
2) 初始化錄像回放結構體
Hik.NET_DVR_VOD_PARA struVodPara = new Hik.NET_DVR_VOD_PARA();//初始化錄像回放結構體
struVodPara.dwSize = (uint)Marshal.SizeOf(struVodPara);//獲取結構體空間大小
struVodPara.struIDInfo.dwChannel = (uint)_ipChannelId; //數字通道號 Channel number,海康設備數字通道號從33開始
//struVodPara.hWnd = this.pictureBoxVideo.Handle;//不使用回調獲取回放視頻時,使用此屬性設置回放窗口句柄
struVodPara.hWnd = IntPtr.Zero;//使用回調獲取回放視頻時,需如此設置回放窗口句柄
//設置回放的開始時間 Set the starting time to search video files
struVodPara.struBeginTime.dwYear = (uint)dateTimeStart.Value.Year;
struVodPara.struBeginTime.dwMonth = (uint)dateTimeStart.Value.Month;
struVodPara.struBeginTime.dwDay = (uint)dateTimeStart.Value.Day;
struVodPara.struBeginTime.dwHour = (uint)dateTimeStart.Value.Hour;
struVodPara.struBeginTime.dwMinute = (uint)dateTimeStart.Value.Minute;
struVodPara.struBeginTime.dwSecond = (uint)dateTimeStart.Value.Second;
//設置回放的結束時間 Set the stopping time to search video files
struVodPara.struEndTime.dwYear = (uint)dateTimeEnd.Value.Year;
struVodPara.struEndTime.dwMonth = (uint)dateTimeEnd.Value.Month;
struVodPara.struEndTime.dwDay = (uint)dateTimeEnd.Value.Day;
struVodPara.struEndTime.dwHour = (uint)dateTimeEnd.Value.Hour;
struVodPara.struEndTime.dwMinute = (uint)dateTimeEnd.Value.Minute;
struVodPara.struEndTime.dwSecond = (uint)dateTimeEnd.Value.Second;
3) 獲取錄像回放播放句柄
目前根據需求只實現根據錄像起止時間範圍播放錄像視頻,其餘功能請參考SDK功能說明文檔。
//按時間回放 Playback by time
_realHandle = Hik.NET_DVR_PlayBackByTime_V40(_NVRUserId, ref struVodPara);// struVodPara爲錄像回放結構體
4) 錄像數據回調函數的使用
/// <summary>
/// 錄像數據回調函數
/// </summary>
/// <param name="lPlayHandle">當前的錄像播放句柄</param>
/// <param name="dwDataType">數據類型</param>
/// <param name="pBuffer">存放數據的緩衝區指針</param>
/// <param name="dwBufSize">緩衝區大小</param>
/// <param name="pUser">用戶數據</param>
public delegate void PlayDataCallBack_V40(Int32 lPlayHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser);
此回調函數的使用方式與實時流回調函數的操做方式相似,都是獲取視頻流後,用播放庫解碼,返回角度信息和解碼後的視頻流。
Hik.NET_DVR_PlayBackControl_V40(_realHandle, 1, IntPtr.Zero, 0, IntPtr.Zero, ref iOutValue);//播放錄像回放視頻
5) 中止錄像回放
Hik.NET_DVR_StopPlayBack(_realHandle)
1) 初始化錄像下載結構體
Hik.NET_DVR_PLAYCOND struDownPara = new Hik.NET_DVR_PLAYCOND();//初始化錄像下載結構體
struDownPara.dwChannel = (uint)_ipChannelId; //數字通道號 Channel number
//設置下載的開始時間 Set the starting time
struDownPara.struStartTime.dwYear = (uint)dateTimeStart.Value.Year;
struDownPara.struStartTime.dwMonth = (uint)dateTimeStart.Value.Month;
struDownPara.struStartTime.dwDay = (uint)dateTimeStart.Value.Day;
struDownPara.struStartTime.dwHour = (uint)dateTimeStart.Value.Hour;
struDownPara.struStartTime.dwMinute = (uint)dateTimeStart.Value.Minute;
struDownPara.struStartTime.dwSecond = (uint)dateTimeStart.Value.Second;
//設置下載的結束時間 Set the stopping time
struDownPara.struStopTime.dwYear = (uint)dateTimeEnd.Value.Year;
struDownPara.struStopTime.dwMonth = (uint)dateTimeEnd.Value.Month;
struDownPara.struStopTime.dwDay = (uint)dateTimeEnd.Value.Day;
struDownPara.struStopTime.dwHour = (uint)dateTimeEnd.Value.Hour;
struDownPara.struStopTime.dwMinute = (uint)dateTimeEnd.Value.Minute;
struDownPara.struStopTime.dwSecond = (uint)dateTimeEnd.Value.Second;
2) 錄像下載結構體
Hik.NET_DVR_PLAYCOND struDownPara
3) 錄像下載
錄像下載後默認保存格式爲mp4。
_realHandle = Hik.NET_DVR_GetFileByTime_V40(_NVRUserId, sVideoFileName, ref struDownPara);
海康平臺能夠掛載多個NVR設備,調用NVR下掛載的IPC設備時,只須要在海康平臺的設備設置中找到其攝像頭ID便可。
具體引用方式,參見IPC_SDK的引用。因爲海康平臺技術人員提供的DLL文件過於繁雜,就不一一列出DLL的說明,詳情參見IVMS_SDK文件夾目錄。
詳情參見C#程序調用DLL中的非託管函數方法。
根據海康視頻設備及平臺使用的方案設計,只應用海康平臺SDK的視頻回調顯示功能,其它功能暫不使用。對Plat_SDK的C#封裝類見附件HikIVMS.cs,可參考此基礎類文件進行程序功能編寫。
Plat_GetLastError(_userId);//獲取錯誤碼,userId爲登陸後得到的用戶ID
使用方式:若是每一個非託管函數方法返回結果不爲0(正確),則調用此方法獲取錯誤碼。
例如:
Int32 ret = Plat_Init();
if (ret != 0)
throw new HikIVMSException(Plat_GetLastError(_userId));// HikIVMSException爲自定義異常調用類,用來解析錯誤碼拋出異常
1) 用戶註冊
Int32 ret;
ret = Plat_Init();//platformSDK初始化
if (ret != 0)
throw new HikIVMSException(Plat_GetLastError(_userId));
IntPtr ptrIP = Marshal.StringToHGlobalAnsi(uri.Host);//IP
IntPtr ptrUserName = Marshal.StringToHGlobalAnsi(a[0]);//用戶名
IntPtr ptrPassword = Marshal.StringToHGlobalAnsi(a[1]);//密碼
IntPtr ptrPort = Marshal.StringToHGlobalAnsi(uri.Port.ToString());//端口號
_userId = Plat_LoginCMS(ptrIP, ptrUserName, ptrPassword, ptrPort, 0);//登陸
//釋放指針
Marshal.FreeHGlobal(ptrIP);
Marshal.FreeHGlobal(ptrUserName);
Marshal.FreeHGlobal(ptrPassword);
Marshal.FreeHGlobal(ptrPort);
2) 用戶註銷
//若是存在播放的視頻,也就是_streamHandle播放句柄>0,則先中止播放視頻
Plat_StopVideo(_streamHandle);
Plat_LogoutCMS(_userId);//註銷用戶
Plat_Free();//釋放SDK,必須執行
1) 播放預覽
/// <summary>
/// 播放實時視頻(開始預覽/回放)
/// </summary>
/// <param name="url">預覽或回放的播放路徑,由Plat_QueryRealStreamURL或Plat_QueryRecordFile</param>
/// <param name="hWnd">播放窗口句柄,若是爲空,則不播放</param>
/// <param name="userHandle">用戶ID</param>
/// <param name="streamCallback">視頻碼流接收回調函數指針,若是回調函數爲NULL則不給碼流</param>
/// <returns>>=0成功,返回實時視頻句柄,錯誤時返回-1</returns>
Int32 Plat_PlayVideo(String url, IntPtr hWnd, Int32 userHandle, fStreamCallback streamCallback, IntPtr user);
例如:
_streamHandle = Plat_PlayVideo(cameraId, IntPtr.Zero, _userId, callback, IntPtr.Zero);
注意:此函數的第一個參數,在應用中只須要傳入攝像機ID便可。
2) 實時流回調函數的使用
/// <summary>
/// 實時流回調
/// </summary>
/// <param name="handle">Plat_PlayVideo返回的句柄</param>
/// <param name="data">接收視頻碼流數據緩衝區指針</param>
/// <param name="size">接收視頻碼流數據字節數</param>
/// <param name="user">用戶數據</param>
public delegate void fStreamCallback(Int32 handle, IntPtr data, UInt32 size, IntPtr user, UInt32 dataType);
其調用方式與IPC_SDK中回調實時視頻流的方式相同,都是調用播放庫解碼,而後返回角度信息和解碼後的視頻。詳情參見IPC_SDK預覽功能說明
示例以下:
private HikIVMS.fStreamCallback _callback;
private HikIVMS.DECCBFUN _displayCallback;//解碼回調
private HikIVMS.ADDITIONDATACBFUN _additionDataDisplayCallback;//角度回調
if (_callback == null)
_callback = new HikIVMS.fStreamCallback(StreamCallback);
if (_displayCallback == null)
_displayCallback = new HikIVMS.DECCBFUN(DecCallbackFUN);
if (_additionDataDisplayCallback == null)
_additionDataDisplayCallback = new HikIVMS.ADDITIONDATACBFUN(AdditionDataCallBackFUN);
Hik.Play(cameraCode, _callback);
注意:Plat的回調函數與IPC回調函數中惟一的區別在於數據類型的定義不一樣,IPC的系統頭數據類型爲1,視頻流數據類型爲2;Plat系統頭數據類型爲0,視頻流數據類型爲1,僅此區別,其它相同。