一、海康摄像头SDK官网下载
1、进入海康ws官网,下载官网SDK和相关文档
2、根据自己应用程序是32位还是64位下载相应的SDK文件。
3、解压下载的SDK到本地,最好是非C盘。
在线SDK工作手册HaiK的SDK工作手册
二、海康摄像头SDK在WinForm/WPF中使用
1、下载的库文件如下图,HCNetSDKCom文件夹和txt文档中介绍的库文件都要放在项目路径(bin路径下的Release或者Debug文件夹)下。
2、在项目中加入CHCNetSDK类。SDK 有一万多行,以下只列举CHCNetSDK类的开始部分和结束部分。
以下仅为示例的代码片段,要查看全部CHCNetSDK类,参考前面第一部分从官网下载SDK包,其中有CHCNetSDK类
using System;
using System.Runtime.InteropServices;
namespace NVRCsharpDemo
{
/// <summary>
/// CHCNetSDK 的摘要说明。
/// </summary>
public class CHCNetSDK
{
public CHCNetSDK()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
//SDK类型
public const int SDK_PLAYMPEG4 = 1;//播放库
public const int SDK_HCNETSDK = 2;//网络库
public const int NAME_LEN = 32;//用户名长度
public const int PASSWD_LEN = 16;//密码长度
public const int GUID_LEN = 16; //GUID长度
public const int DEV_TYPE_NAME_LEN = 24; //设备类型名称长度
public const int MAX_NAMELEN = 16;//DVR本地登陆名
public const int MAX_RIGHT = 32;//设备支持的权限(1-12表示本地权限,13-32表示远程权限)
public const int SERIALNO_LEN = 48;//序列号长度
public const int MACADDR_LEN = 6;//mac地址长度
public const int MAX_ETHERNET = 2;//设备可配以太网络
public const int MAX_NETWORK_CARD = 4; //设备可配最大网卡数目
public const int PATHNAME_LEN = 128;//路径长度
public const int MAX_NUMBER_LEN = 32; //号码最大长度
public const int MAX_NAME_LEN = 128; //设备名称最大长度
public const int MAX_TIMESEGMENT_V30 = 8;//9000设备最大时间段数
public const int MAX_TIMESEGMENT = 4;//8000设备最大时间段数
public const int MAX_ICR_NUM = 8; //抓拍机红外滤光片预置点数
public const int MAX_SHELTERNUM = 4;//8000设备最大遮挡区域数
public const int PHONENUMBER_LEN = 32;//pppoe拨号号码最大长度
public const int MAX_DISKNUM = 16;//8000设备最大硬盘数
public const int MAX_DISKNUM_V10 = 8;//1.2版本之前版本
public const int MAX_WINDOW_V30 = 32;//9000设备本地显示最大播放窗口数
public const int MAX_WINDOW = 16;//8000设备最大硬盘数
public const int MAX_VGA_V30 = 4;//9000设备最大可接VGA数
public const int MAX_VGA = 1;//8000设备最大可接VGA数
public const int MAX_USERNUM_V30 = 32;//9000设备最大用户数
public const int MAX_USERNUM = 16;//8000设备最大用户数
public const int MAX_EXCEPTIONNUM_V30 = 32;//9000设备最大异常处理数
public const int MAX_EXCEPTIONNUM = 16;//8000设备最大异常处理数
public const int MAX_LINK = 6;//8000设备单通道最大视频流连接数
public const int MAX_ITC_EXCEPTIONOUT = 32;//抓拍机最大报警输出
public const int MAX_DECPOOLNUM = 4;//单路解码器每个解码通道最大可循环解码数
public const int MAX_DECNUM = 4;//单路解码器的最大解码通道数(实际只有一个,其他三个保留)
public const int MAX_TRANSPARENTNUM = 2;//单路解码器可配置最大透明通道数
public const int MAX_CYCLE_CHAN = 16; //单路解码器最大轮循通道数
public const int MAX_CYCLE_CHAN_V30 = 64;//最大轮询通道数(扩展)
public const int MAX_DIRNAME_LENGTH = 80;//最大目录长度
public const int MAX_STRINGNUM_V30 = 8;//9000设备最大OSD字符行数数
public const int MAX_STRINGNUM = 4;//8000设备最大OSD字符行数数
public const int MAX_STRINGNUM_EX = 8;//8000定制扩展
public const int MAX_AUXOUT_V30 = 16;//9000设备最大辅助输出数
public const int MAX_AUXOUT = 4;//8000设备最大辅助输出数
public const int MAX_HD_GROUP = 16;//9000设备最大硬盘组数
public const int MAX_NFS_DISK = 8; //8000设备最大NFS硬盘数
public const int IW_ESSID_MAX_SIZE = 32;//WIFI的SSID号长度
public const int IW_ENCODING_TOKEN_MAX = 32;//WIFI密锁最大字节数
public const int WIFI_WEP_MAX_KEY_COUNT = 4;
public const int WIFI_WEP_MAX_KEY_LENGTH = 33;
public const int WIFI_WPA_PSK_MAX_KEY_LENGTH = 63;
public const int WIFI_WPA_PSK_MIN_KEY_LENGTH = 8;
public const int WIFI_MAX_AP_COUNT = 20;
public const int MAX_SERIAL_NUM = 64;//最多支持的透明通道路数
public const int MAX_DDNS_NUMS = 10;//9000设备最大可配ddns数
public const int MAX_EMAIL_ADDR_LEN = 48;//最大email地址长度
public const int MAX_EMAIL_PWD_LEN = 32;//最大email密码长度
public const int MAXPROGRESS = 100;//回放时的最大百分率
public const int MAX_SERIALNUM = 2;//8000设备支持的串口数 1-232, 2-485
public const int CARDNUM_LEN = 20;//卡号长度
public const int CARDNUM_LEN_OUT = 32; //外部结构体卡号长度
public const int MAX_VIDEOOUT_V30 = 4;//9000设备的视频输出数
public const int MAX_VIDEOOUT = 2;//8000设备的视频输出数
public const int MAX_PRESET_V30 = 256;// 9000设备支持的云台预置点数
public const int MAX_TRACK_V30 = 256;// 9000设备支持的云台轨迹数
public const int MAX_CRUISE_V30 = 256;// 9000设备支持的云台巡航数
public const int MAX_PRESET = 128;// 8000设备支持的云台预置点数
public const int MAX_TRACK = 128;// 8000设备支持的云台轨迹数
public const int MAX_CRUISE = 128;// 8000设备支持的云台巡航数
public const int CRUISE_MAX_PRESET_NUMS = 32;// 一条巡航最多的巡航点
public const int MAX_SERIAL_PORT = 8;//9000设备支持232串口数
public const int MAX_PREVIEW_MODE = 8;// 设备支持最大预览模式数目 1画面,4画面,9画面,16画面....
public const int MAX_MATRIXOUT = 16;// 最大模拟矩阵输出个数
public const int LOG_INFO_LEN = 11840; // 日志附加信息
public const int DESC_LEN = 16;// 云台描述字符串长度
public const int PTZ_PROTOCOL_NUM = 200;// 9000最大支持的云台协议数
public const int MAX_AUDIO = 1;//8000语音对讲通道数
public const int MAX_AUDIO_V30 = 2;//9000语音对讲通道数
public const int MAX_CHANNUM = 16;//8000设备最大通道数
public const int MAX_ALARMIN = 16;//8000设备最大报警输入数
public const int MAX_ALARMOUT = 4;//8000设备最大报警输出数
//9000 IPC接入
public const int MAX_ANALOG_CHANNUM = 32;//最大32个模拟通道
public const int MAX_ANALOG_ALARMOUT = 32; //最大32路模拟报警输出
public const int MAX_ANALOG_ALARMIN = 32;//最大32路模拟报警输入
public const int MAX_IP_DEVICE = 32;//允许接入的最大IP设备数
public const int MAX_IP_DEVICE_V40 = 64;//允许接入的最大IP设备数
public const int MAX_IP_CHANNEL = 32;//允许加入的最多IP通道数
public const int MAX_IP_ALARMIN = 128;//允许加入的最多报警输入数
public const int MAX_IP_ALARMOUT = 64;//允许加入的最多报警输出数
public const int MAX_IP_ALARMIN_V40 = 4096; //允许加入的最多报警输入数
public const int MAX_IP_ALARMOUT_V40 = 4096; //允许加入的最多报警输出数
public const int MAX_RECORD_FILE_NUM = 20; // 每次删除或者刻录的最大文件数
//SDK_V31 ATM
public const int MAX_ATM_NUM = 1;
public const int MAX_ACTION_TYPE = 12;
public const int ATM_FRAMETYPE_NUM = 4;
public const int MAX_ATM_PROTOCOL_NUM = 1025;
public const int ATM_PROTOCOL_SORT = 4;
public const int ATM_DESC_LEN = 32;
// SDK_V31 ATM
/* 最大支持的通道数 最大模拟加上最大IP支持 */
public const int MAX_CHANNUM_V30 = MAX_ANALOG_CHANNUM + MAX_IP_CHANNEL;//64
public const int MAX_ALARMOUT_V30 = MAX_ANALOG_ALARMOUT + MAX_IP_ALARMOUT;//96
public const int MAX_ALARMIN_V30 = MAX_ANALOG_ALARMIN + MAX_IP_ALARMIN;//160
public const int MAX_CHANNUM_V40 = 512;
public const int MAX_ALARMOUT_V40 = MAX_IP_ALARMOUT_V40 + MAX_ANALOG_ALARMOUT;//4128
public const int MAX_ALARMIN_V40 = MAX_IP_ALARMIN_V40 + MAX_ANALOG_ALARMOUT;//4128
public const int MAX_MULTI_AREA_NUM = 24;
public const int MAX_HUMAN_PICTURE_NUM = 10; //最大照片数
public const int MAX_HUMAN_BIRTHDATE_LEN = 10;
public const int MAX_LAYERNUMS = 32;
public const int MAX_ROIDETECT_NUM = 8; //支持的ROI区域数
public const int MAX_LANERECT_NUM = 5; //最大车牌识别区域数
public const int MAX_FORTIFY_NUM = 10; //最大布防个数
public const int MAX_INTERVAL_NUM = 4; //最大时间间隔个数
public const int MAX_CHJC_NUM = 3; //最大车辆省份简称字符个数
public const int MAX_VL_NUM = 5; //最大虚拟线圈个数
public const int MAX_DRIVECHAN_NUM = 16; //最大车道数
public const int MAX_COIL_NUM = 3; //最大线圈个数
public const int MAX_SIGNALLIGHT_NUM = 6; //最大信号灯个数
public const int LEN_32 = 32;
public const int LEN_31 = 31;
public const int MAX_CABINET_COUNT = 8; //最大支持机柜数量
public const int MAX_ID_LEN = 48;
public const int MAX_PARKNO_LEN = 16;
public const int MAX_ALARMREASON_LEN = 32;
public const int MAX_UPGRADE_INFO_LEN= 48; //获取升级文件匹配信息(模糊升级)
public const int MAX_CUSTOMDIR_LEN = 32; //自定义目录长度
public const int MAX_TRANSPARENT_CHAN_NUM = 4; //每个串口允许建立的最大透明通道数
public const int MAX_TRANSPARENT_ACCESS_NUM = 4; //每个监听端口允许接入的最大主机数
//ITS
public const int MAX_PARKING_STATUS = 8; //车位状态 0代表无车,1代表有车,2代表压线(优先级最高), 3特殊车位
public const int MAX_PARKING_NUM = 4; //一个通道最大4个车位 (从左到右车位 数组0~3)
public const int MAX_ITS_SCENE_NUM = 16; //最大场景数量
public const int MAX_SCENE_TIMESEG_NUM = 16; //最大场景时间段数量
public const int MAX_IVMS_IP_CHANNEL = 128; //最大IP通道数
public const int DEVICE_ID_LEN = 48; //设备编号长度
public const int MONITORSITE_ID_LEN = 48; //监测点编号长度
public const int MAX_AUXAREA_NUM = 16; //辅助区域最大数目
public const int MAX_SLAVE_CHANNEL_NUM = 16; //最大从通道数量
public const int MAX_SCH_TASKS_NUM = 10;
public const int MAX_SERVERID_LEN = 64; //最大服务器ID的长度
public const int MAX_SERVERDOMAIN_LEN = 128; //服务器域名最大长度
public const int MAX_AUTHENTICATEID_LEN = 64; //认证ID最大长度
public const int MAX_AUTHENTICATEPASSWD_LEN = 32; //认证密码最大长度
public const int MAX_SERVERNAME_LEN = 64; //最大服务器用户名
public const int MAX_COMPRESSIONID_LEN = 64; //编码ID的最大长度
public const int MAX_SIPSERVER_ADDRESS_LEN = 128; //SIP服务器地址支持域名和IP地址
//压线报警
public const int MAX_PlATE_NO_LEN = 32; //车牌号码最大长度 2013-09-27
public const int UPNP_PORT_NUM = 12; //upnp端口映射端口数目
public const int MAX_LOCAL_ADDR_LEN = 96; //SOCKS最大本地网段个数
public const int MAX_COUNTRY_NAME_LEN = 4; //国家简写名称长度
public const int THERMOMETRY_ALARMRULE_NUM = 40; //热成像报警规则数
public const int ACS_CARD_NO_LEN = 32; //门禁卡号长度
public const int MAX_ID_NUM_LEN = 32; //最大身份证号长度
public const int MAX_ID_NAME_LEN = 128; //最大姓名长度
public const int MAX_ID_ADDR_LEN = 280; //最大住址长度
public const int MAX_ID_ISSUING_AUTHORITY_LEN = 128; //最大签发机关长度
public const int MAX_CARD_RIGHT_PLAN_NUM = 4; //卡权限最大计划个数
public const int MAX_GROUP_NUM_128 = 128; //最大群组数
public const int MAX_CARD_READER_NUM = 64; //最大读卡器数
public const int MAX_SNEAK_PATH_NODE = 8; //最大后续读卡器数
public const int MAX_MULTI_DOOR_INTERLOCK_GROUP = 8; //最大多门互锁组数
public const int MAX_INTER_LOCK_DOOR_NUM = 8; //一个多门互锁组中最大互锁门数
public const int MAX_CASE_SENSOR_NUM = 8; //最大case sensor触发器数
public const int MAX_DOOR_NUM_256 = 256; //最大门数
public const int MAX_READER_ROUTE_NUM = 16; //最大刷卡循序路径
public const int MAX_FINGER_PRINT_NUM = 10; //最大指纹个数
public const int MAX_CARD_READER_NUM_512 = 512; //最大读卡器数
public const int NET_SDK_MULTI_CARD_GROUP_NUM_20 = 20; //单门最大多重卡组数
public const int CARD_PASSWORD_LEN = 8; //卡密码长度
public const int MAX_DOOR_CODE_LEN = 8; //房间代码长度
public const int MAX_LOCK_CODE_LEN = 8; //锁代码长度
public const int MAX_NOTICE_NUMBER_LEN = 32; //公告编号最大长度
public const int MAX_NOTICE_THEME_LEN = 64; //公告主题最大长度
public const int MAX_NOTICE_DETAIL_LEN = 1024; //公告详情最大长度
public const int MAX_NOTICE_PIC_NUM = 6; //公告信息最大图片数量
public const int MAX_DEV_NUMBER_LEN = 32; //设备编号最大长度
public const int LOCK_NAME_LEN = 32; //锁名称
public const int NET_SDK_EMPLOYEE_NO_LEN = 32; //工号长度
public const int VCA_MAX_POLYGON_POINT_NUM = 10;//检测区域最多支持10个点的多边形
public const int MAX_RULE_NUM = 8;//最多规则条数
public const int MAX_TARGET_NUM = 30;//最多目标个数
public const int MAX_CALIB_PT = 6;//最大标定点个数
public const int MIN_CALIB_PT = 4;//最小标定点个数
public const int MAX_TIMESEGMENT_2 = 2;//最大时间段数
public const int MAX_LICENSE_LEN = 16;//车牌号最大长度
public const int MAX_PLATE_NUM = 3;//车牌个数
public const int MAX_MASK_REGION_NUM = 4;//最多四个屏蔽区域
public const int MAX_SEGMENT_NUM = 6;//摄像机标定最大样本线数目
public const int MIN_SEGMENT_NUM = 3;//摄像机标定最小样本线数目
public const int MAX_CATEGORY_LEN = 8; //车牌附加信息最大字符
public const int SERIAL_NO_LEN = 16; //泊车位编号
//码流连接方式
public const int NORMALCONNECT = 1;
public const int MEDIACONNECT = 2;
//设备型号(大类)
public const int HCDVR = 1;
public const int MEDVR = 2;
public const int PCDVR = 3;
public const int HC_9000 = 4;
public const int HF_I = 5;
public const int PCNVR = 6;
public const int HC_76NVR = 8;
//NVR类型
public const int DS8000HC_NVR = 0;
public const int DS9000HC_NVR = 1;
public const int DS8000ME_NVR = 2;
#region 录像库
public const int DATASTREAM_HEAD = 0; //数据头
public const int DATASTREAM_BITBLOCK = 1; //字节数据
public const int DATASTREAM_KEYFRAME = 2; //关键帧数据
public const int DATASTREAM_NORMALFRAME = 3; //非关键帧数据
public const int MESSAGEVALUE_DISKFULL = 0x01;
public const int MESSAGEVALUE_SWITCHDISK = 0x02;
public const int MESSAGEVALUE_CREATEFILE = 0x03;
public const int MESSAGEVALUE_DELETEFILE = 0x04;
public const int MESSAGEVALUE_SWITCHFILE = 0x05;
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct STOREINFO
{
public int iMaxChannels;
public int iDiskGroup;
public int iStreamType;
public bool bAnalyze;
public bool bCycWrite;
public uint uiFileSize;
public CALLBACKFUN_MESSAGE funCallback;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATEFILE_INFO
{
public int iHandle;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 128)]
public string strCameraid;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 128)]
public string strFileName;
public BLOCKTIME tFileCreateTime;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CLOSEFILE_INFO
{
public int iHandle;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 128)]
public string strCameraid;
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 128)]
public string strFileName;
public BLOCKTIME tFileSwitchTime;
}
public delegate int CALLBACKFUN_MESSAGE(int iMessageType, System.IntPtr pBuf, int iBufLen);
[DllImport("RecordDLL.dll")]
public static extern int Initialize(STOREINFO struStoreInfo);
[DllImport("RecordDLL.dll")]
public static extern int Release();
[DllImport("RecordDLL.dll")]
public static extern int OpenChannelRecord(string strCameraid, IntPtr pHead, uint dwHeadLength);
[DllImport("RecordDLL.dll")]
public static extern bool CloseChannelRecord(int iRecordHandle);
[DllImport("RecordDLL.dll")]
public static extern int GetData(int iHandle, int iDataType, IntPtr pBuf, uint uiSize);
#endregion
}
3、主程序中调用需要加入命名空间using NVRCsharpDemo;
三、常用接口函数,封装调用函数
摄像头的连接、显示、 控制等功能在CHCNetSDK类中都有,以下为常见功能接口的调用。这里是开辟了一个摄像头模块,可以单独放在一个类中,也可以放在使用摄像头的类中。
这些接口的调用是放在新建的函数中,而非直接使用SDK中的接口函数。下面的代码可直接使用,一些地方比如显示摄像头的控件名、文件存放的路径等可能需要修改。
这段代码是在WPF中使用的,在WinForm中也可使用,需微调。
#region 摄像机
#region 变量
private bool m_bInitSDK = false;
private bool m_bRecord = false;
private uint iLastErr = 0;
private Int32 m_lUserID = -1;
//实时数据返回值
private Int32 m_lRealHandle = -1;
private string str1;
private string str2;
private Int32 i = 0;
private Int32 m_lTree = 0;
private string str;
private long iSelIndex = 0;
private uint dwAChanTotalNum = 0;
private uint dwDChanTotalNum = 0;
private Int32 m_lPort = -1;
private IntPtr m_ptrRealHandle;
private int[] iIPDevID = new int[96];
private int[] iChannelNum = new int[96];
private CHCNetSDK.REALDATACALLBACK RealData = null;
public CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo;
public CHCNetSDK.NET_DVR_IPPARACFG_V40 m_struIpParaCfgV40;
public CHCNetSDK.NET_DVR_STREAM_MODE m_struStreamMode;
public CHCNetSDK.NET_DVR_IPCHANINFO m_struChanInfo;
public CHCNetSDK.NET_DVR_PU_STREAM_URL m_struStreamURL;
public CHCNetSDK.NET_DVR_IPCHANINFO_V40 m_struChanInfoV40;
private PlayCtrl.DECCBFUN m_fDisplayFun = null;
public delegate void MyDebugInfo(string str);
#endregion 变量
#region ip配置
public string DVRIPAddress1 = "172.16.0.53"; //设备IP地址或者域名
public Int16 DVRPortNumber1 = 8000;//设备服务端口号
public string DVRUserName1 = "admin";//设备登录用户名
public string DVRPassword1 = "******";//设备登录密码
public string DVRIPAddress2 = "172.16.0.50"; //设备IP地址或者域名
public Int16 DVRPortNumber2 = 8000;//设备服务端口号
public string DVRUserName2 = "admin";//设备登录用户名
public string DVRPassword2 = "******";//设备登录密码
public string DVRIPAddress3 = "172.16.0.52"; //设备IP地址或者域名
public Int16 DVRPortNumber3 = 8000;//设备服务端口号
public string DVRUserName3 = "admin";//设备登录用户名
public string DVRPassword3 = "******";//设备登录密码
#endregion ip配置
#region 报警信息
string InfoWarning = "";
public void DebugInfo(string str)
{
if (str.Length > 0)
{
str += "\n";
//TextBoxInfo.AppendText(str);
InfoWarning = InfoWarning + str + "\n";
}
}
#endregion 报警信息
#region 初始化相机
public int InitCamera() //配置信息
{
try
{
//读取配置文件
XDocument document = XDocument.Load("Parameter.xml");
XElement root = document.Root;
//相机ip
DVRIPAddress1 = root.Element("CameraIP1").Value.ToString();
//相机端口
DVRPortNumber1 = Convert.ToInt16(root.Element("CameraPort1").Value.ToString());
//相机用户登录名
DVRUserName1 = root.Element("CameraUser1").Value.ToString();
//相机用户登录密码
DVRPassword1 = root.Element("CameraPwd1").Value.ToString();
//相机ip
DVRIPAddress2 = root.Element("CameraIP2").Value.ToString();
//相机端口
DVRPortNumber2 = Convert.ToInt16(root.Element("CameraPort2").Value.ToString());
//相机用户登录名
DVRUserName2 = root.Element("CameraUser2").Value.ToString();
//相机用户登录密码
DVRPassword2 = root.Element("CameraPwd2").Value.ToString();
//相机ip
DVRIPAddress3 = root.Element("CameraIP3").Value.ToString();
//相机端口
DVRPortNumber3 = Convert.ToInt16(root.Element("CameraPort3").Value.ToString());
//相机用户登录名
DVRUserName3 = root.Element("CameraUser3").Value.ToString();
//相机用户登录密码
DVRPassword3 = root.Element("CameraPwd3").Value.ToString();
}
catch (Exception ex)
{
MessageBox.Show("用户登录信息错误!");
return -1;
}
return 0;
}
#endregion 初始化相机
#region 登录Login
public void Login(string ip, int port, string username, string password)
{
m_bInitSDK = CHCNetSDK.NET_DVR_Init();
if (m_bInitSDK == false)
{
MessageBox.Show("NET_DVR_Init error!");
return;
}
else
{
//保存SDK日志
CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\CameraSdkLog\\", true);
comboBoxView.SelectedIndex = 0;
for (int i = 0; i < 64; i++)
{
iIPDevID[i] = -1;
iChannelNum[i] = -1;
}
}
if (m_lUserID < 0)
{
//string DVRIPAddress = textBoxIP.Text; //设备IP地址或者域名
//Int16 DVRPortNumber = Int16.Parse(textBoxPort.Text);//设备服务端口号
//string DVRUserName = textBoxUserName.Text;//设备登录用户名
//string DVRPassword = textBoxPassword.Text;//设备登录密码
//登录设备 Login the device
m_lUserID = CHCNetSDK.NET_DVR_Login_V30(ip, port, username, password, ref DeviceInfo);
if (m_lUserID < 0)
{
iLastErr = CHCNetSDK.NET_DVR_GetLastError();
str = " NET_DVR_Login_V30 failed, error code= " + iLastErr; //登录失败,输出错误号
DebugInfo(str);
return;
}
else
{
//登录成功
DebugInfo(" NET_DVR_Login_V30 succ!");
//btnLogin.Text = "Logout"; //这里修改为show
MessageBox.Show("相机登录成功!");
dwAChanTotalNum = (uint)DeviceInfo.byChanNum;
dwDChanTotalNum = (uint)DeviceInfo.byIPChanNum + 256 * (uint)DeviceInfo.byHighDChanNum;
if (dwDChanTotalNum > 0)
{
InfoIPChannel();
}
else
{
for (i = 0; i < dwAChanTotalNum; i++)
{
ListAnalogChannel(i + 1, 1);
iChannelNum[i] = i + (int)DeviceInfo.byStartChan;
}
comboBoxView.SelectedItem = 1;
// MessageBox.Show("This device has no IP channel!");
}
}
}
else
{
//注销登录 Logout the device
if (m_lRealHandle >= 0)
{
DebugInfo(" Please stop live view firstly"); //登出前先停止预览
return;
}
if (!CHCNetSDK.NET_DVR_Logout(m_lUserID))
{
iLastErr = CHCNetSDK.NET_DVR_GetLastError();
str = " NET_DVR_Logout failed, error code= " + iLastErr;
DebugInfo(str);
return;
}
DebugInfo(" NET_DVR_Logout succ!");
//listViewIPChannel.Items.Clear();//清空通道列表
m_lUserID = -1;
//btnLogin.Text = "Login";
MessageBox.Show("Login"); //这里修改为show
}
return;
}
public void InfoIPChannel()
{
uint dwSize = (uint)Marshal.SizeOf(m_struIpParaCfgV40);
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(m_struIpParaCfgV40, ptrIpParaCfgV40, false);
uint dwReturn = 0;
int iGroupNo = 0;
if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
{
iLastErr = CHCNetSDK.NET_DVR_GetLastError();
str = " NET_DVR_GET_IPPARACFG_V40 failed, error code= " + iLastErr;
//获取IP资源配置信息失败,输出错误号 Failed to get configuration of IP channels and output the error code
DebugInfo(str);
}
else
{
DebugInfo(" NET_DVR_GET_IPPARACFG_V40 succ!");
m_struIpParaCfgV40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));
for (i = 0; i < dwAChanTotalNum; i++)
{
ListAnalogChannel(i + 1, m_struIpParaCfgV40.byAnalogChanEnable[i]);
iChannelNum[i] = i + (int)DeviceInfo.byStartChan;
}
byte byStreamType = 0;
uint iDChanNum = 64;
if (dwDChanTotalNum < 64)
{
iDChanNum = dwDChanTotalNum;
}
for (i = 0; i < iDChanNum; i++)
{
iChannelNum[i + dwAChanTotalNum] = i + (int)m_struIpParaCfgV40.dwStartDChan;
byStreamType = m_struIpParaCfgV40.struStreamMode[i].byGetStreamType;
dwSize = (uint)Marshal.SizeOf(m_struIpParaCfgV40.struStreamMode[i].uGetStream);
switch (byStreamType)
{
//目前NVR仅支持直接从设备取流 NVR supports only the mode: get stream from device directly
case 0:
IntPtr ptrChanInfo = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrChanInfo, false);
m_struChanInfo = (CHCNetSDK.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(CHCNetSDK.NET_DVR_IPCHANINFO));
//列出IP通道 List the IP channel
ListIPChannel(i + 1, m_struChanInfo.byEnable, m_struChanInfo.byIPID);
iIPDevID[i] = m_struChanInfo.byIPID + m_struChanInfo.byIPIDHigh * 256 - iGroupNo * 64 - 1;
Marshal.FreeHGlobal(ptrChanInfo);
break;
case 4:
IntPtr ptrStreamURL = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrStreamURL, false);
m_struStreamURL = (CHCNetSDK.NET_DVR_PU_STREAM_URL)Marshal.PtrToStructure(ptrStreamURL, typeof(CHCNetSDK.NET_DVR_PU_STREAM_URL));
//列出IP通道 List the IP channel
ListIPChannel(i + 1, m_struStreamURL.byEnable, m_struStreamURL.wIPID);
iIPDevID[i] = m_struStreamURL.wIPID - iGroupNo * 64 - 1;
Marshal.FreeHGlobal(ptrStreamURL);
break;
case 6:
IntPtr ptrChanInfoV40 = Marshal.AllocHGlobal((Int32)dwSize);
Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrChanInfoV40, false);
m_struChanInfoV40 = (CHCNetSDK.NET_DVR_IPCHANINFO_V40)Marshal.PtrToStructure(ptrChanInfoV40, typeof(CHCNetSDK.NET_DVR_IPCHANINFO_V40));
//列出IP通道 List the IP channel
ListIPChannel(i + 1, m_struChanInfoV40.byEnable, m_struChanInfoV40.wIPID);
iIPDevID[i] = m_struChanInfoV40.wIPID - iGroupNo * 64 - 1;
Marshal.FreeHGlobal(ptrChanInfoV40);
break;
default:
break;
}
}
}
Marshal.FreeHGlobal(ptrIpParaCfgV40);
}
public void ListIPChannel(Int32 iChanNo, byte byOnline, int byIPID)
{
str1 = String.Format("IPCamera {0}", iChanNo);
m_lTree++;
if (byIPID == 0)
{
str2 = "X"; //通道空闲,没有添加前端设备 the channel is idle
}
else
{
if (byOnline == 0)
{
str2 = "offline"; //通道不在线 the channel is off-line
}
else
str2 = "online"; //通道在线 The channel is on-line
}
//listViewIPChannel.Items.Add(new ListViewItem(new string[] { str1, str2 }));//将通道添加到列表中 add the channel to the list
}
public void ListAnalogChannel(Int32 iChanNo, byte byEnable)
{
str1 = String.Format("Camera {0}", iChanNo);
m_lTree++;
if (byEnable == 0)
{
str2 = "Disabled"; //通道已被禁用 This channel has been disabled
}
else
{
str2 = "Enabled"; //通道处于启用状态 This channel has been enabled
}
//listViewIPChannel.Items.Add(new ListViewItem(new string[] { str1, str2 }));//将通道添加到列表中 add the channel to the list
}
#endregion 登录Login
#region 打开预览摄像机
public int StartPreview(System.Windows.Forms.PictureBox pictureShow)
{
if (m_lUserID < 0)
{
MessageBox.Show("Please login the device firstly!");
return -1;
}
if (m_bRecord)
{
MessageBox.Show("Please stop recording firstly!");
return -1;
}
if (m_lRealHandle < 0)
{
CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
//lpPreviewInfo.hPlayWnd = RealPlayWnd.Handle;//预览窗口 live view window
lpPreviewInfo.hPlayWnd = pictureShow.Handle;//预览窗口 live view window //---------------------换成当前的picturebox
lpPreviewInfo.lChannel = iChannelNum[(int)iSelIndex];//预览的设备通道 the device channel number
lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推
lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流
lpPreviewInfo.dwDisplayBufNum = 15; //播放库显示缓冲区最大帧数
IntPtr pUser = IntPtr.Zero;//用户数据 user data
if (comboBoxView.SelectedIndex == 0)
{
//打开预览 Start live view
m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);
}
else
{
lpPreviewInfo.hPlayWnd = IntPtr.Zero;//预览窗口 live view window
//m_ptrRealHandle = RealPlayWnd.Handle;
m_ptrRealHandle = pictureShow.Handle;//---------------------换成当前的picturebox
RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数 real-time stream callback function
m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, RealData, pUser);
}
if (m_lRealHandle < 0)
{
iLastErr = CHCNetSDK.NET_DVR_GetLastError();
str = " NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号 failed to start live view, and output the error code.
DebugInfo(str);
return -1;
}
else
{
//预览成功
DebugInfo(" NET_DVR_RealPlay_V40 succ!");
//btnPreview.Text = "Stop View";
MessageBox.Show("Stop View");
return 0;
}
}
else
{
//停止预览 Stop live view
if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle))
{
iLastErr = CHCNetSDK.NET_DVR_GetLastError();
str = " NET_DVR_StopRealPlay failed, error code= " + iLastErr;
DebugInfo(str);
return -1;
}
if ((comboBoxView.SelectedIndex == 1) && (m_lPort >= 0))
{
if (!PlayCtrl.PlayM4_Stop(m_lPort))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = " PlayM4_Stop failed, error code= " + iLastErr;
DebugInfo(str);
}
if (!PlayCtrl.PlayM4_CloseStream(m_lPort))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = " PlayM4_CloseStream failed, error code= " + iLastErr;
DebugInfo(str);
}
if (!PlayCtrl.PlayM4_FreePort(m_lPort))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = " PlayM4_FreePort failed, error code= " + iLastErr;
DebugInfo(str);
}
m_lPort = -1;
}
DebugInfo(" NET_DVR_StopRealPlay succ!");
m_lRealHandle = -1;
//btnPreview.Text = "Live View";
MessageBox.Show("Live View");
//RealPlayWnd.Invalidate();//刷新窗口 refresh the window
pictureShow.Invalidate(); //---------------------换成当前的picturebox
}
return 0;
}
#endregion 打开预览摄像机
#region 停止预览摄像机
public void StopPreview()
{
//停止预览
if (m_lRealHandle >= 0)
{
CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle);
m_lRealHandle = -1;
}
}
#endregion 停止预览摄像机
#region 退出登录
public void ExitLogin()
{
//注销登录
if (m_lUserID >= 0)
{
CHCNetSDK.NET_DVR_Logout(m_lUserID);
m_lUserID = -1;
}
CHCNetSDK.NET_DVR_Cleanup();
}
#endregion 退出登录
#region 回调函数
/// <summary>
/// 解码回调函数
/// </summary>
/// <param name="nPort"></param>
/// <param name="pBuf"></param>
/// <param name="nSize"></param>
/// <param name="pFrameInfo"></param>
/// <param name="nReserved1"></param>
/// <param name="nReserved2"></param>
private void DecCallbackFUN(int nPort, IntPtr pBuf, int nSize, ref PlayCtrl.FRAME_INFO pFrameInfo, int nReserved1, int nReserved2)
{
// 将pBuf解码后视频输入写入文件中(解码后YUV数据量极大,尤其是高清码流,不建议在回调函数中处理)
if (pFrameInfo.nType == 3) //#define T_YV12 3
{
// FileStream fs = null;
// BinaryWriter bw = null;
// try
// {
// fs = new FileStream("DecodedVideo.yuv", FileMode.Append);
// bw = new BinaryWriter(fs);
// byte[] byteBuf = new byte[nSize];
// Marshal.Copy(pBuf, byteBuf, 0, nSize);
// bw.Write(byteBuf);
// bw.Flush();
// }
// catch (System.Exception ex)
// {
// MessageBox.Show(ex.ToString());
// }
// finally
// {
// bw.Close();
// fs.Close();
// }
}
}
/// <summary>
/// 预览实时流回调函数
/// </summary>
/// <param name="lRealHandle"></param>
/// <param name="dwDataType"></param>
/// <param name="pBuffer"></param>
/// <param name="dwBufSize"></param>
/// <param name="pUser"></param>
public void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser)
{
//下面数据处理建议使用委托的方式
MyDebugInfo AlarmInfo = new MyDebugInfo(DebugInfo);
switch (dwDataType)
{
case CHCNetSDK.NET_DVR_SYSHEAD: // sys head
if (dwBufSize > 0)
{
if (m_lPort >= 0)
{
return; //同一路码流不需要多次调用开流接口
}
//获取播放句柄 Get the port to play
if (!PlayCtrl.PlayM4_GetPort(ref m_lPort))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_GetPort failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str); //--------------- 改成Dispatcher.BeginInvoke
this.Dispatcher.BeginInvoke(AlarmInfo, str);
break;
}
//设置流播放模式 Set the stream mode: real-time stream mode
if (!PlayCtrl.PlayM4_SetStreamOpenMode(m_lPort, PlayCtrl.STREAME_REALTIME))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "Set STREAME_REALTIME mode failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
this.Dispatcher.BeginInvoke(AlarmInfo, str); //-------------改成Dispatcher.BeginInvoke
}
//打开码流,送入头数据 Open stream
if (!PlayCtrl.PlayM4_OpenStream(m_lPort, pBuffer, dwBufSize, 2 * 1024 * 1024))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_OpenStream failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
this.Dispatcher.BeginInvoke(AlarmInfo, str); //---------- 改成Dispatcher.BeginInvoke
break;
}
//设置显示缓冲区个数 Set the display buffer number
if (!PlayCtrl.PlayM4_SetDisplayBuf(m_lPort, 15))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_SetDisplayBuf failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
this.Dispatcher.BeginInvoke(AlarmInfo, str); //----------- 改成Dispatcher.BeginInvoke
}
//设置显示模式 Set the display mode
if (!PlayCtrl.PlayM4_SetOverlayMode(m_lPort, 0, 0/* COLORREF(0)*/)) //play off screen
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_SetOverlayMode failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
this.Dispatcher.BeginInvoke(AlarmInfo, str); //------------ 改成Dispatcher.BeginInvoke
}
//设置解码回调函数,获取解码后音视频原始数据 Set callback function of decoded data
m_fDisplayFun = new PlayCtrl.DECCBFUN(DecCallbackFUN);
if (!PlayCtrl.PlayM4_SetDecCallBackEx(m_lPort, m_fDisplayFun, IntPtr.Zero, 0))
{
//this.BeginInvoke(AlarmInfo, "PlayM4_SetDisplayCallBack fail");
this.Dispatcher.BeginInvoke(AlarmInfo, "PlayM4_SetDisplayCallBack fail");//------------- 改成Dispatcher.BeginInvoke
}
//开始解码 Start to play
if (!PlayCtrl.PlayM4_Play(m_lPort, m_ptrRealHandle))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_Play failed, error code= " + iLastErr;
//this.BeginInvoke(AlarmInfo, str);
this.Dispatcher.BeginInvoke(AlarmInfo, str); //--------- 改成Dispatcher.BeginInvoke
break;
}
}
break;
case CHCNetSDK.NET_DVR_STREAMDATA: // video stream data
if (dwBufSize > 0 && m_lPort != -1)
{
for (int i = 0; i < 999; i++)
{
//送入码流数据进行解码 Input the stream data to decode
if (!PlayCtrl.PlayM4_InputData(m_lPort, pBuffer, dwBufSize))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_InputData failed, error code= " + iLastErr;
Thread.Sleep(2);
}
else
{
break;
}
}
}
break;
default:
if (dwBufSize > 0 && m_lPort != -1)
{
//送入其他数据 Input the other data
for (int i = 0; i < 999; i++)
{
if (!PlayCtrl.PlayM4_InputData(m_lPort, pBuffer, dwBufSize))
{
iLastErr = PlayCtrl.PlayM4_GetLastError(m_lPort);
str = "PlayM4_InputData failed, error code= " + iLastErr;
Thread.Sleep(2);
}
else
{
break;
}
}
}
break;
}
}
#endregion 回调函数
#region 控制视频方向
//海康云台控制:(需要先启动视频预览)
///***BOOL NET_DVR_PTZControl(
///***LONG lRealHandle, [in] NET_DVR_RealPlay或NET_DVR_RealPlay_V30的返回值
///***DWORD dwPTZCommand, [in] 云台控制命令,见下表:上下左右等,调焦光圈
///***DWORD dwStop [in] 云台停止动作或开始动作:0-开始,1-停止
///***);
//上按钮
public bool TopMouseDown()
{
//MessageBox.Show("云台上仰开始");
bool a = CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.TILT_UP, 0); //云台上仰开始
return a;
}
public bool TopMouseUp()
{
//MessageBox.Show("云台上仰停止");
bool b=CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.TILT_UP, 1); //云台上仰停止
return b;
}
//下按钮
public bool BottomMouseDown()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.TILT_DOWN, 0);//云台下俯开始
}
public bool BottomMouseUp()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.TILT_DOWN, 1);//云台下俯停止
}
//左按钮
public bool LeftMouseDown()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.PAN_LEFT, 0);//云台左转开始
}
public bool LeftMouseUp()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.PAN_LEFT, 1);//云台左转停止
}
//右按钮
public bool RightMouseDown()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.PAN_RIGHT, 0);//云台右转开始
}
public bool RightMouseUp()
{
return CHCNetSDK.NET_DVR_PTZControl(m_lRealHandle, CHCNetSDK.PAN_RIGHT, 1);//云台右转停止
}
#endregion 控制视频方向
private void btnStartCameraMin_Click(object sender, RoutedEventArgs e)
{
if (txtStartStopMin.Text == "暂停")
{
//MainWindow.camera.OpenCamera(pnlCamera);
BitmapImage img1 = new BitmapImage(new Uri("pack://application:,,,/Resource/资源0001.png"));
//pnlCameraMax.Load("E:/Resource/资源0001.png");
BitmapImage img = new BitmapImage(new Uri("pack://application:,,,/Resource/资源 99.png"));
imgStartStopMin.Source = img;
txtStartStopMin.Text = "播放";
//暂停三个摄像机
StopPreview();
//开启当前最大化界面
MessageBox.Show("暂停当前选中的视频!"); //视频的播放和暂停如何实现
}
else if (txtStartStopMin.Text == "播放")
{
// MainWindow.camera.CloseCamera();
BitmapImage img = new BitmapImage(new Uri("pack://application:,,,/Resource/资源 102.png"));
imgStartStopMin.Source = img;
txtStartStopMin.Text = "暂停";
//开启三个摄像头
StartPreview(pnlCameraMinC1);
StartPreview(pnlCameraMinC2);
StartPreview(pnlCameraMinC3);
//关闭当前最大化界面
MessageBox.Show("播放当前选中的视频!");
}
}
#endregion 摄像机