您的位置:首页 > 编程语言 > C#

海康SDK编程指南(C#二次开发版本)

2016-02-24 20:54 621 查看


转载于整理自:心澄欲遣

目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息。本文仅对视频监控常用功能的使用进行说明,其它未实现功能请参看设备网络SDK使用手册和播放库编程指南V7.2。



IPC_SDK编程指南


(一)SDK的引用

由于IPC_SDK没有SDK安装程序,所以需手工把下面图表中的DLL放入Debug或者Release文件夹的根目录下供程序调用,或者加入系统环境变量Path下。

名称
版本号
说明
AudioIntercom.dll
1.1.0.5
 
AudioRender.dll
1.0.0.2
 
DsSdk.dll
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#程序调用DLL中的非托管函数方法


1.调用外部声明方法

首先在C#语言源程序中声明外部方法,其基本形式是:

[DLLImport(“DLL文件”)]

修饰符extern返回变量类型方法名称(参数列表)

例如:

usingSystem.Runtime.InteropServices;

[DllImport("HCNetSDK.dll")]
publicstaticexternboolNET_DVR_Init();


注意:

1)需要在程序声明中使用System.Runtime.InteropServices命名空间。DllImport只能放置在方法声明上。

2)DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。

3)返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。

4)若要使用其它函数名,可以使用EntryPoint属性设置,如:[DllImport("user32.dll",EntryPoint="MessageBoxA")]

staticexternintMsgBox(inthWnd,stringmsg,stringcaption,inttype);

5)其它可选的DllImportAttribute属性:

CharSet指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;

SetLastError指示方法是否保留Win32"上一错误",如:SetLastError=true;

ExactSpelling指示EntryPoint是否必须与指示的入口点的拼写完全匹配,

如:ExactSpelling=false;

PreserveSig指示方法的签名应当被保留还是被转换,如:PreserveSig=true;

CallingConvention指示入口点的调用约定,如:CallingConvention=CallingConvention.Winapi;


2.参数数据类型转换(详细参考这里)

Win32Types
CLRType
char,INT8,SBYTE,CHAR
System.SByte
short,shortint,INT16,SHORT
System.Int16
int,long,longint,INT32,LONG32,BOOL,INT
System.Int32
_int64,INT64,LONGLONG
System.Int64
unsignedchar,UINT8,UCHAR,BYTE
System.Byte
unsignedshort,UINT16,USHORT,WORD,ATOM,WCHAR,__wchar_t
System.UInt16
unsigned,unsignedint,UINT32,ULONG32,DWORD32,ULONG,DWORD,UINT
System.UInt32
unsigned__int64,UINT64,DWORDLONG,ULONGLONG
System.UInt64
float,FLOAT
System.Single
double,longdouble,DOUBLE
System.Double
BSTR
StringBuilder
LPCTSTR
StringBuilder
LPCWSTR
IntPtr
handle
IntPtr
hwnd
IntPtr
char*
string
int*
refint
int&
refint
void*
IntPtrs
unsignedchar*
refbyte
BOOL——
bool
DWORD
uint或int
注意:

指针做参数时在C#中一定要使用ref或out关键字,尤其是结构体指针,要不会报内存读取错误
首先声明结构体[StructLayoutAttribute(LayoutKind.Sequential)]
重写结构体的时候,之前有指明类型长度或数组长度的地方,也要进行相应的标注,要不也会导致内存错误


3.重写结构体

例如:[MarshalAs(UnmanagedType.ByValTStr,SizeConst=16)],具体长度需参看SDK中改结构体的说明文档

或者[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst=64,ArraySubType=UnmanagedType.I1)]


4.结构体与指针之间的转换

1)结构体转换为指针

Hik.NET_DVR_IPPARACFG_V40ipParaCfgV40=newHik.NET_DVR_IPPARACFG_V40();//初始化结构体

Int32size=Marshal.SizeOf(ipParaCfgV40);//返回结构体字节数

IntPtrptrIpParaCfgV40=Marshal.AllocHGlobal(size);//定义指针字节数

