如何使用海康SDK实现异步登录网络摄像机(IPC)【源码】【监控】【录播】【NVR】

前言:

    在上一篇博客:《如何利用UDP组播实现海康网络摄像机(IPC)的自动探测功能》,我们已经通过源码实现了ONVIF协议的网络摄像机自动探测功能,获取到了IPC的IP地址和服务端口。

    要想进一步的操作IPC,就需要登录到IPC当中,海康IPC的登录有两种模式:同步和异步,同步比较简单,直接调用API就可以了,缺点是需要阻塞界面,用户体验不好;异步,无需阻塞界面,登录状态通过回调函数告知,相对比较麻烦一些,今天,我们就通过源码示例来详细介绍有关异步登录的使用方法。

    在开始写代码之前,我们先要下载好一份海康SDK,里面有详细的开发文档和丰富的示例程序;

    下载地址 => http://www.hikvision.com/cn/download_61.html

    我们示例代码使用的是 设备网络SDK_Win32,版本为 V5.2.5.25

源码下载:

    CSDN: https://download.csdn.net/download/haoyitech/10288543

源码说明:

    开发工具:下载后,请用 VS2010 打开。

    基本原理:先初始化海康SDK,准备好登录IPC需要的IP地址、服务端口、登录用户名、登录密码,调用异步登录接口,设置好回调函数;无论登录成功与否,回调函数都会以异步的方式返回,我们可以在异步回调函数当中验证和判断是否登录成功;由于异步回调函数仍然处于SDK里面的线程当中,我们为了避免阻塞SDK线程,在判断已经成功登录之后,向主窗口发起异步消息通知,在异步消息通知当中再进行实际的IPC操作,具体的操作示例,请详见:《如何使用海康SDK实现网络摄像机(IPC)自动配置》

    总体思路:就是要将异步操作分散开,尽量不要在异步登录回调函数中进行IPC操作,要将具体操作交给主窗口主线程。

    特别注意:在程序退出释放资源时,没有直接退出,因为,有可能还处在异步登录的等待回调过程中,必须等待异步回调返回之后才能退出,否则,会引起程序崩溃。详见 Csample_hk_loginDlg::WaitForExit()

    海康SDK里面有很多的相关动态库,我们进行了部分筛选,只留下我们需要的,文件结构说明:

编译结果存放位置    => sample_hk_login\bin
海康SDK核心库       => sample_hk_login\bin\HCCore.dll
海康SDK网络库       => sample_hk_login\bin\HCNetSDK.dll
海康SDK播放D3D库    => sample_hk_login\bin\D3DX9_43.dll
海康SDK播放控件库   => sample_hk_login\bin\PlayCtrl.dll
海康SDK音频渲染库   => sample_hk_login\bin\AudioRender.dll
海康SDK播放辅助库   => sample_hk_login\bin\SuperRender.dll
海康SDK画面预览库   => sample_hk_login\bin\HCNetSDKCom\HCPreview.dll
海康SDK设备配置库   => sample_hk_login\bin\HCNetSDKCom\HCCoreDevCfg.dll
海康SDK通用配置库   => sample_hk_login\bin\HCNetSDKCom\HCGeneralCfgMgr.dll
浩一科技代码辅助库  => sample_hk_login\common

关键代码:(详见 Csample_hk_loginDlg)

