Unity接入海康相机SDK(2023/6/21)
1.问题描述:控制海康相机进行操作(远焦、近焦、上下左右移动等)。
2.准备:官网下载SDK:https://open.hikvision.com/#home
选择适合自己平台代码语言开发的SDK下载
Demo里有对应案例可查看
在库文件里除了ClientDemoDll文件 都拖进unityPlugins ,然后有两个重复Dll文件(OpenAL,AudioRender)删除即可
嫌多的,到最后根据用不着的慢慢删除就行
3.开始脚本(两个脚本)
(1)引用Dll的脚本
public class HCNetSDK
{
#region HCNetSDK.dll function definition
// function definition
/* The SDK initialization function */
// 初始化SDK,调用其他SDK函数的前提
[DllImport(@"HCNetSDK.dll")]
public static extern bool NET_DVR_Init();
// 启用日志文件写入接口
[DllImport(@"HCNetSDK.dll")]
public static extern bool NET_DVR_SetLogToFile(int nLogLevel, IntPtr strLogDir, bool bAutoDel);
// 返回最后操作的错误码
[DllImport(@"HCNetSDK.dll")]
public static extern uint NET_DVR_GetLastError();
// 释放SDK资源,在程序结束之前调用
[DllImport(@"HCNetSDK.dll")]
public static extern bool NET_DVR_Cleanup();
// 登录接口 v40
[DllImport(@"HCNetSDK.dll")]
public static extern int NET_DVR_Login_V40(ref NET_DVR_USER_LOGIN_INFO pLoginInfo, ref NET_DVR_DEVICEINFO_V40 lpDeviceInfo);
// 用户注销
[DllImport(@"HCNetSDK.dll")]
public static extern bool NET_DVR_Logout(int lUserID);
// 回调函数声明,登录状态回调函数
public delegate void LoginResultCallBack(int lUserID, uint dwResult, ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo, IntPtr pUser);
//云台控制
[DllImport(@"HCNetSDK.dll")]
public static extern bool NET_DVR_PTZControlWithSpeed_Other(int lUserID, int lChannel, uint dwPTZCommand, uint dwStop, uint dwSpeed);
#endregion
#region HCNetSDK.dll structure definition
[StructLayout(LayoutKind.Sequential)]
public struct NET_DVR_USER_LOGIN_INFO
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_DEV_ADDRESS_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] sDeviceAddress;
public byte byUseTransport;
public ushort wPort;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_LOGIN_USERNAME_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] sUserName;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_LOGIN_PASSWD_MAX_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] sPassword;
public LoginResultCallBack cbLoginResult;
public IntPtr pUser;
public bool bUseAsynLogin;
public byte byProxyType; //0:不使用代理,1:使用标准代理,2:使用EHome代理
public byte byUseUTCTime; //0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换
public byte byLoginMode; //0-Private, 1-ISAPI, 2-自适应
public byte byHttps; //0-不适用tls,1-使用tls 2-自适应
public uint iProxyID; //代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值
public byte byVerifyMode; //认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 119, ArraySubType = UnmanagedType.I1)]
public byte[] byRes3;
}
public const int NET_DVR_DEV_ADDRESS_MAX_LEN = 129; //device address max length
public const int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64; //login username max length
public const int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64; //login password max length
public struct NET_DVR_DEVICEINFO_V40
{
public NET_DVR_DEVICEINFO_V30 struDeviceV30;
public byte bySupportLock; //设备支持锁定功能,该字段由SDK根据设备返回值来赋值的。bySupportLock为1时,dwSurplusLockTime和byRetryLoginTime有效
public byte byRetryLoginTime; //剩余可尝试登陆的次数,用户名,密码错误时,此参数有效
public byte byPasswordLevel; //admin密码安全等级0-无效,1-默认密码,2-有效密码,3-风险较高的密码。当用户的密码为出厂默认密码(12345)或者风险较高的密码时,上层客户端需要提示用户更改密码。
public byte byProxyType;//代理类型,0-不使用代理, 1-使用socks5代理, 2-使用EHome代理
public uint dwSurplusLockTime; //剩余时间,单位秒,用户锁定时,此参数有效
public byte byCharEncodeType; //字符编码类型(SDK所有接口返回的字符串编码类型,透传接口除外):0- 无字符编码信息(老设备),1- GB2312(简体中文),2- GBK,3- BIG5(繁体中文),4- Shift_JIS(日文),5- EUC-KR(韩文),6- UTF-8,7- ISO8859-1,8- ISO8859-2,9- ISO8859-3,…,依次类推,21- ISO8859-15(西欧)
public byte bySupportDev5;//支持v50版本的设备参数获取,设备名称和设备类型名称长度扩展为64字节
public byte bySupport; //能力集扩展,位与结果:0- 不支持,1- 支持
// bySupport & 0x1: 保留
// bySupport & 0x2: 0-不支持变化上报 1-支持变化上报
public byte byLoginMode; //登录模式 0-Private登录 1-ISAPI登录
public int dwOEMCode;
public int iResidualValidity; //该用户密码剩余有效天数,单位:天,返回负值,表示密码已经超期使用,例如“-3表示密码已经超期使用3天”
public byte byResidualValidity; // iResidualValidity字段是否有效,0-无效,1-有效
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 243, ArraySubType = UnmanagedType.I1)]
public byte[] byRes2;
}
public const int SERIALNO_LEN = 48;//序列号长度
public struct NET_DVR_DEVICEINFO_V30
{
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = SERIALNO_LEN, ArraySubType = UnmanagedType.I1)]
public byte[] sSerialNumber; //序列号
public byte byAlarmInPortNum; //报警输入个数
public byte byAlarmOutPortNum; //报警输出个数
public byte byDiskNum; //硬盘个数
public byte byDVRType; //设备类型, 1:DVR 2:ATM DVR 3:DVS ......
public byte byChanNum; //模拟通道个数
public byte byStartChan; //起始通道号,例如DVS-1,DVR - 1
public byte byAudioChanNum; //语音通道数
public byte byIPChanNum; //最大数字通道个数,低位
public byte byZeroChanNum; //零通道编码个数 //2010-01-16
public byte byMainProto; //主码流传输协议类型 0-private, 1-rtsp,2-同时支持private和rtsp
public byte bySubProto; //子码流传输协议类型0-private, 1-rtsp,2-同时支持private和rtsp
public byte bySupport; //能力,位与结果为0表示不支持,1表示支持,
//bySupport & 0x1, 表示是否支持智能搜索
//bySupport & 0x2, 表示是否支持备份
//bySupport & 0x4, 表示是否支持压缩参数能力获取
//bySupport & 0x8, 表示是否支持多网卡
//bySupport & 0x10, 表示支持远程SADP
//bySupport & 0x20, 表示支持Raid卡功能
//bySupport & 0x40, 表示支持IPSAN 目录查找
//bySupport & 0x80, 表示支持rtp over rtsp
public byte bySupport1; // 能力集扩充,位与结果为0表示不支持,1表示支持
//bySupport1 & 0x1, 表示是否支持snmp v30
//bySupport1 & 0x2, 支持区分回放和下载
//bySupport1 & 0x4, 是否支持布防优先级
//bySupport1 & 0x8, 智能设备是否支持布防时间段扩展
//bySupport1 & 0x10, 表示是否支持多磁盘数(超过33个)
//bySupport1 & 0x20, 表示是否支持rtsp over http
//bySupport1 & 0x80, 表示是否支持车牌新报警信息2012-9-28, 且还表示是否支持NET_DVR_IPPARACFG_V40结构体
public byte bySupport2; /*能力,位与结果为0表示不支持,非0表示支持
bySupport2 & 0x1, 表示解码器是否支持通过URL取流解码
bySupport2 & 0x2, 表示支持FTPV40
bySupport2 & 0x4, 表示支持ANR
bySupport2 & 0x8, 表示支持CCD的通道参数配置
bySupport2 & 0x10, 表示支持布防报警回传信息(仅支持抓拍机报警 新老报警结构)
bySupport2 & 0x20, 表示是否支持单独获取设备状态子项
bySupport2 & 0x40, 表示是否是码流加密设备*/
public ushort wDevType; //设备型号
public byte bySupport3; //能力集扩展,位与结果为0表示不支持,1表示支持
//bySupport3 & 0x1, 表示是否多码流
// bySupport3 & 0x4 表示支持按组配置, 具体包含 通道图像参数、报警输入参数、IP报警输入、输出接入参数、
// 用户参数、设备工作状态、JPEG抓图、定时和时间抓图、硬盘盘组管理
//bySupport3 & 0x8为1 表示支持使用TCP预览、UDP预览、多播预览中的"延时预览"字段来请求延时预览(后续都将使用这种方式请求延时预览)。而当bySupport3 & 0x8为0时,将使用 "私有延时预览"协议。
//bySupport3 & 0x10 表示支持"获取报警主机主要状态(V40)"。
//bySupport3 & 0x20 表示是否支持通过DDNS域名解析取流
public byte byMultiStreamProto;//是否支持多码流,按位表示,0-不支持,1-支持,bit1-码流3,bit2-码流4,bit7-主码流,bit-8子码流
public byte byStartDChan; //起始数字通道号,0表示无效
public byte byStartDTalkChan; //起始数字对讲通道号,区别于模拟对讲通道号,0表示无效
public byte byHighDChanNum; //数字通道个数,高位
public byte bySupport4;
public byte byLanguageType;// 支持语种能力,按位表示,每一位0-不支持,1-支持
// byLanguageType 等于0 表示 老设备
// byLanguageType & 0x1表示支持中文
// byLanguageType & 0x2表示支持英文
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 9, ArraySubType = UnmanagedType.I1)]
public byte[] byRes2; //保留
}
#endregion
}
(2)控制海康相机的脚本文章来源:https://www.toymoban.com/news/detail-599617.html
public class Camera_HK : MonoBehaviour
{
public Text showMesText;
private uint iLastErr = 0;
private int m_lUserID = -1;
private HCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo;
private HCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo;
private string str;
HCNetSDK.LoginResultCallBack LoginCallBack = null;
public Button up_Button;
public Button dow_Button;
public Button lef_Button;
public Button rig_Button;
public Button zoomOut_Button;//焦距小
public Button zoomIn_Button;
Thread thread;
void Start()
{
bool m_bInitSDK = HCNetSDK.NET_DVR_Init();
if (m_bInitSDK == false)
{
Debug.Log("初始化失败!");
// showMesText.text += "初始化失败!";
return;
}
else
{
Debug.Log("初始化成功!");
// showMesText.text += "初始化成功!";
}
LoginCameraHK();
}
#region 按钮事件
/// <summary>
/// 云控制台
/// </summary>
/// <param name="登录成功返回的ID"></param>
/// <param name="默认1"></param>
/// <param name="平台控制命令"></param>
/// <param name="开始/停止"></param>
/// <param name="速度"></param>
/// <param name="备注"></param>
private void ControlHead(int lUserID, int lChannel, uint dwPTZCommand, uint dwStop, uint dwSpeed,string remarks="")
{
if (HCNetSDK.NET_DVR_PTZControlWithSpeed_Other(lUserID, lChannel, dwPTZCommand, dwStop, dwSpeed))
{
Debug.Log("控制云台成功!"+ remarks);
}
else
{
Debug.Log("控制云台失败...");
ViewErrorInfo("初始化失败!", HCNetSDK.NET_DVR_GetLastError());
}
}
//Button 按钮 Event Trigger 组件 按下开始做操作 抬起 停止
public void up_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 21, 0, 2, "开始上仰");
}
public void up_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 21, 1, 2, "关闭上仰");
}
public void dow_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 22, 0, 2, "开始下俯");
}
public void dow_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 22, 1, 2, "关闭下俯");
}
public void lef_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 23, 0, 2, "开始左转");
}
public void lef_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 23, 1, 2, "关闭左转");
}
public void rig_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 24, 0, 2, "开始右转");
}
public void rig_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 24, 1, 2, "关闭右转");
}
public void zoomOut_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 11, 0, 2, "开始焦距变小");
}
public void zoomOut_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 11, 1, 2, "关闭焦距变小");
}
public void zoomIn_ButtonDownEvent()
{
ControlHead(m_lUserID, 1, 12, 0, 2, "开始焦距变大");
}
public void zoomIn_ButtonUpEvent()
{
ControlHead(m_lUserID, 1, 12, 1, 2, "关闭焦距变大");
}
#endregion
private void ViewErrorInfo(string errorMessage, uint errorCode)
{
Debug.Log(errorMessage + ", 错误代码: " + errorCode);
}
public void LoginCameraHK()
{
struLogInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
if (m_lUserID < 0)
{
//从textBox文本框读取字符串,转成byte数组之后,赋值给结构体对象中对应字段
//设备IP地址或者域名
byte[] byIP = System.Text.Encoding.Default.GetBytes("192.168.0.201"); //改成自己的
struLogInfo.sDeviceAddress = new byte[129];
byIP.CopyTo(struLogInfo.sDeviceAddress, 0);
//设备用户名
byte[] byUserName = System.Text.Encoding.Default.GetBytes("admin"); // 改成自己的
struLogInfo.sUserName = new byte[64];
byUserName.CopyTo(struLogInfo.sUserName, 0);
//设备密码
byte[] byPassword = System.Text.Encoding.Default.GetBytes("q123456.");///改成自己的
struLogInfo.sPassword = new byte[64];
byPassword.CopyTo(struLogInfo.sPassword, 0);
struLogInfo.wPort = ushort.Parse("8000");//设备服务端口号 ///改成自己的 这边注意视频流554 等不是端口 ,端口需要进海康相机自带平台去看一下
if (LoginCallBack == null)
{
LoginCallBack = new HCNetSDK.LoginResultCallBack(cbLoginCallBack);//注册回调函数
}
struLogInfo.cbLoginResult = LoginCallBack;
struLogInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是
DeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
//登录设备 Login the device
m_lUserID = HCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);
if (m_lUserID < 0)
{
iLastErr = HCNetSDK.NET_DVR_GetLastError();
str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败,输出错误号\
Debug.Log(str);
// showMesText.text += str;
return;
}
else
{
Debug.Log("m_lUserID:" + m_lUserID);
//登录成功
Debug.Log("登陆成功!");
// showMesText.text += "登陆成功!";
}
}
else
{
//注销登录 Logout the device
if (!HCNetSDK.NET_DVR_Logout(m_lUserID))
{
iLastErr = HCNetSDK.NET_DVR_GetLastError();
str = "NET_DVR_Logout failed, error code= " + iLastErr;
Debug.LogWarning(str);
return;
}
m_lUserID = -1;
}
}
private void cbLoginCallBack(int lUserID, uint dwResult, ref HCNetSDK.NET_DVR_DEVICEINFO_V30 lpDeviceInfo, IntPtr pUser)
{
string strLoginCallBack = "登录设备,lUserID:" + lUserID + ",dwResult:" + dwResult;
Debug.Log("cbLoginCallBack:" + strLoginCallBack);
// showMesText.text += strLoginCallBack;
}
private void OnApplicationQuit()
{
Debug.Log("用户注销...");
HCNetSDK.NET_DVR_Logout(m_lUserID);
m_lUserID = -1;
Debug.Log("SDK资源卸载...");
HCNetSDK.NET_DVR_Cleanup();
}
再具体可结合海康提供的接口文本去查看
参考文章:Unity3d C# 接入海康威视摄像头SDK实现接口控制功能(如:控制云台) 作者:十幺卜入文章来源地址https://www.toymoban.com/news/detail-599617.html
到了这里,关于Unity接入海康相机SDK(保姆级)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!