Marshal.StructureToPtr(ipParaCfgV40,ptrIpParaCfgV40,false);//将结构体封装到内存指针中

//调用需要指针的方法

Marshal.FreeHGlobal(ptrIpParaCfgV40);//释放指针


2)指针转换为结构体

Hik.NET_DVR_CAMERAPARAMCFG_EXcameraParamCfg=newHik.NET_DVR_CAMERAPARAMCFG_EX();//实例化结构体

Int32size=Marshal.SizeOf(cameraParamCfg);//获取结构体字节数

IntPtrptrCfg=Marshal.AllocHGlobal(size);//为指针分配空间

//调用获取指针的方法

cameraParamCfg=(Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg,typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//把指针转换为结构体

Marshal.FreeHGlobal(ptrCfg);//释放指针


3)指针转换为结构体精简写法

Int32size=Marshal.SizeOf(typeof(Hik.NET_DVR_PTZPOS));

IntPtrptrPTZ=Marshal.AllocHGlobal(size);

//调用获取指针的方法

Hik.NET_DVR_PTZPOSPTZPos=(Hik.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPTZ,typeof(Hik.NET_DVR_PTZPOS));//指针转换为结构体

Marshal.FreeHGlobal(ptrPTZ);//释放指针


对第2点和第3点的说明:当一个方法的参数为一个结构体的指针时,并且执行方法后此指针会返回结构体信息时,可以有两种方式来初始化这个指针,第二种更为简洁些。


(三)SDK的调用

对IPC_SDK的C#封装类见附件Hik.cs(类似我们CHCNetSDK.cs),可参考此基础类文件进行程序功能编写。


(类似我们的HKIPCamera.cs类来调用CHCNetSDK类的win32函数)


1.获取错误码

Hik.NET_DVR_GetLastError();//获取错误码


使用方式:如果有个非托管函数方法返回结果为false,则调用此方法获取错误码。

例如:

ret=Hik.NET_DVR_Init();

if(ret!=true)

thrownewHikException(Hik.NET_DVR_GetLastError());//HikException为自定义异常调用类,用来解析错误码抛出异常



2.登录

1)用户注册

Hik.NET_DVR_Init();//初始化SDK,多次初始化会抛出错误

Hik.NET_DVR_SetConnectTime(2000,1);//设置超时时间

Hik.NET_DVR_SetReconnect(10000,1);//设置重连时间

Hik.NET_DVR_DEVICEINFO_V30_deviceInfo=newHik.NET_DVR_DEVICEINFO_V30();//设备参数结构体,可以返回设备信息

StringuserId=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



3.获取通道号

由于IPC_SDK同时支持IPC与NVR,所以两者获取通道号的方式有所不同。

1)获取IPC设备通道号

如果Hik.NET_DVR_DEVICEINFO_V30结构体中byChanNum模拟通道数量属性值大于0,则代表登录设备为IPC设备,需要获取其模拟通道号byStartChan属性的值。每组模拟通道号范围为0-32。

for(Int32i=0;i<_deviceInfo.byChanNum;i++)//一个IPC设备可以设置多个模拟通道号,默认为一个模拟通道号

{

IntchannelId=_deviceInfo.byStartChan

}


2)获取NVR设备通道号

如果Hik.NET_DVR_DEVICEINFO_V30结构体中byIPChanNum数字通道数量属性值大于0,则代表登录设备为NVR设备,需要获取其数字通道号,其获取方法要比获取IPC设备通道号复杂。每组数字通道号范围为33-64。

publicvoidInfoIPChannel()

