Linux C++海康SDK取流
下载海康Linux开发SDK
-
进入 海康开放平台 , 点击 设备集成SDK ,点击 资源下载 。
-
下载Linux x64的SDK
设置环境变量
- 把SDK的库放进Linux里解压
- 把库文件文件夹和子文件夹HCNetSDKCom里的所有文件拷贝在 ~/hkSdk/lib 目录下
- 往 ~/.bashrc 添加如下:
# hk sdk
export LD_LIBRARY_PATH=$HOME/lib/hkSdk/lib:$LD_LIBRARY_PATH
- 使得环境变量生效
source ~/.bashrc
C++使用海康SDK取流
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
using namespace std;
#include "HCNetSDK.h"
#include "LinuxPlayM4.h"
int g_nPort = -1;
void Get_HK_SDK_Version()
{
unsigned int uiVersion = NET_DVR_GetSDKBuildVersion();
char strTemp[1024] = {0};
sprintf(strTemp, "HCNetSDK V%d.%d.%d.%d\n", \
(0xff000000 & uiVersion)>>24, \
(0x00ff0000 & uiVersion)>>16, \
(0x0000ff00 & uiVersion)>>8, \
(0x000000ff & uiVersion));
printf(strTemp);
}
// 视频流解码成功后的回调函数
void CALLBACK DecodeCallBackFun(int nPort, char* pBuf, int nSize, FRAME_INFO* pFrameInfo, void* nUser, int nReserved)
{
if (pFrameInfo->nType == T_YV12) {
printf("Get Decode Stream ok.\n");
// TODO, 自行处理解码后的 YV12 数据
}
}
void CALLBACK g_HikDataCallBack(int lRealHandle, unsigned int dwDataType, unsigned char *pBuffer, unsigned int dwBufSize, void *dwUser)
{
//printf("pyd---(private)Get data,the size is %d.\n", dwBufSize);
unsigned int ret;
switch (dwDataType) {
case NET_DVR_SYSHEAD:
if(!PlayM4_GetPort(&g_nPort)) {
printf("pyd---PlayM4_GetPort error, %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
exit(0); // TODO 自行处理, 重新登录等操作
break;
}
if(dwBufSize > 0) {
// 打开流
if(!PlayM4_OpenStream(g_nPort, pBuffer, dwBufSize, 1024*1024)) {
ret = PlayM4_GetLastError(g_nPort);
printf("PlayM4_OpenStream failed: %d\n", ret);
break;
}
// 设置视频流解码成功后的回调函数, 封装成类时, 可把 PlayM4_SetDecCallBackExMend 第四个参数 为 this 指针
if(!PlayM4_SetDecCallBackExMend(g_nPort, DecodeCallBackFun, NULL, 0, 0)) {
ret = PlayM4_GetLastError(g_nPort);
printf("PlayM4_SetDecCallBackExMend failed: %d\n", ret);
break;
}
// 打开视频解码
if(!PlayM4_Play(g_nPort, NULL)) {
//todo
ret = PlayM4_GetLastError(g_nPort);
printf("PlayM4_Play failed: %d\n", ret);
break;
}
// 播放声音
if (!PlayM4_PlaySound(g_nPort)) {
}
}
break;
case NET_DVR_STREAMDATA:
if(dwBufSize > 0 && g_nPort != -1) {
bool in_data = PlayM4_InputData(g_nPort, pBuffer, dwBufSize);
while (!in_data) {
in_data = PlayM4_InputData(g_nPort, pBuffer, dwBufSize);
sleep(1);
}
}
break;
default:
break;
}
}
void CALLBACK ExceptionCallBackFun(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
switch(dwType) {
case EXCEPTION_RECONNECT: //预览时重连
printf("----------reconnect--------%d\n", time(NULL));
break;
default:
break;
}
}
int main()
{
BOOL iRet = NET_DVR_Init();
if (!iRet) {
printf("Alarm! NET_DVR_Init fail!\n");
printf("NET_DVR_GetLastError is %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
Get_HK_SDK_Version();
//设置连接时间与重连时间
iRet = NET_DVR_SetConnectTime(2000, 1);
if (!iRet) {
printf("NET_DVR_SetConnectTime failed: %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
iRet = NET_DVR_SetReconnect(10000, true);
if (!iRet) {
printf("NET_DVR_SetReconnect failed: %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
// 设置日志
iRet = NET_DVR_SetLogToFile(3, "./sdkLog");
if (!iRet) {
printf("NET_DVR_SetReconnect failed: %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
//设置异常消息回调函数
iRet = NET_DVR_SetExceptionCallBack_V30(0, NULL, ExceptionCallBackFun, NULL);
if (!iRet) {
printf("NET_DVR_SetReconnect failed: %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
// 登录设备
NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};
struLoginInfo.bUseAsynLogin = false;
struLoginInfo.wPort = 8000;
memcpy(struLoginInfo.sDeviceAddress, "xxx.xxx.xxx.xxx", NET_DVR_DEV_ADDRESS_MAX_LEN);
memcpy(struLoginInfo.sUserName, "admin", NAME_LEN);
memcpy(struLoginInfo.sPassword, "123456", NAME_LEN);
int lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
if (lUserID < 0) {
printf("pyd---Login error, %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return false;
}
// 启动预览 设置参数
NET_DVR_PREVIEWINFO struct_play_info = {0};
struct_play_info.hPlayWnd = 0; // SDK解码时播放窗口的句柄,仅取流不解码时可设为空
struct_play_info.lChannel = 1; // 通道号
struct_play_info.dwLinkMode = 0; // 0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
struct_play_info.bBlocked = 1; // 0-非阻塞取流, 1-阻塞取流, 如果阻塞SDK内部connect失败将会有5s的超时才能够返回,不适合于轮询取流操作.
struct_play_info.dwDisplayBufNum = 1;
long lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struct_play_info, NULL, NULL);
if(lRealPlayHandle < 0) {
printf("pyd---NET_DVR_RealPlay_V40 error, %d\n", NET_DVR_GetLastError());
NET_DVR_Logout_V30(lUserID);
NET_DVR_Cleanup();
return false;
}
// 设置回调函数取流, 封装成类时, 可把 NET_DVR_SetRealDataCallBackEx 第三个参数 为 this 指针
iRet = NET_DVR_SetRealDataCallBackEx(lRealPlayHandle, g_HikDataCallBack, 0);
if (!iRet) {
printf("pyd---NET_DVR_SetRealDataCallBackEx error, %d\n", NET_DVR_GetLastError());
NET_DVR_StopRealPlay(lRealPlayHandle);
NET_DVR_Logout_V30(lUserID);
NET_DVR_Cleanup();
return false;
}
getchar();
return 1;
}
错误处理
海康SDK和TensorRT库一起使用导致 NET_DVR_Init 失败
注释(不要使用) TensorRT 库的函数 initLibNvInferPlugins
报错 29
环境变量没设置,先参考上文设置号环境变量
其他报错
请参考海康SDK下的开发文档自行解决
参考
【1】: 海康开发平台