海康威视SDK接口调用的主要流程及预览模块

海康威视SDK接口调用的主要流程及预览模块_第1张图片

其中虚线框的流程是可选部分,不会影响其他流程和模块的功能使用。

  • 初始化SDK(NET_DVR_Init):对整个网络SDK系统的初始化,内存预分配等操作。
  • 用户注册设备(NET_DVR_Login_V40):实现用户的注册功能,注册成功后,返回的用户ID作为其他功能操作的唯一标识,SDK允许最大注册个数为2048个。就设备而言,V3.0以上版本支持的设备允许有32个注册用户名,而且同时最多允许128个用户注册;V3.0以下版本支持的设备允许有16个注册用户名,而且同时最多允许128个用户注册。

预览录像抓图模块流程

海康威视SDK接口调用的主要流程及预览模块_第2张图片

图中虚线框部分的模块是与预览模块相关,必须在启动预览后才能调用,这些模块之间是并列的关系,各自完成相应的功能。实时预览支持TCP、UDP、MULTICAST网络传输模式,应用层协议支持私有协议和RTSP协议,码流类型可以选择主码流、子码流、第三码流等。

  • 预览实时流解码有两种方式:

方式一

预览接口NET_DVR_RealPlay_V40中预览参数的播放窗口句柄(hPlayWnd)赋值为有效句柄,则由SDK自动实现解码显示功能。在初始化SDK和注册设备两步骤后,直接调用启动预览和停止预览接口即可。正常开启预览之后可以调用NET_DVR_RigisterDrawFun注册画图回调函数(仅Windows版本支持),回调获取窗口DC,然后用户可以自己在窗口表层绘图或者写字。如果预览的码流是音视频复合流,也可以调用声音预览控制相关接口实现打开或者关闭声音、客户端音量控制等功能,相关接口有:NET_DVR_OpenSoundNET_DVR_CloseSoundNET_DVR_OpenSoundShareNET_DVR_CloseSoundShareNET_DVR_Volume等。

#include 
#include 
#include "Windows.h"
#include "HCNetSDK.h"
#include 
using namespace std;

typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
PROCGETCONSOLEWINDOW GetConsoleWindowAPI;

void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
    char tempbuf[256] = {0};
    switch(dwType) 
    {
    case EXCEPTION_RECONNECT:    //预览时重连
        printf("----------reconnect--------%d\n", time(NULL));
    break;
	default:
    break;
    }
}

void main() {

  //---------------------------------------
  // 初始化
  NET_DVR_Init();
  //设置连接时间与重连时间
  NET_DVR_SetConnectTime(2000, 1);
  NET_DVR_SetReconnect(10000, true);
  
  //---------------------------------------
  //设置异常消息回调函数
  NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);

  //---------------------------------------
  // 获取控制台窗口句柄
  HMODULE hKernel32 = GetModuleHandle("kernel32");
  GetConsoleWindowAPI = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");

  //---------------------------------------
  // 注册设备
  LONG lUserID;

  //登录参数,包括设备地址、登录用户、密码等
  NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
  struLoginInfo.bUseAsynLogin = 0; //同步登录方式
  strcpy(struLoginInfo.sDeviceAddress, "10.13.35.229"); //设备IP地址
  struLoginInfo.wPort = 8000; //设备服务端口
  strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
  strcpy(struLoginInfo.sPassword, "abcd1234"); //设备登录密码
  
  //设备信息, 输出参数
  NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};

  lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
  if (lUserID < 0)
  {
      printf("Login failed, error code: %d\n", NET_DVR_GetLastError());
      NET_DVR_Cleanup();
      return;
  }

  //---------------------------------------
  //启动预览并设置回调数据流
  LONG lRealPlayHandle;
  HWND hWnd = GetConsoleWindowAPI();     //获取窗口句柄
  NET_DVR_PREVIEWINFO struPlayInfo = {0};
  struPlayInfo.hPlayWnd = hWnd;         //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
  struPlayInfo.lChannel     = 1;       //预览通道号
  struPlayInfo.dwStreamType = 0;       //0-主码流,1-子码流,2-码流3,3-码流4,以此类推
  struPlayInfo.dwLinkMode   = 0;       //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
  struPlayInfo.bBlocked     = 1;       //0- 非阻塞取流,1- 阻塞取流

  lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, NULL, NULL);
  if (lRealPlayHandle < 0)
  {
      printf("NET_DVR_RealPlay_V40 error\n");
	  NET_DVR_Logout(lUserID);
      NET_DVR_Cleanup();
      return;
  }

  Sleep(10000);
  //---------------------------------------
  //关闭预览
  NET_DVR_StopRealPlay(lRealPlayHandle);
  //注销用户
  NET_DVR_Logout(lUserID);
  //释放SDK资源
  NET_DVR_Cleanup();

  return;
}