{


Hik.NET_DVR_IPPARACFG_V40ipParaCfgV40=newHik.NET_DVR_IPPARACFG_V40();

Int32size=Marshal.SizeOf(ipParaCfgV40);


IntPtrptrIpParaCfgV40=Marshal.AllocHGlobal(size);

Marshal.StructureToPtr(ipParaCfgV40,ptrIpParaCfgV40,false);


UInt32result=0;

Int32groupNo=0;

Booleanret=Hik.NET_DVR_GetDVRConfig(_userId,Hik.NET_DVR_GET_IPPARACFG_V40,groupNo,ptrIpParaCfgV40,(UInt32)size,refresult);//获取配置信息

if(ret)

{

ipParaCfgV40=(Hik.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40,typeof(Hik.NET_DVR_IPPARACFG_V40));


bytebyStreamType;

for(Int32i=0;i<ipParaCfgV40.dwDChanNum;i++)

{


byStreamType=ipParaCfgV40.struStreamMode[i].byGetStreamType;

size=Marshal.SizeOf(ipParaCfgV40.struStreamMode[i].uGetStream);


switch(byStreamType)

{

//目前NVR仅支持直接从设备取流NVRsupportsonlythemode:getstreamfromdevicedirectly

case0:

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

Int32deviceId=_struChanInfo.byIPID+_struChanInfo.byIPIDHigh*256-groupNo*64-1;

if(deviceId==-1)

continue;

_channelInfoList.Add(newChannelInfo(){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);

}



4.预览

1)初始化预览结构体

Hik.NET_DVR_PREVIEWINFOpreviewInfo=newHik.NET_DVR_PREVIEWINFO();

previewInfo.lChannel=channelId;//预览的设备通道thedevicechannelnumber

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,refpreviewInfo,realData,IntPtr.Zero);//返回实时流句柄供后续方法调用


参数说明:

UserID为登录后返回的用户句柄,

previewInfo为已实例化的预览结构体

realData为预览实时流回调函数,如果直接在窗口显示实时流而不通过回调方式,则此参数可以设置为null

3)实时流回调函数的使用

在封装类(CHCNetSDK)中定义回调函数:

///<summary>

///预览实时流回调函数

///</summary>

///<paramname="lRealHandle">当前的预览句柄</param>

///<paramname="dwDataType">数据类型:1系统头数据,2流数据(包括复合流或音视频分开的视频流数据),3音频数据</param>

///<paramname="pBuffer">存放数据的缓冲区指针</param>

///<paramname="dwBufSize">缓冲区大小</param>

///<paramname="pUser">用户数据</param>

publicdelegatevoidREALDATACALLBACK(Int32lRealHandle,UInt32dwDataType,IntPtrpBuffer,UInt32dwBufSize,IntPtrpUser);


使用时注意:实例化实时流回调函数时,不能在方法内声明并实例化,否则会被回收机制提前释放实例化对象,导致程序错误。需要在最外部调用类中作为字段预先声明。

例如:(HKIPCamera类中)

privateHik.REALDATACALLBACK_callback;//实时流回调,作为字段声明

publicoverrideintIncreaseClient()

{

if(_callback==null)

_callback=newHik.REALDATACALLBACK(RealDataCallBack);//RealDataCallBack是一个方法

Hik.StartPlay(Hik.ChannelInfoList[0].ChannelID,_callback);//播放实时流视频

}


简易流程描述为:实时流回调函数返回实时视频流,然后把实时视频流传入到播放库解码(PlayCtrl.dll),通过播放库的两个回调函数来返回解析后的视频流和角度。角度回调信息的格式为我公司定制协议,具体内容参看角度信息私有数据格式,59个字节长度的16进制字符串。

privateHik.DECCBFUN_displayCallback;//解码回调

privateHik.ADDITIONDATACBFUN_additionDataDisplayCallback;//角度回调


获取播放库错误码

Intport;

PlayM4_GetPort(refport);//首先需获取播放句柄

PlayM4_GetLastError(port);//获取播放库错误码


具体回调如下:

intport;播放库端口号

switch(dwDataType)

{

case1://syshead系统头数据

if(dwBufSize>0)

{

//获取播放句柄Gettheporttoplay

PlayM4_GetPort(ref_port);

//设置流播放模式

PlayM4_SetStreamOpenMode(_port,0);

//打开码流,送入头数据Openstream

PlayM4_OpenStream(_port,pBuffer,dwBufSize,2*1024*1024);

//设置显示缓冲区个数

PlayM4_SetDisplayBuf(_port,15);

//设置解码回调函数,获取解码后音视频原始数据Setcallbackfunctionofdecodeddata

PlayM4_SetDecCallBackEx(_port,displayFun,IntPtr.Zero,0);

//设置角度回调函数,获取解码前角度信息

PlayM4_SetAdditionDataCallBack(_port,0x1004,additionDataDisplayFun,IntPtr.Zero);

//开始解码Starttoplay

PlayM4_Play(_port,IntPtr.Zero);//最后一个参数表示播放窗体的指针

}

break;

case2://videostreamdata视频流数据(包括复合流和音视频分开的视频流数据)

if(dwBufSize>0&&_port!=-1)

{

for(Int32i=0;i<999;i++)

{

//送入码流数据进行解码Inputthestreamdatatodecode

if(!PlayM4_InputData(_port,pBuffer,dwBufSize))

Thread.Sleep(2);

else

break;

}

}

break;

default:

if(dwBufSize>0&&_port!=-1)

{

//送入其他数据Inputtheotherdata

for(Int32i=0;i<999;i++)

{

if(!PlayM4_InputData(_port,pBuffer,dwBufSize))

Thread.Sleep(2);

else

break;

}

}

break;

}


4)停止预览

