海康SDK编程指南(C#二次开发版本)
2016-02-24 20:54
621 查看
转载于整理自:心澄欲遣
目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息。本文仅对视频监控常用功能的使用进行说明,其它未实现功能请参看设备网络SDK使用手册和播放库编程指南V7.2。
目前使用的海康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),通过播放库的两个回调函数来返回解析后的视频流和角度。角度回调信息的格式为我公司定制协议,具体内容参看
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的引用
具体引用方式,参见
(二)C#程序调用DLL中的非托管函数方法
详情参见
(三)SDK的调用
根据海康视频设备及平台使用的方案设计,只应用海康平台SDK的视频回调显示功能,其它功能暂不使用。对Plat_SDK的C#封装类见附件
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中回调实时视频流的方式相同,都是调用播放库解码,然后返回角度信息和解码后的视频。详情参见
示例如下:
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,仅此区别,其它相同。
相关文章推荐
- C#FileStream文件流(字符)
- C#高级编程(三)
- 如何有效的使用C#读取文件
- 【C#】Color颜色对照表
- C#之构造方法
- C# 结构的特点
- C#-StructLayoutAttribute(结构体布局)
- C#中的IntPtr类型
- C#将一个excel工作表根据指定范围拆分为多个excel文件
- C# DataTable Compute方法的使用
- C#访问openfire服务器之一:服务端的安装、客户端的简介
- C#调用金数据API
- C#访问openfire服务器之三:一次成功的登录
- C#原理
- C# using 三种使用方式
- C#怎么设置子窗体在主窗体中居中显示
- C#进阶系列——WebApi接口测试工具:WebApiTestClient
- C#创建唯一的订单号, 考虑时间因素
- C# 串口通讯
- C# DateTime详解