公司的项目里使用到海康威视的摄像监控设备,而后项目要求在咱们的B/S系统中集成摄像头的播放画面。所以经过和海康威视工做人员的沟通,和网上一些人的文章,实现了在本身的网页里进行预览和回放。html
海康威视的视频监控设备有网络摄像头、网络硬盘录像机(NVR)等。这些设备都自带一个小系统,能够经过在浏览器上输入设备的IP进行监控画面的查看和设备信息的修改。前端
如图所示。web
其实海康的网络摄像头自带的功能仍是挺多的,可是就是当对不少网络摄像头进行批量管理的时候有些不方便,并且不符合项目要求所以仍是得按照本身的需求本身来开发。数据库
NVR最主要的功能是经过网络接收IPC(网络摄像机)设备传输的数字视频码流, 并进行存储、管理,从而实现网络化带来的分布式架构优点。 简单来讲,经过Nvr,能够同时观看、浏览、回放、管理、存储多个网络摄像机。摆脱了电脑硬件的牵绊,不再用面临安装软件的繁琐。若是全部摄像机网络化,那么必经之路就是有一个集中管理核心出现。http://http://www.elecfans.com/baike/yuyinshipin/anfangjiankong/20180102609985.html后端
NVR具备16/32/64路通道,也就是最多支持64路视频音频信号的接入。咱们将摄像头经过网线和NVR的相连,就能够在NVR中经过添加设备的方式将该摄像头做为NVR的一个信号输入,该设备将会占用一个通道。至此咱们只要经过NVR就能够实现对该摄像头的监控画面预览了。网络摄像头输出的是模拟信号,NVR将摄像头的模拟信号转换为数字信号。api
此时经过浏览器输入NVR的IP进入NVR的系统,能够看到预览页和回放页都有设备列表,选中设备能够进行预览或者回放。在回放页面多了日历,有绿色标记的表示当天有视频信息的存储,能够进行播放。浏览器
为帮助客户实现定制化的监控视频实时预览功能的集成,海康威视提供了两种SDK分别用于C/S架构和B/S架构的开发。缓存
海康威视在官网【下载】->【SDK开发】里提供了用于C/S架构的SDK,我下载的是“设备网络SDK_Win64”。下载页上这样说到:安全
设备网络SDK是基于设备私有网络通讯协议开发的,为后端设备(嵌入式网络硬盘录像机、视频服务器)、前端设备(网络摄像机、网络球机、IP模块)等产品服务的配套模块,用于远程访问和控制设备软件的二次开发。服务器
在解压好的文件夹中,库文件存放的是海康封装好的库文件,这些被Import(外部引入)到项目中,是SDK运行的条件,若是没有引入这些文件那么Demo程序中的SDK文件将引起错误。详情请参考SDK中的《HCNetSDKCom文件夹必须加载到工程.txt》
包里有MFC、Java和C#的Demo。我用的是C#,这里就C#作一下介绍和总结。
一、是直接登陆摄像头进行直接预览。
二、登陆CVR、NVR,对此中的输入信号进行预览等
……
其余的功能就本身看一下代码吧,若是对属性或者做用不清晰的,能够对照开发文档和SDK使用手册,里面有说明。
SDK的基本使用方法是:
一、“CHCNetSDK.cs”。海康威视提供了一个静态类“CHCNetSDK.cs”,里面包含了针对各类设备的各类方法,以及各类适用于不一样方法的数据结构体和属性。
二、在Winform后台代码中的使用方法(部分代码,只供解读)
`
private uint iLastErr = 0; //错误代码 private Int32 m_lUserID = -1;//登陆句柄 private bool m_bInitSDK = false;//sdk初始化结果 private bool m_bRecord = false;//是否录像 private Int32 m_lRealHandle = -1;//预览句柄 m_bInitSDK = CHCNetSDK.NET_DVR_Init();// 1初始化 m_lUserID = CHCNetSDK.NET_DVR_Login_V30(DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DeviceInfo); // 2登陆设备 Login the device。登陆前如要先定义参数。 其中DeviceInfo为引用传递。这样在Login方法中就把设备的信息获取出来并赋值给了DeviceInfo,包含的信息参考NET_DVR_DEVICEINFO_V30结构体;若是登陆成功会返回一个大于零的值,不然返回-1。 if(m_lUserID < 0) //未登陆 { MessageBox.Show("Please login the device firstly"); return; } if (m_lRealHandle < 0) //初始为-1,表示未预览 { CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); lpPreviewInfo.hPlayWnd = RealPlayWnd.Handle;//预览窗口 lpPreviewInfo.lChannel = Int16.Parse(textBoxChannel.Text);//预te览的设备通道 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; //播放库播放缓冲区最大缓冲帧数 CHCNetSDK.REALDATACALLBACK RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数 IntPtr pUser = new IntPtr();//用户数据 //打开预览 Start live view m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser); if (m_lRealHandle < 0) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号 MessageBox.Show(str); return; } else { //预览成功 btnPreview.Text = "Stop Live View"; } } else { //中止预览 Stop live view if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_StopRealPlay failed, error code= " + iLastErr; MessageBox.Show(str); return; } m_lRealHandle = -1; btnPreview.Text = "Live View"; } return; }
`
代码中方法“NET_DVR_RealPlay_V40”是海康摄像头进行实时预览的方法,支持多码流播放。海康提供了这个方法调用,而咱们使用时只须要定义好播放参数就行,如在哪一个窗口播放
lpPreviewInfo.hPlayWnd = RealPlayWnd.Handle;//预览窗口 live view window
基本上就是上面的一个逻辑。挺简单的。可是针对不一样的设备可能方法有不一样,能够参照开发文档和SDK使用手册多搜索一下。好比,我在获取NVR的硬盘使用空间时就花了很长时间去找调用的方法。
//WorkStates是我本身定义的一个结构体,用来方便的获取我想要的结果。 WorkStates workStates = new WorkStates() { totalUsedSpace = 0, totalSpace = 0, HardDiskStatic = 0, AlarmOutStatic = 0, DeviceStatic = 0, iErrCode = 0, iLastErrStr = string.Empty }; var result = new CHCNetSDK.NET_DVR_WORKSTATE(); CHCNetSDK.NET_DVR_DISKSTATE[] struHardDiskStatic = new CHCNetSDK.NET_DVR_DISKSTATE[33]; if (!CHCNetSDK.NET_DVR_GetDVRWorkState(m_lUserID, ref result)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); workStates.iErrCode = iLastErr; workStates.iLastErrStr = FetchDescription((GlobalErrorCode)iLastErr); return workStates; }
C/S 架构SDk的使用主要用来作一下工做:
通过分析,上述两个需求要采用了后台服务的方式来实现。
可是海康的SDk适用于Winform控件,写WCF服务的时候,因为那些外部dll引用的缘由致使没法直接进行调用,所以咱们对海康控件进行了一次封装,生成了一个dll。咱们在dll中用一个用户winform控件来代替winform窗体,来调用海康的各类方法。而后再项目中,搭建了一个线程服务,同事引用这个dll并进行调用。实现了定时获取NVR的硬盘存储空间的功能。
public class NVRSpaceMonitorFactory { public static void Start() { try { List<NVR> nvrList = NVR.FindAllEnabled(); //这里NVR、Alarm都是项目中的一个EF实体, if (nvrList != null && nvrList.Count > 0) { UCHKVideo ucVideo = new UCHKVideo(); foreach (NVR nvr in nvrList) { int nvrid = nvr.ID; Alarm alarm = new Alarm() { DeviceID = nvr.ID, BusinessType = 8 }; UCHKVideo.LoginState loginResult = ucVideo.NVRLogin(nvr.IPAddress, nvr.ClientPort.ToString(), nvr.UserName, nvr.Password); if (loginResult.bInitSDK != -1) //插件登录失败 { UCHKVideo.WorkStates result = ucVideo.GetNVRWorkState(); ucVideo.LogOut(); if (result.iErrCode == 0) //result.totalSpace!=0表示获取成功 { NVRSpaceHistory nvrSpaceRecord = new NVRSpaceHistory(); nvrSpaceRecord.NVRID = nvrid; nvrSpaceRecord.UsedSpace = result.totalUsedSpace; nvrSpaceRecord.UpdateTime = DateTime.Now; nvrSpaceRecord.Insert(); // if (nvr.TotalSpace != result.totalSpace) { nvr.IsEnable = true; //不设定true 就会被false掉,暂时处理 nvr.UsedSpace = result.totalUsedSpace; nvr.TotalSpace = result.totalSpace; nvr.AlarmOutStatic = (int)result.AlarmOutStatic; nvr.DeviceStatic = (int)result.DeviceStatic; nvr.HardDiskStatic = (int)result.HardDiskStatic; nvr.Update(); //将信息写入数据库报警表中(来自系统的报警) IP、名称、报警信息 List<V_Alarm_Rule> alarmRuleList = V_Alarm_Rule.FindAllBySubSystemName("视频监控"); if (alarmRuleList != null && alarmRuleList.Count > 0) { foreach (V_Alarm_Rule ar in alarmRuleList) { double thresholdValue = 0; double.TryParse(ar.Value, out thresholdValue); if (!string.IsNullOrEmpty(ar.AlarmCondition) && thresholdValue != 0) { int compareResult = (nvr.UsedSpace / nvr.TotalSpace).CompareTo((decimal)thresholdValue); var comperaResultEnum = (CompareResult)compareResult; var comperaResultStr = UCHKVideo.FetchDescription(comperaResultEnum); if (ar.AlarmCondition.Contains(comperaResultStr)) { alarm.Content = "NVR硬盘存储空间已不足" + (thresholdValue * 100).ToString() + "%"; alarm.AlarmTime = DateTime.Now; alarm.Insert(); } } } } } } else { //若是获取失败,将信息写入数据库报警表中(来自系统的报警)IP、名称、报警信息 Log4netHelper.Error(nvr.Name + "_" + nvr.IPAddress + "_" + result.iLastErrStr); //测试 alarm.Content = result.iLastErrStr; alarm.AlarmTime = DateTime.Now; alarm.Insert(); } } else { //若是登录失败,将信息写入数据库报警表中(来自NVR的报警)IP、名称、报警信息 Log4netHelper.Error(nvr.Name+"_"+nvr.IPAddress+"_"+ loginResult.iLastErrStr); //测试 alarm.Content = loginResult.iLastErrStr; alarm.AlarmTime = DateTime.Now; alarm.Insert(); } } } } catch (Exception ex) { Log4netHelper.Error(ex.Message); } } }
关于后台的服务,我将在后面进行一个专门的总结,敬请期待。总之,海康的C#的SDK挺简单的。参照SDK和开发文档就能实现本身要的功能。容易有坑的地方是 一些方法的参数实例化。由于不知道参数如何设定,总会致使调用方法时出现异常,须要多了解跟这个方法相关的信息。
下面是一个使用MFC的实例。
海康威视网络摄像头SDK中Demo的二次开发(运行) - 土豪gold的博客 - CSDN博客https://blog.csdn.net/qq_15029743/article/details/79733960
浏览器实时预览摄像头画面的方法有好几种。
能够参考下面这篇博文吧(只是为了让文章显得完整 才加上)。
采集rtsp流摄像头到浏览器实时播放方案 - 书写人生 - CSDN博客
https://blog.csdn.net/yelin042/article/details/78134113/
咱们在项目中作的就是在WEB系统中集成海康威视的实时预览和回放,所以在经过对海康设备的一番度娘研究以后,发现海康有JS语言的SDK,通过咨询,海康威视的技术人员提供了这份SDK。
doc文件夹里放了SDK说明文档。建议先了解一下SDK的文档。
Demo里放的是实例。webVideoCtrl.js是海康威视的插件WebComponentsKit.exe控制硬件设备的API demo.js里面是封装了的方法,引入这个文件,就能够直接使用了。海康威视的API功能仍是挺全的,就是须要安装插件。安装了插件就意味着须要使用IE的浏览器(Trident内核)。这个很不爽。Chrome认为插件不安全,已经全面中止了插件的安装,所以没法使用Chrome浏览器预览实时画面。
海康摄像头经过登陆IP 就能够在Chrome上进行预览。我以为这应该是采用了视频流转换。但我还没研究这种方法。
整个api的调用顺序以下图所示。
var iRet = WebVideoCtrl.I_CheckPluginInstall();// 1 检查是否安装 // 二、初始化插件参数及插入插件。我在里面放入了一个返回结果,在调用的时候作一个判断 function clickInitPlugin(iWndowType, divPlugin) { var isSuccess = false; //用来返回的结果 WebVideoCtrl.I_InitPlugin("100%", "100%", { bWndFull: true, // 是否支持单窗口双击全屏,默认支持 true:支持 false:不支持 iPackageType: 2, // 2:PS 11:MP4 iWndowType: iWndowType, bNoPlugin: true, cbSelWnd: function (xmlDoc) { …… }, cbDoubleClickWnd: function (iWndIndex, bFullScreen) { …… }, cbEvent: function (iEventType, iParam1, iParam2) { …… }, cbRemoteConfig: function () { …… }, cbInitPluginComplete: function () { WebVideoCtrl.I_InsertOBJECTPlugin(divPlugin); // 检查插件是否最新 if (-1 == WebVideoCtrl.I_CheckPluginVersion()) { alert("检测到新的播放器版本,请安装最新的WebComponentsKit.exe升级!"); return isSuccess; } isSuccess = true; } }); return isSuccess; } ///三、登陆 var iRet = WebVideoCtrl.I_Login(szIP, 1, szPort, szUsername, szPassword, { success: function (xmlDoc) { showOPInfo(szDeviceIdentify + " 登陆成功!"); $("#ip").prepend("<option value='" + szDeviceIdentify + "'>" + szDeviceIdentify + "</option>"); setTimeout(function () { $("#ip").val(szDeviceIdentify); getChannelInfo();//获取通道 getDevicePort();//获取端口 }, 10); }, error: function (status, xmlDoc) { showOPInfo(szDeviceIdentify + " 登陆失败!", status, xmlDoc); } }); // 4 按IP、端口号预览 function clickStartRealPlay(szIP, szPort, iChannelID) { var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex), szDeviceIdentify = szIP, iRtspPort = szPort, bZeroChannel = false, szInfo = "", iStreamType = 1;// 主码流 if ("undefined" === typeof iStreamType) { iStreamType = parseInt($("#streamtype").val(), 10); } var startRealPlay = function () { WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iRtspPort: iRtspPort, iStreamType: iStreamType, iChannelID: iChannelID, bZeroChannel: bZeroChannel, success: function () { …… }, error: function (status, xmlDoc) { …… } }); }; if (oWndInfo != null) {// 已经在播放了,恢复;这个地方能够本身控制逻辑。若是正在播放就中止该播放窗口再播放。 WebVideoCtrl.I_Stop({ success: function () { startRealPlay(); } }); } else { startRealPlay(); } } }
其余的方法能够多看看说明文档和实例Demo。
我作的最终效果。能够实现预览和回放。回放的日历是仿造海康的系统写的,会默认查询最近一个月内是否有视频数据,若是有就标记绿色三角。
说几点js语言的sdk问题:
海康威视提供了查询已经链接的视频监控设备的应用程序。经过该应用程序,能够搜索到和主机电脑同一局域网络下的全部海康视频设备。
在页面中能够看到各个设备的型号和参数,其中关键参数有:IP,客户端端口号、HTTP端口号(用于浏览器使用的)。若是忘记了帐号和密码,能够经过输入右侧的管理员密码进行重置,也能够修改其余参数。帐号一般都是“Admin”。
选中设备后就能够点击右下角的【忘记密码】–>【官方公众号获取秘钥】–>【导入并重置】
1 keyi chongfu denglu 2 bixu xian denglu caineng yulanhuozhehuifang