Hik.NET_DVR_StopRealPlay(_realHandle);//_realHandle为播放句柄



5.云台控制

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>

///<paramname="lRealHandle">NET_DVR_RealPlay_V40的返回值</param>

///<paramname="dwPTZCommand">云台控制命令</param>

///<paramname="dwStop">云台停止动作或开始动作:0-开始;1-停止</param>

///<paramname="dwSpeed">云台控制的速度,用户按不同解码器的速度控制值设置。取值范围[1,160]</param>

///<returns>TRUE表示成功,FALSE表示失败</returns>

boolNET_DVR_PTZControlWithSpeed(intlRealHandle,uintdwPTZCommand,uintdwStop,uintdwSpeed);



6.云台预置位

1)预置位命令

SET_PRESET=8,//设置预置点

CLE_PRESET=9,//清除预置点

GOTO_PRESET=39//转到预置点


2)预置位操作

///<summary>

///设置预置位

///</summary>

///<paramname="lRealHandle">NET_DVR_RealPlay_V40的返回值</param>

///<paramname="dwPTZPresetCmd">预置位控制命令</param>

///<paramname="dwPresetIndex">预置位编号最多支持255个预置点</param>

///<returns>TRUE表示成功,FALSE表示失败</returns>

boolNET_DVR_PTZPreset(intlRealHandle,uintdwPTZPresetCmd,uintdwPresetIndex);


3)反向操作

Hik.NET_DVR_PTZPreset(_realHandle,(uint)8,33);



7.获取设备的配置信息

在设定某些配置时,需预先执行此方法来获取相关配置信息的结构体。

///<summary>

///获取设备的配置信息

///</summary>

///<paramname="lUserID">NET_DVR_Login_V30的返回值</param>

///<paramname="dwCommand">设备配置命令</param>

///<paramname="lChannel">通道号或者组号,不同的命令对应不同的取值</param>

///<paramname="lpOutBuffer">接收数据的缓冲指针</param>

///<paramname="dwOutBufferSize">接收数据的缓冲长度(以字节为单位),不能为0</param>

///<paramname="lpBytesReturned">实际收到的数据长度指针,不能为NULL</param>

///<returns></returns>

boolNET_DVR_GetDVRConfig(intlUserID,uintdwCommand,intlChannel,IntPtrlpOutBuffer,uintdwOutBufferSize,refuintlpBytesReturned);


具体调用见下面操作示例


8.设置设备的配置信息

///<summary>

///设置设备的配置信息

///</summary>

///<paramname="lUserID">NET_DVR_Login_V30的返回值</param>

///<paramname="dwCommand">设备配置命令</param>

///<paramname="lChannel">通道号或者组号,不同的命令对应不同的取值

<param>

///<paramname="lpInBuffer">输入数据的缓冲指针</param>

///<paramname="dwInBufferSize">输入数据的缓冲长度(以字节为单位)</param>

///<returns></returns>