1、初始化过程:
BOOL Csample_hk_loginDlg::OnInitDialog()
{
      .........................
	// 初始化海康SDK资源...
	NET_DVR_Init();

	// 初始化网络、线程、套接字...
	WORD	wsVersion = MAKEWORD(2, 2);
	WSADATA	wsData	  = {0};
	(void)::WSAStartup(wsVersion, &wsData);
      .........................
}
2、发起异步登录:
// 点击“异步登录”按钮...
void Csample_hk_loginDlg::OnBnClickedButtonAsync()
{
	if( m_HKLoginID > 0 ) {
		TRACE("=== 当前已经处于登录状态 ===\n");
		return;
	}
	ASSERT( m_HKLoginID <= 0 );
	CString strAddress("192.168.1.65");
	CString strUser("admin");
	CString strPass("admin123");
	int nCmdPort = 8000;
	DWORD dwErr = this->doDeviceLogin(strAddress, nCmdPort, strUser, strPass);
}
// 执行DVR登录操作...
DWORD Csample_hk_loginDlg::doDeviceLogin(LPCTSTR lpIPAddr, int nCmdPort, 
                                         LPCTSTR lpUser, LPCTSTR lpPass)
{	// 将摄像机的错误标志复位...
	m_dwHKErrCode = NET_DVR_NOERROR;
	// 登录之前,先释放资源,保存通知窗口...
	DWORD dwErr = GM_NoErr;
	this->ClearResource();
	// 异步方式登录DVR设备...
	NET_DVR_DEVICEINFO_V40  dvrDevV40 = {0};
	NET_DVR_USER_LOGIN_INFO dvrLoginInfo = {0};
	dvrLoginInfo.cbLoginResult = Csample_hk_loginDlg::DeviceLoginResult;
	strcpy(dvrLoginInfo.sDeviceAddress, lpIPAddr);
	strcpy(dvrLoginInfo.sUserName, lpUser);
	strcpy(dvrLoginInfo.sPassword, lpPass);
	dvrLoginInfo.bUseAsynLogin = 1;
	dvrLoginInfo.wPort = nCmdPort;
	dvrLoginInfo.pUser = this;
	// 调用异步接口函数...
	if( NET_DVR_Login_V40(&dvrLoginInfo, &dvrDevV40) < 0 ) {
		dwErr = NET_DVR_GetLastError();
		MsgLogGM(dwErr);
	}
	// 设置正在异步登录中标志...
	m_HKLoginIng = true;
	// 如果调用失败,清除所有资源...
	if( dwErr != GM_NoErr ) {
		TRACE("=== 登录失败,错误号:%lu ===\n", dwErr);
		this->ClearResource();
		return dwErr;
	}
	// 打印正在登录状态...
	TRACE("=== 正在异步登录... ===\n");
	return GM_NoErr;
}
3、等待异步反馈:
// 登录回调函数接口...
void CALLBACK Csample_hk_loginDlg::DeviceLoginResult(LONG lUserID, DWORD dwResult,
                              LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo, void * pUser)
{	Csample_hk_loginDlg * lpDlg = (Csample_hk_loginDlg*)pUser;
	lpDlg->onDeviceLoginAsync(lUserID, dwResult, lpDeviceInfo);
}
// 设备异常回调函数接口...
void CALLBACK Csample_hk_loginDlg::DeviceException(DWORD dwType, LONG lUserID,
                                                  LONG lHandle, void * pUser)
{
	Csample_hk_loginDlg * lpDlg = (Csample_hk_loginDlg*)pUser;
	lpDlg->onDeviceException(dwType, lUserID, lHandle);
}
//
// 处理设备异常的实际函数...
void Csample_hk_loginDlg::onDeviceException(DWORD dwType, LONG lUserID, LONG lHandle)
{
	TRACE("=== Device Exception 0x%x ===\n", dwType);
}
4、判断登录结果,再次发起异步通知:
// 实际处理登录回调的函数...
void Csample_hk_loginDlg::onDeviceLoginAsync(LONG lUserID, DWORD dwResult,
                             LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo)
{	// 正在登录状态复位...
	m_HKLoginIng = false;
	// 处在退出状态中,直接返回...
	if( m_bIsExiting ) {
		TRACE("=== onDeviceLoginAsync => Exit ===\n");
		return;
	}
	// 登录失败的处理过程,需要通知上层窗口...
	if( dwResult <= 0 || lUserID < 0 ) {
		m_dwHKErrCode = NET_DVR_GetLastError();
		TRACE("=== 登录失败(%lu),错误:%s ===\n", m_dwHKErrCode, NET_DVR_GetErrorMsg(&m_dwHKErrCode));
		// 释放该通道上的资源数据...
		this->ClearResource();
		MsgLogGM(m_dwHKErrCode);
		return;
	}
	// 登录成功之后,保存数据...
	m_dwHKErrCode = NET_DVR_NOERROR;
	this->m_HKLoginID = lUserID;
	memcpy(&m_HKDeviceInfo, lpDeviceInfo, sizeof(NET_DVR_DEVICEINFO_V30));
	// 通过异步消息,离开登录线程...
	::PostMessage(this->m_hWnd, WM_DEVICE_LOGIN_SUCCESS, NULL, NULL);
}
5、在异步通知中操作IPC:
// 处理异步登录成功的消息通知...
LRESULT Csample_hk_loginDlg::OnDeviceLoginSuccess(WPARAM wParam, LPARAM lParam)
{
	// 打印异步登录成功消息...
	TRACE("=== 异步登录成功... ===\n");
	return S_OK;
}
6、退出登录:
// 点击“立即注销”按钮...
void Csample_hk_loginDlg::OnBnClickedButtonLogout()
{
	this->ClearResource();
}

// 释放建立资源...
void Csample_hk_loginDlg::ClearResource()
{
	// 释放登录资源...
	if( m_HKLoginID >= 0 ) {
		NET_DVR_Logout_V30(m_HKLoginID);
		m_HKLoginID = -1;
		memset(&m_HKDeviceInfo, 0, sizeof(m_HKDeviceInfo));
	}
}
7、释放资源:
Csample_hk_loginDlg::~Csample_hk_loginDlg()
{
	// 释放海康SDK资源...
	NET_DVR_Cleanup();
	// 阻塞等待退出...
	this->WaitForExit();
	// 注销登录...
	this->ClearResource();
}
// 等待异步登录退出 => 使用互斥不起作用...
void Csample_hk_loginDlg::WaitForExit()
{
	m_bIsExiting = true;
	while( m_HKLoginIng ) {
		::Sleep(5);
	}
	ASSERT( !m_HKLoginIng );
}

注意:在程序退出释放资源时,没有直接退出,因为,有可能还处在异步登录的等待回调过程中,必须等待异步回调返回之后才能退出,否则,会引起程序崩溃。

更多信息:

************************************************************
 * 浩一科技,提供云监控、云录播的全平台无插件解决方案。
 * 支持按需直播,多点布控,分布式海量存储,动态扩容;
 * 支持微信扫码登录,全平台帐号统一,关联微信小程序;
 * 支持多种数据输入:摄像头IPC、rtmp、rtsp、MP4文件;
 * 支持全实时、全动态、全网页管理,网页前后台兼容IE8;
 * 支持多终端无插件自适应播放,flvjs/hls/rtmp自动适配;
************************************************************
 * 官方网站 => https://myhaoyi.com
 * 技术博客 => http://blog.csdn.net/haoyitech
 * 开源代码 => https://github.com/HaoYiTech/
************************************************************

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值