第一次使用华为的网络摄像头并进行二次开发,网上关于QT对华为网络摄像头的二次开发的文章很少,基于项目的需求做了一些工作,特此记录。
1、实时预览
2、手动控制录制视频
3、监听告警信号
4、实时获取元数据中的划定区域内的人数
摄像头型号如下:
在购买摄像头后,应当在官网下载对应的开发资料,如果需要权限,则联系华为的技术支持人员。下载资料如下:
SDC Development Kit Demo 8.0.T9 SDK DEMO下载地址:https://bbs.huaweicloud.com/forum/thread-76061-1-1.html
SDC Development Kit 8.0.RC3 下载地址:https://bbs.huaweicloud.com/forum/thread-76255-1-1.html
智能摄像机SDK相关FAQ集:https://bbs.huaweicloud.com/forum/thread-28015-1-1.html?mobile=2Q57
在sdk目录下有对应的开发指南,根据开发指南进行环境搭建、流程搭建、函数查找等
/*********************告警回调函数,此处用于监听人数超限告警***********************/
long CALLBACK fGetAlarmInfoCallBack(LPPU_ALARM_REPORT_S pstAlarmReport , void *pUsrData)
{
PU_ITGT_CROWD_DENSITY_DETECT_PARAM_S *crowdDensityWarning;
//选择人群密度告警
switch(pstAlarmReport-> enAlarmType)
{
case PU_ALARM_TYPE_CROWD_DENSITY_DETECT:
//crowdDensityWarning = qobject_cast<PU_ITGT_CROWD_DENSITY_DETECT_PARAM_S *>(pUsrData);
break;
default:
break;
}
printf("Device Id:%d\tAlarm type:%d\ttime:%s-%s-%s % s:%s:%s\tAlarm happen:%d\n", pstAlarmReport->ulDeviceId, pstAlarmReport-> enAlarmType,
pstAlarmReport->stTime.szYear, pstAlarmReport->stTime.szMonth, pstAlarmReport->stTime.szDay, pstAlarmReport->stTime.szHour,
pstAlarmReport->stTime.szMinute, pstAlarmReport->stTime.szSecond, pstAlarmReport->enAction);
return 0;
}
/*****************回调函数,此处用于获取元数据中划定区域的人数*********************/
void CALLBACK fRealDataCallBack(CHAR *szBuffer, LONG lSize, VOID *pUsrData)
{
BOOL bRet = PU_FALSE;
//第二层元数据TYPE : TARGET //目标(车、人、人脸等)
PU_META_DATA *pstMetaTargetData = NULL;
bRet = IVS_User_GetMetaData(szBuffer,lSize,TARGET, &pstMetaTargetData);
if ((PU_TRUE == bRet) && (NULL != pstMetaTargetData))
{
procMetaData(pstMetaTargetData);
IVS_User_FreeMetaData(&pstMetaTargetData);
}
return;
}
//初始化SDK
void camerawidget::InitSDK()
{
bool isInit = IVS_PU_Init(3 , NULL , 5050);
if(!isInit)
{
long RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1,错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
return;
}
}
//注册设备
void camerawidget::DeviceLogin()
{
QString m_IP = "192.168.0.14";
ULONG strPort = 6060;
QString strUser = "admin";
QString strPwd = "HuaWei123";
m_lUserID = IVS_PU_Login(m_IP.toLatin1().data() , strPort , strUser.toLatin1().data() , strPwd.toLatin1().data());
if(PU_FALSE == m_lUserID)
{
long RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1,错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
return;
}
//设置断网重连
if(PU_FALSE == IVS_PU_SetAutoReconnect(1))
{
long RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1,错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
return;
}
}
/********************Part1: 实时获取区域人数****************/
void camerawidget::startPreview_callbackPeoploNum()
{
PU_REAL_PLAY_INFO_S stRealPlayInfo = {0};
stRealPlayInfo.ulChannelId = 101; //通道号
stRealPlayInfo.bKeepLive = TRUE; //是否报活
stRealPlayInfo.enStreamType = PU_VIDEO_MAIN_STREAM; //码流类型
stRealPlayInfo.enVideoType = PU_VIDEO_TYPE_META; //流类型
stRealPlayInfo.enProtocolType = PU_PROTOCOL_TYPE_TCP; //传输协议类型
stRealPlayInfo.enMediaCallbackType = PU_MEDIA_CALLBACK_TYPE_META_FRAME;
stRealPlayInfo.enMediaCryptoType = PU_MEDIA_CRYPTO_NONE; //不加密
stRealPlayInfo.szReserved[22] = 1;
stRealPlayInfo.hPlayWnd = NULL;
m_ReculVideoPlayhandle = IVS_PU_RealPlay(m_lUserID, &stRealPlayInfo, fRealDataCallBack , NULL);
if(PU_FALSE == m_ReculVideoPlayhandle)
{
ULONG RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1 , 错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
//如果错误,则定时重连
callbackPeoploNumConnectFlag = false;
return;
}
else
{
callbackPeoploNumConnectFlag = true;
}
//告警
/* if(PU_FALSE == IVS_PU_AlarmInfoStatesCallBack(m_lUserID, fGetAlarmInfoCallBack , NULL))
{
long RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1,错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
return;
}*/
}
/*********************Part2 :录像部分*********************/
void camerawidget::startPreview_saveRealData() //预览,并用于录像
{
PU_REAL_PLAY_INFO_S stRealPlayInfo = {0};
stRealPlayInfo.ulChannelId = 101; //通道号
stRealPlayInfo.bKeepLive = TRUE; //是否报活
stRealPlayInfo.enStreamType = PU_VIDEO_MAIN_STREAM; //码流类型
stRealPlayInfo.enVideoType = PU_VIDEO_TYPE_VIDEO; //流类型
stRealPlayInfo.enProtocolType = PU_PROTOCOL_TYPE_TCP; //传输协议类型
stRealPlayInfo.enMediaCallbackType = PU_MEDIA_CALLBACK_TYPE_RTP;
stRealPlayInfo.enMediaCryptoType = PU_MEDIA_CRYPTO_NONE; //不加密
stRealPlayInfo.hPlayWnd = (HWND)ui->label->winId();
if(NULL == stRealPlayInfo.hPlayWnd)
{
QMessageBox::about(NULL , "提示" , "获取句柄失败");
return;
}
m_recordingPreviewHandle = IVS_PU_RealPlay(m_lUserID, &stRealPlayInfo, NULL , NULL);
if(PU_FALSE == m_recordingPreviewHandle)
{
ULONG RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "提示" , QString("错误码是%1 , 错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
saveRealDataConnectFlag = false;
return;
}
else
{
saveRealDataConnectFlag = true;
}
}
//开始保存录像数据
void camerawidget::startSaveRealData(QString path)
{
//保存实况数据
PU_SAVE_REALDATA_INFO_S saveRealDataInfo = {0};
//memset(saveRealDataInfo, 0, sizeof(LPPU_SAVE_REALDATA_INFO_S));
saveRealDataInfo.enSaveType = PU_SAVE_REALDATA_TYPE_TIME;
strcpy(saveRealDataInfo.szFilePath , path.toLatin1().data());
saveRealDataInfo.ulSaveSize = 1440; //最大大小,才能正常播放(时间单位:分钟,大小单位:Mb),此处设置为一天
if(PU_FALSE == IVS_PU_SaveRealData(m_lUserID , m_recordingPreviewHandle, &saveRealDataInfo))
{
ULONG RetErro=IVS_PU_GetLastError();
QMessageBox::about(NULL , "开始录像" , QString("错误码是%1 , 错误信息是%2").arg(RetErro).arg(IVS_PU_GetErrorMsg(RetErro)));
return;
}
}
1、windows下64位sdk加载有问题,请参考:
2、网页登录摄像头与通过SDK登录摄像头的密码是独立的;SDK固定的账户名和密码:admin/HuaWei123,固定端口是6060
3、视频显示和码流回调不能同时进行,需两次调用接口即可
4、录像时,开始录像函数与停止录像函数必须成对使用,否则视频会无法渲染