boolNET_DVR_SetDVRConfig(intlUserID,uintdwCommand,intlChannel,IntPtrlpInBuffer,uintdwInBufferSize);


具体调用见下面操作示例


9.日夜切换(前端参数配置结构体中)

1)设备配置命令

3369;//IPC设置CCD参数配置

3368;//IPC获取CCD参数配置


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_CAMERAPARAMCFG_EXcameraParamCfg=newHik.NET_DVR_CAMERAPARAMCFG_EX();//实例化前端参数结构体

Int32nSize=Marshal.SizeOf(cameraParamCfg);//获取结构体空间大小

IntPtrptrCfg=Marshal.AllocHGlobal(nSize);//设置指针大小

Hik.NET_DVR_GetDVRConfig(_userId,3368,_channelId,ptrCfg,(UInt32)nSize,refdwReturn);//获取配置信息的指针

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_DAYNIGHTstruDayNight;/*日夜转换*/


6)设置配置信息

Hik.NET_DVR_CAMERAPARAMCFG_EXcameraParamCfg=获取配置信息();

Int32size=Marshal.SizeOf(cameraParamCfg);//获取结构体大小

IntPtrptrCfg=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);//释放指针



10.透雾切换(前端参数配置结构体中)

1)设备配置命令

3369;//IPC设置CCD参数配置

3368;//IPC获取CCD参数配置


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_CAMERAPARAMCFG_EXcameraParamCfg=newHik.NET_DVR_CAMERAPARAMCFG_EX();//实例化前端参数结构体

Int32nSize=Marshal.SizeOf(cameraParamCfg);//获取结构体空间大小

IntPtrptrCfg=Marshal.AllocHGlobal(nSize);//设置指针大小

Hik.NET_DVR_GetDVRConfig(_userId,3368,_channelId,ptrCfg,(UInt32)nSize,refdwReturn);//获取配置信息的指针

cameraParamCfg=(Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg,typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//指针转换为数据结构

Marshal.FreeHGlobal(ptrCfg);//释放指针


4)透雾切换命令

0关闭

2开启


5)透雾切换结构体

NET_DVR_DEFOGCFGstruDefogCfg;//透雾参数


6)设置配置信息

Hik.NET_DVR_CAMERAPARAMCFG_EXcameraParamCfg=获取配置信息();

Int32size=Marshal.SizeOf(cameraParamCfg);//获取结构体大小

IntPtrptrCfg=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);//释放指针



11.聚焦模式切换

1)设备配置命令

3306;//设置快球聚焦模式参数

3305;//获取快球聚焦模式参数


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_FOCUSMODE_CFGfocusModeCfg=newHik.NET_DVR_FOCUSMODE_CFG();//实例化聚焦模式结构体

Int32size=Marshal.SizeOf(focusModeCfg);//获取结构体大小

IntPtrptrCfg=Marshal.AllocHGlobal(size);//设置指针空间大小

Hik.NET_DVR_GetDVRConfig(_userId,3305,_channelId,ptrCfg,(UInt32)size,refdwReturn);//获取聚焦模式信息的指针

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_CFGfocusModeCfg=获取配置信息();

Int32size=Marshal.SizeOf(focusModeCfg);//获取结构体大小

IntPtrptrCfg=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);//释放指针



12.OSD字符设置

1)设备配置命令

1030;//获取叠加字符操作命令

1031;//设置叠加字符操作命令


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_SHOWSTRING_V30struShowStrCfg=newHik.NET_DVR_SHOWSTRING_V30();//初始化叠加字符结构体

Int32size=Marshal.SizeOf(struShowStrCfg);//获取结构体空间大小

IntPtrptr=Marshal.AllocHGlobal(size);//设置指针大小

Hik.NET_DVR_GetDVRConfig(_userId,1030,_channelId,ptr,(UInt32)size,refdwReturn);//获取配置信息

struShowStrCfg=(Hik.NET_DVR_SHOWSTRING_V30)Marshal.PtrToStructure(ptr,typeof(Hik.NET_DVR_SHOWSTRING_V30));//指针转换为结构体

Marshal.FreeHGlobal(ptr);//释放指针