方式二

预览接口NET_DVR_RealPlay_V40中预览参数的播放窗口句柄(hPlayWnd)可以设置为空值,直接设置回调函数,或者调用预览接口之后,通过NET_DVR_SetRealDataCallBackNET_DVR_SetStandardDataCallBack设置回调函数,回调获取实时流数据(前两个接口设置的回调获取的是PS封装的码流,后者获取的是标准RTP封装的码流)之后用户后续自己处理,比如二进制流方式写入文件保存成录像或者调用播放库解码显示等操作。

#include 
#include 
#include "Windows.h"
#include "HCNetSDK.h"
#include "plaympeg4.h"
#include 
using namespace std;

typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
PROCGETCONSOLEWINDOW GetConsoleWindowAPI;

LONG lPort = -1; //全局的播放库port号

void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser)
{
    HWND hWnd=GetConsoleWindowAPI();

	switch (dwDataType)
	{
	case NET_DVR_SYSHEAD: //系统头
		if (lPort >= 0)
		{
			break;  //该通道取流之前已经获取到句柄,后续接口不需要再调用
		}

		if (!PlayM4_GetPort(&lPort))  //获取播放库未使用的通道号
		{
			break;
		}
		//m_iPort = lPort; //第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放
		if (dwBufSize > 0)
		{
			if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME))  //设置实时流播放模式
			{
				break;
			}

			if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024)) //打开流接口
			{
				break;
			}

			if (!PlayM4_Play(lPort, hWnd)) //播放开始
			{
				break;
			}
		}
        break; 
	case NET_DVR_STREAMDATA:   //码流数据
		if (dwBufSize > 0 && lPort != -1)
		{
			if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
			{
				break;
			} 
		}
        break; 
    default: //其他数据
        if (dwBufSize > 0 && lPort != -1)
		{
			if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
			{
				break;
			} 
		}
        break;      
	}
}

void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
    char tempbuf[256] = {0};
    switch(dwType) 
    {
    case EXCEPTION_RECONNECT:    //预览时重连
    printf("----------reconnect--------%d\n", time(NULL));
    break;
	default:
    break;
    }
}

void main() {

  //---------------------------------------
  // 初始化
  NET_DVR_Init();
  //设置连接时间与重连时间
  NET_DVR_SetConnectTime(2000, 1);
  NET_DVR_SetReconnect(10000, true);
 
  //---------------------------------------
  //设置异常消息回调函数
  NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);
   
  //---------------------------------------
  // 获取控制台窗口句柄
  HMODULE hKernel32 = GetModuleHandle("kernel32");
  GetConsoleWindowAPI = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");

  //---------------------------------------
  // 注册设备
  LONG lUserID;

  //登录参数,包括设备地址、登录用户、密码等
  NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
  struLoginInfo.bUseAsynLogin = 0; //同步登录方式
  strcpy(struLoginInfo.sDeviceAddress, "10.13.35.229"); //设备IP地址
  struLoginInfo.wPort = 8000; //设备服务端口
  strcpy(struLoginInfo.sUserName, "admin"); //设备登录用户名
  strcpy(struLoginInfo.sPassword, "abcd1234"); //设备登录密码
  
  //设备信息, 输出参数
  NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};

  lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
  if (lUserID < 0)
  {
      printf("Login failed, error code: %d\n", NET_DVR_GetLastError());
      NET_DVR_Cleanup();
      return;
  }

  //---------------------------------------
  //启动预览并设置回调数据流
  LONG lRealPlayHandle;

  NET_DVR_PREVIEWINFO struPlayInfo = {0};
  struPlayInfo.hPlayWnd     = NULL;         //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
  struPlayInfo.lChannel     = 1;       //预览通道号
  struPlayInfo.dwStreamType = 0;       //0-主码流,1-子码流,2-码流3,3-码流4,以此类推
  struPlayInfo.dwLinkMode   = 0;       //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
  struPlayInfo.bBlocked     = 1;       //0- 非阻塞取流,1- 阻塞取流

  lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);
  if (lRealPlayHandle < 0)
  {
      printf("NET_DVR_RealPlay_V40 error, %d\n", NET_DVR_GetLastError());
      NET_DVR_Logout(lUserID);
      NET_DVR_Cleanup();
      return;
  }

  Sleep(10000);
  //---------------------------------------
  //关闭预览
  NET_DVR_StopRealPlay(lRealPlayHandle);

  //释放播放库资源
  PlayM4_Stop(lPort);
  PlayM4_CloseStream(lPort);
  PlayM4_FreePort(lPort);

  //注销用户
  NET_DVR_Logout(lUserID);
  NET_DVR_Cleanup();

  return;
}

 

你可能感兴趣的:(海康威视SDK接口调用的主要流程及预览模块)