4)叠加字符结构体

NET_DVR_SHOWSTRINGINFOstruStringInfo;/*要显示的字符内容*/


说明:设置叠加字符需要为其属性赋值。

5)设置配置信息

Hik.NET_DVR_SHOWSTRING_V30struShowStrCfg=获取叠加字符配置信息();

Int32size=Marshal.SizeOf(struShowStrCfg);//获取结构体空间大小

IntPtrptr=Marshal.AllocHGlobal(size);//设置指针空间大小

Stringosd="海康智能监控视频一";

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);//释放指针


说明:可以叠加显示多个字符串。


13.球机定位速度设置

1)设备配置命令

3270;//获取PTZ基本参数信息

3271;//设置PTZ基本参数信息


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_PTZ_BASICPARAMCFGbasicParamCfg=newHik.NET_DVR_PTZ_BASICPARAMCFG();//初始化PTZ基本参数结构体

Int32size=Marshal.SizeOf(basicParamCfg);//获取结构体空间大小

IntPtrptr=Marshal.AllocHGlobal(size);//设置指针大小

Hik.NET_DVR_GetDVRConfig(userId,3270,_channelId,ptr,(UInt32)size,refbytesReturned);//获取配置参数指针

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_BASICPARAMCFGbasicParamCfg


6)设置配置信息

Hik.NET_DVR_PTZ_BASICPARAMCFGbasicParamCfg=获取配置信息();

Int32size=Marshal.SizeOf(basicParamCfg);//获取结构体空间大小

IntPtrptr=Marshal.AllocHGlobal(size);//设置指针空间大小

basicParamCfg.byPresetSpeed=(byte)速度值;

Marshal.StructureToPtr(basicParamCfg,ptr,false);//结构体转换为指针

Hik.NET_DVR_SetDVRConfig(userId,3271,_channelId,ptr,size);//设置配置信息

Marshal.FreeHGlobal(ptr);//释放指针



14.获取球机转动范围

1)设备配置命令

294;//云台获取PTZ范围


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

Hik.NET_DVR_PTZSCOPEPTZScope=newHik.NET_DVR_PTZSCOPE();//初始化球机范围信息结构体

Int32size=Marshal.SizeOf(PTZScope);//获取结构体空间大小

IntPtrptrScope=Marshal.AllocHGlobal(size);//设置指针空间大小

Hik.NET_DVR_GetDVRConfig(_userId,294,_channelId,ptrScope,(UInt32)size,refresult);//获取配置信息

PTZScope=(Hik.NET_DVR_PTZSCOPE)Marshal.PtrToStructure(ptrScope,typeof(Hik.NET_DVR_PTZSCOPE));//指针转换为结构体

Marshal.FreeHGlobal(ptrScope);//释放指针


4)球机转动范围结构体

Hik.NET_DVR_PTZSCOPEPTZScope



15.球机定位

使用球机定位功能前,需先设置球机定位速度和获取球机转动范围,再根据球机转动范围信息来操作球机定位功能。

1)设备配置命令

292;//云台设置PTZ位置

293;//云台获取PTZ位置


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)获取配置信息

//用精简方式实现

Int32size=Marshal.SizeOf(typeof(Hik.NET_DVR_PTZPOS));//获取球机位置信息结构体大小

IntPtrptrPTZ=Marshal.AllocHGlobal(size);//设置指针空间大小

Hik.NET_DVR_GetDVRConfig(_userId,293,_channelId,ptrPTZ,(UInt32)size,refresult);//获取球机位置配置信息

Hik.NET_DVR_PTZPOSPTZPos=(Hik.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPTZ,typeof(Hik.NET_DVR_PTZPOS));//指针转换为结构体

Marshal.FreeHGlobal(ptrPTZ);//释放指针


4)透雾切换结构体

Hik.NET_DVR_PTZPOSPTZPos


5)设置配置信息

Hik.NET_DVR_PTZPOSPTZPos=获取球机位置信息();

Int32size=Marshal.SizeOf(PTZPos);//获取结构体空间大小

IntPtrptr=Marshal.AllocHGlobal(size);//设置指针空间大小

PTZPos.wAction=1;//-表示定位PTZ参数

//本结构体中的wAction参数是设置时的操作类型,因此获取时该参数无效。实际显示的PTZ值是获取到的十六进制值的十分之一,如获取的水平参数P的值是0x1750,实际显示的P值为175度;获取到的垂直参数T的值是0x0789,实际显示的T值为78.9度;获取到的变倍参数Z的值是0x1100,实际显示的Z值为110度。

Stringtemp="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);//释放指针



16.零方位角控制

1)设备配置命令

3283;//零方位角控制


2)通道号或者组号

ChannelId//登录IPC设备时获取的通道号


3)零方位角控制命令

SET=0,//设置

GOTO=1,//调用

CLE=2//清除


4)零方位角控制结构体

Hik.NET_DVR_INITIALPOSITIONCTRLinitialPositionCtrl


5)设置控制信息

Hik.NET_DVR_INITIALPOSITIONCTRLinitialPositionCtrl=newHik.NET_DVR_INITIALPOSITIONCTRL();//初始化零方位角控制结构体

Int32size=Marshal.SizeOf(initialPositionCtrl);//获取结构体空间大小

IntPtrptr=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);//释放指针



17.录像回放

此功能需要硬盘录像机支持。需要先登录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_PARAstruVodPara=newHik.NET_DVR_VOD_PARA();//初始化录像回放结构体

struVodPara.dwSize=(uint)Marshal.SizeOf(struVodPara);//获取结构体空间大小

struVodPara.struIDInfo.dwChannel=(uint)_ipChannelId;//数字通道号Channelnumber,海康设备数字通道号从33开始

//struVodPara.hWnd=this.pictureBoxVideo.Handle;//不使用回调获取回放视频时,使用此属性设置回放窗口句柄

struVodPara.hWnd=IntPtr.Zero;//使用回调获取回放视频时,需如此设置回放窗口句柄

//设置回放的开始时间Setthestartingtimetosearchvideofiles

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;

//设置回放的结束时间Setthestoppingtimetosearchvideofiles

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功能说明文档。

//按时间回放Playbackbytime

_realHandle=Hik.NET_DVR_PlayBackByTime_V40(_NVRUserId,refstruVodPara);//struVodPara为录像回放结构体


4)录像数据回调函数的使用

///<summary>

///录像数据回调函数

///</summary>

///<paramname="lPlayHandle">当前的录像播放句柄</param>

///<paramname="dwDataType">数据类型</param>

///<paramname="pBuffer">存放数据的缓冲区指针</param>

///<paramname="dwBufSize">缓冲区大小</param>

///<paramname="pUser">用户数据</param>

publicdelegatevoidPlayDataCallBack_V40(Int32lPlayHandle,UInt32dwDataType,IntPtrpBuffer,UInt32dwBufSize,IntPtrpUser);


此回调函数的使用方式与实时流回调函数的操作方式类似,都是获取视频流后,用播放库解码,返回角度信息和解码后的视频流。

Hik.NET_DVR_PlayBackControl_V40(_realHandle,1,IntPtr.Zero,0,IntPtr.Zero,refiOutValue);//播放录像回放视频


5)停止录像回放

Hik.NET_DVR_StopPlayBack(_realHandle)



18.录像下载

1)初始化录像下载结构体

Hik.NET_DVR_PLAYCONDstruDownPara=newHik.NET_DVR_PLAYCOND();//初始化录像下载结构体

struDownPara.dwChannel=(uint)_ipChannelId;//数字通道号Channelnumber

//设置下载的开始时间Setthestartingtime

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;

//设置下载的结束时间Setthestoppingtime

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_PLAYCONDstruDownPara


3)录像下载

录像下载后默认保存格式为mp4。

_realHandle=Hik.NET_DVR_GetFileByTime_V40(_NVRUserId,sVideoFileName,refstruDownPara);



Plat_SDK编程指南

海康平台可以挂载多个NVR设备,调用NVR下挂载的IPC设备时,只需要在海康平台的设备设置中找到其摄像头ID即可。


(一)SDK的引用

具体引用方式,参见IPC_SDK的引用。由于海康平台技术人员提供的DLL文件过于繁杂,就不一一列出DLL的说明,详情参见IVMS_SDK文件夹目录。


(二)C#程序调用DLL中的非托管函数方法

详情参见C#程序调用DLL中的非托管函数方法。


(三)SDK的调用

根据海康视频设备及平台使用的方案设计,只应用海康平台SDK的视频回调显示功能,其它功能暂不使用。对Plat_SDK的C#封装类见附件HikIVMS.cs,可参考此基础类文件进行程序功能编写。


1.获取错误码

Plat_GetLastError(_userId);//获取错误码,userId为登录后获得的用户ID


使用方式:如果每个非托管函数方法返回结果不为0(正确),则调用此方法获取错误码。

例如:

Int32ret=Plat_Init();

if(ret!=0)

thrownewHikIVMSException(Plat_GetLastError(_userId));//HikIVMSException为自定义异常调用类,用来解析错误码抛出异常



2.登录

1)用户注册

Int32ret;

ret=Plat_Init();//platformSDK初始化

if(ret!=0)

thrownewHikIVMSException(Plat_GetLastError(_userId));

IntPtrptrIP=Marshal.StringToHGlobalAnsi(uri.Host);//IP

IntPtrptrUserName=Marshal.StringToHGlobalAnsi(a[0]);//用户名

IntPtrptrPassword=Marshal.StringToHGlobalAnsi(a[1]);//密码

IntPtrptrPort=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,必须执行



3.预览

1)播放预览

///<summary>

///播放实时视频(开始预览/回放)

///</summary>

///<paramname="url">预览或回放的播放路径,由Plat_QueryRealStreamURL或Plat_QueryRecordFile</param>

///<paramname="hWnd">播放窗口句柄,如果为空,则不播放</param>

///<paramname="userHandle">用户ID</param>

///<paramname="streamCallback">视频码流接收回调函数指针,如果回调函数为NULL则不给码流</param>

///<returns>>=0成功,返回实时视频句柄,错误时返回-1</returns>

Int32Plat_PlayVideo(Stringurl,IntPtrhWnd,Int32userHandle,fStreamCallbackstreamCallback,IntPtruser);


例如:

_streamHandle=Plat_PlayVideo(cameraId,IntPtr.Zero,_userId,callback,IntPtr.Zero);


注意:此函数的第一个参数,在应用中只需要传入摄像机ID即可。

2)实时流回调函数的使用

///<summary>

///实时流回调

///</summary>

///<paramname="handle">Plat_PlayVideo返回的句柄</param>

///<paramname="data">接收视频码流数据缓冲区指针</param>

///<paramname="size">接收视频码流数据字节数</param>

///<paramname="user">用户数据</param>

publicdelegatevoidfStreamCallback(Int32handle,IntPtrdata,UInt32size,IntPtruser,UInt32dataType);


其调用方式与IPC_SDK中回调实时视频流的方式相同,都是调用播放库解码,然后返回角度信息和解码后的视频。详情参见IPC_SDK预览功能说明

示例如下:

privateHikIVMS.fStreamCallback_callback;

privateHikIVMS.DECCBFUN_displayCallback;//解码回调

privateHikIVMS.ADDITIONDATACBFUN_additionDataDisplayCallback;//角度回调


if(_callback==null)

_callback=newHikIVMS.fStreamCallback(StreamCallback);

if(_displayCallback==null)

_displayCallback=newHikIVMS.DECCBFUN(DecCallbackFUN);

if(_additionDataDisplayCallback==null)

_additionDataDisplayCallback=newHikIVMS.ADDITIONDATACBFUN(AdditionDataCallBackFUN);

Hik.Play(cameraCode,_callback);


注意:Plat的回调函数与IPC回调函数中唯一的区别在于数据类型的定义不同,IPC的系统头数据类型为1,视频流数据类型为2;Plat系统头数据类型为0,视频流数据类型为1,仅此区别,其它相同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: