通过大华客流去获取客流数据
第一步初始化登录
package cn.microvideo.jiangning.sdk.module;
import cn.microvideo.jiangning.sdk.lib.NetSDKLib;
import cn.microvideo.jiangning.sdk.lib.ToolKits;
import lombok.extern.slf4j.Slf4j;
/**
* 登陆接口实现
* 主要有 :初始化、登陆、登出功能
*/
@Slf4j
public class LoginModule {
public static NetSDKLib netsdk = NetSDKLib.NETSDK_INSTANCE;
// 设备信息
public static NetSDKLib.NET_DEVICEINFO_Ex m_stDeviceInfo = new NetSDKLib.NET_DEVICEINFO_Ex();
// 登陆句柄
public static NetSDKLib.LLong m_hLoginHandle = new NetSDKLib.LLong(0);
private static boolean bInit = false;
private static boolean bLogopen = false;
/**
* \if ENGLISH_LANG
* Init
* \else
* 初始化
* \endif
*/
public static boolean init(NetSDKLib.fDisConnect disConnect, NetSDKLib.fHaveReConnect haveReConnect) {
bInit = netsdk.CLIENT_Init(disConnect, null);
if(!bInit) {
log.error("初始化失败");
return false;
}
// 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作
// 此操作为可选操作,但建议用户进行设置
netsdk.CLIENT_SetAutoReconnect(haveReConnect, null);
//设置登录超时时间和尝试次数,可选
int waitTime = 5000; //登录请求响应超时时间设置为5S
int tryTimes = 1; //登录时尝试建立链接1次
netsdk.CLIENT_SetConnectTime(waitTime, tryTimes);
// 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime
// 接口设置的登录设备超时时间和尝试次数意义相同,可选
NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM();
netParam.nConnectTime = 10000; // 登录时尝试建立链接的超时时间
netParam.nGetConnInfoTime = 3000; // 设置子连接的超时时间
netParam.nGetDevInfoTime = 3000;//获取设备信息超时时间,为0默认1000ms
netsdk.CLIENT_SetNetworkParam(netParam);
log.info("初始化成功");
return true;
}
/**
* \if ENGLISH_LANG
* CleanUp
* \else
* 清除环境
* \endif
*/
public static void cleanup() {
if(bLogopen) {
netsdk.CLIENT_LogClose();
}
if(bInit) {
netsdk.CLIENT_Cleanup();
}
}
/**
* \if ENGLISH_LANG
* Login Device
* \else
* 登录设备
* \endif
*/
public static boolean login(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) {
//IntByReference nError = new IntByReference(0);
//入参
NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam=new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
pstInParam.nPort=m_nPort;
pstInParam.szIP=m_strIp.getBytes();
pstInParam.szPassword=m_strPassword.getBytes();
pstInParam.szUserName=m_strUser.getBytes();
//出参
NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam=new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
pstOutParam.stuDeviceInfo=m_stDeviceInfo;
//m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError);
m_hLoginHandle=netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
if(m_hLoginHandle.longValue() == 0) {
System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint());
} else {
log.info("Login Success");
System.out.println("Login Success [ " + m_strIp + " ]");
}
return m_hLoginHandle.longValue() == 0? false:true;
}
/**
* \if ENGLISH_LANG
* Logout Device
* \else
* 登出设备
* \endif
*/
public static boolean logout() {
if(m_hLoginHandle.longValue() == 0) {
return false;
}
boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle);
if(bRet) {
m_hLoginHandle.setValue(0);
}
return bRet;
}
}
第二步登录摄像头
package cn.microvideo.jiangning.sdk.service;
import cn.microvideo.jiangning.sdk.entity.ConfigBean;
import cn.microvideo.jiangning.sdk.lib.NetSDKLib;
import cn.microvideo.jiangning.sdk.module.LoginModule;
import cn.microvideo.jiangning.sdk.task.PassengerFlowTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class LoginService {
//登录状态
private static boolean loginStatus = false;
private static final int PORT = 37777;
public static NetSDKLib.LLong lLong;
public void login(ConfigBean bean) {
//判断订阅
if (lLong != null) {
LoginModule.netsdk.CLIENT_DetachVideoStatSummary(lLong);
lLong = null;
}
//判断登录
if (loginStatus) {
LoginModule.logout();
}
try {
//如果登录失败,会在函数里面报错,项目停止,所以不做错误处理
loginStatus = LoginModule.login(bean.getIp(), PORT, bean.getUser(), bean.getPwd());
if (loginStatus) {
log.info("设备登录成功");
} else {
log.error("设备登录失败");
}
NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
inParam.nChannel = 0;
inParam.cbVideoStatSum = PassengerFlowTask.humanNumberStatisticCB;
//出参
NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
//订阅客流量事件
lLong = LoginModule.netsdk.CLIENT_AttachVideoStatSummary(LoginModule.m_hLoginHandle, inParam, outParam, 5000);
} catch (Exception e) {
log.error("客流监控关闭:{}", e.getMessage(), e);
}
}
}
第三步,构造订阅客流数据
package cn.microvideo.jiangning.sdk.module;
import cn.microvideo.jiangning.sdk.lib.NetSDKLib;
import cn.microvideo.jiangning.sdk.lib.ToolKits;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @author : 47040
* @since : Created in 2020/7/25 17:59
*/
public class VideoStateSummaryModule {
public static Map<Integer, NetSDKLib.LLong> getM_hAttachMap() {
return m_hAttachMap;
}
// handle map
private static Map<Integer, NetSDKLib.LLong> m_hAttachMap = new HashMap<Integer, NetSDKLib.LLong>();
// Attach 订阅 人数统计事件
public static boolean attachVideoStatSummary(int channel, NetSDKLib.fVideoStatSumCallBack fVideoStatSumCallBack) {
if (!m_hAttachMap.containsKey(channel)) {
NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
inParam.nChannel = channel;
inParam.cbVideoStatSum = fVideoStatSumCallBack;
NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
NetSDKLib.LLong m_hAttachHandle = LoginModule.netsdk.CLIENT_AttachVideoStatSummary(LoginModule.m_hLoginHandle, inParam, outParam, 5000);
if (m_hAttachHandle.longValue() == 0) {
System.err.printf("Attach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
return false;
}
m_hAttachMap.put(channel, m_hAttachHandle);
System.out.printf("Attach Succeed at Channel %d ! AttachHandle: %d. Wait Device Notify Information\n", channel, m_hAttachHandle.longValue());
return true;
} else { // 非 0 说明正在订阅,先退订,再返回订阅失败
System.err.print("Attach Handle is not Zero, Please Detach First.\n");
return false;
}
}
// Check if Channel is Attached 是否订阅通道
public static boolean channelAttached(int channel) {
return m_hAttachMap.containsKey(channel);
}
// Detach 退订 人数统计事件
public static boolean detachVideoStatSummary(int channel) {
if (m_hAttachMap.containsKey(channel)) {
NetSDKLib.LLong m_hAttachHandle = m_hAttachMap.get(channel);
if (m_hAttachHandle.longValue() != 0) {
if (!LoginModule.netsdk.CLIENT_DetachVideoStatSummary(m_hAttachHandle)) {
System.err.printf("Detach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
return false;
}
System.out.println("Channel " + channel + ". Handle: " + m_hAttachHandle.longValue() + ". Detach Succeed!");
m_hAttachHandle.setValue(0);
m_hAttachMap.remove(channel);
return true;
} else {
System.err.print("Attach Handle is Zero, no Need for Detach.\n");
return false;
}
} else {
System.err.print("Attach Handle not found.\n");
return false;
}
}
// Detach All 退订 人数统计事件
public static void detachAllVideoStatSummary() {
Set<Integer> keySet = m_hAttachMap.keySet();
for (Iterator<Integer> iter = keySet.iterator(); iter.hasNext(); ) {
int channel = iter.next();
NetSDKLib.LLong m_hAttachHandle = m_hAttachMap.get(channel);
if (!LoginModule.netsdk.CLIENT_DetachVideoStatSummary(m_hAttachHandle)) {
System.err.printf("Detach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
}
System.out.println("Channel " + channel + ". Handle: " + m_hAttachHandle.longValue() + ". Detach Succeed!");
iter.remove();
}
}
// reAttach 重订 人数统计事件
public static void reAttachAllVideoStatSummary(NetSDKLib.fVideoStatSumCallBack fVideoStatSumCallBack) {
Set<Integer> keySet = m_hAttachMap.keySet();
for (int channel : keySet) {
NetSDKLib.LLong m_hAttachHandle = m_hAttachMap.get(channel);
if (!LoginModule.netsdk.CLIENT_DetachVideoStatSummary(m_hAttachHandle)) {
System.err.printf("Detach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
}
System.out.println("Channel " + channel + ". Handle: " + m_hAttachHandle.longValue() + ". Detach Succeed!");
NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM inParam = new NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
inParam.nChannel = channel;
inParam.cbVideoStatSum = fVideoStatSumCallBack;
NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM outParam = new NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
m_hAttachHandle = LoginModule.netsdk.CLIENT_AttachVideoStatSummary(LoginModule.m_hLoginHandle, inParam, outParam, 5000);
if (m_hAttachHandle.longValue() == 0) {
System.err.printf("Attach Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
}
m_hAttachMap.put(channel, m_hAttachHandle);
System.out.printf("Attach Succeed at Channel %d ! AttachHandle: %d. Wait Device Notify Information\n", channel, m_hAttachHandle.longValue());
}
}
// clear OSD info
public static boolean clearVideoStateSummary(int channel) {
NetSDKLib.NET_CTRL_CLEAR_SECTION_STAT_INFO info = new NetSDKLib.NET_CTRL_CLEAR_SECTION_STAT_INFO();
info.nChannel = channel;
info.write();
if (!LoginModule.netsdk.CLIENT_ControlDevice(LoginModule.m_hLoginHandle, NetSDKLib.CtrlType.CTRLTYPE_CTRL_CLEAR_SECTION_STAT, info.getPointer(), 5000)) {
System.err.printf("Clear Video State Summary Failed!LastError = %s\n", ToolKits.getErrorCodePrint());
return false;
}
System.out.println("Clear Video State Summary Succeed!");
return true;
}
}
第四步 订阅函数回调
package cn.microvideo.jiangning.sdk.util;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.microvideo.jiangning.sdk.common.EventTaskCommonQueue;
import cn.microvideo.jiangning.sdk.dao.IpPassengerValue;
import cn.microvideo.jiangning.sdk.entity.ConfigBean;
import cn.microvideo.jiangning.sdk.lib.NetSDKLib;
import cn.microvideo.jiangning.sdk.task.PassengerFlowTask;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/**
* @ProjectName: person
* @Package: cn.microvideo.jiangning.sdk.util
* @ClassName: FHumanNumberStatisticCallBack
* @Author: xijing
* @Description: 人数统计回调
* @Date: 2021/10/29 14:11
* @Version: 1.0
*/
@Slf4j
public class FHumanNumberStatisticCallBack implements NetSDKLib.fVideoStatSumCallBack {
@Resource
private PassengerFlowTask passengerFlowTask;
private static FHumanNumberStatisticCallBack instance = new FHumanNumberStatisticCallBack();
public static FHumanNumberStatisticCallBack getInstance() {
return instance;
}
private EventTaskCommonQueue eventTaskQueue = new EventTaskCommonQueue();
public FHumanNumberStatisticCallBack() {
eventTaskQueue.init();
}
public void invoke(NetSDKLib.LLong lAttachHandle, NetSDKLib.NET_VIDEOSTAT_SUMMARY stVideoState, int dwBufLen, Pointer dwUser) {
//String dateTime = DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:00:00");
ConfigBean parameter = passengerFlowTask.parameter();
log.info("ip:{}", parameter.getIp());
log.info("ChannelID:{}",stVideoState.nChannelID);
log.info("CreasteTime:{}",stVideoState.stuTime.toStringTime());
log.info("People in information:{},hour:{},today:{}",stVideoState.stuEnteredSubtotal.nToday, stVideoState.stuEnteredSubtotal.nHour, stVideoState.stuEnteredSubtotal.nTotal);
log.info("People out information:{},hour:{},today:{}",stVideoState.stuExitedSubtotal.nToday, stVideoState.stuExitedSubtotal.nHour, stVideoState.stuExitedSubtotal.nTotal);
DateTime parse = DateUtil.parse(stVideoState.stuTime.toStringTime());
String dateTime = DateUtil.format(parse, "yyyy-MM-dd HH:00:00");
Map<String,Object> valueMap = new HashMap<>();
valueMap.put("enteredToday",stVideoState.stuEnteredSubtotal.nToday);
valueMap.put("enteredHour",stVideoState.stuEnteredSubtotal.nHour);
valueMap.put("exitedToday",stVideoState.stuExitedSubtotal.nToday);
valueMap.put("exitedHour",stVideoState.stuExitedSubtotal.nHour);
valueMap.put("ip",parameter.getIp());
valueMap.put("roadId",parameter.getRoadId());
valueMap.put("createTime", dateTime);
valueMap.put("district", parameter.getDistrict());
valueMap.put("saId", parameter.getSaId());
//推送到返回数据的静态数据
IpPassengerValue.IP_VALUE.put(parameter.getIp().concat("-").concat(dateTime),valueMap);
}
}
第五步 编写定时任务获取数据
package cn.microvideo.jiangning.sdk.task;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.microvideo.jiangning.sdk.dao.IpPassengerValue;
import cn.microvideo.jiangning.sdk.entity.ConfigBean;
import cn.microvideo.jiangning.sdk.module.LoginModule;
import cn.microvideo.jiangning.sdk.service.LoginService;
import cn.microvideo.jiangning.sdk.util.DisConnectCallBack;
import cn.microvideo.jiangning.sdk.util.FHumanNumberStatisticCallBack;
import cn.microvideo.jiangning.sdk.util.HaveReConnectCallBack;
import cn.microvideo.jiangning.sdk.util.HttpUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
/**
* @ProjectName: person
* @Package: cn.microvideo.isa.vehicledata.clean.task
* @ClassName: PassengerFlowTask
* @Author: xijing
* @Description: 客流量统计
* @Date: 2021/10/26 15:07
* @Version: 1.0
*/
@Component
@Slf4j
public class PassengerFlowTask {
@Resource
private LoginService loginService;
// 设备断线通知回调
private static DisConnectCallBack disConnectCB = new DisConnectCallBack();
// 人数统计回调事件
public static FHumanNumberStatisticCallBack humanNumberStatisticCB = FHumanNumberStatisticCallBack.getInstance();
// 网络连接恢复
private static HaveReConnectCallBack haveReConnectCB = new HaveReConnectCallBack();
@Value("${sendPassengerUrl}")
public String sendUrl;
@Value("${sdkIp}")
public String ip;
@Value("${sdkUser}")
private String user;
@Value("${sdkPwd}")
private String pwd;
@Value("${roadId}")
private String roadId;
@Value("${saId}")
private String saId;
@Value("${district}")
private String district;
@PostConstruct
public void init() {
log.info("初始化SDK开始");
//初始化SDK
boolean init = LoginModule.init(disConnectCB, haveReConnectCB);
if (init) {
log.info("初始化SDK成功");
ConfigBean parameter = parameter();
//启动客流监控
log.info("首次启动客流监控");
loginService.login(parameter);
log.info("客流监控启动成功");
}else {
log.error("初始化SDK失败");
}
}
public ConfigBean parameter() {
ConfigBean bean = new ConfigBean();
bean.setIp(ip);
bean.setUser(user);
bean.setPwd(pwd);
bean.setRoadId(roadId);
bean.setSaId(saId);
bean.setDistrict(district);
return bean;
}
/**
* 重启客流监控
*/
@Scheduled(cron = "* * 0/1 * * ? ")
public void tsak() {
log.info("重启客流监控开始");
ConfigBean parameter = parameter();
//启动客流监控
loginService.login(parameter);
log.info("重启客流监控结束");
}
//推送数据
@Scheduled(cron = "0 2/5 * * * ? ")
public void sendTask() throws IOException {
log.info("新项目部署");
Map<String, Map<String, Object>> stringMapMap = IpPassengerValue.IP_VALUE;
for (Map<String, Object> value : stringMapMap.values()) {
log.info("发送到服务器数据:{}", value);
String result = HttpUtils.sendPost(sendUrl, JSON.toJSONString(value));
log.info("服务器返回数据:{}", result);
}
stringMapMap.clear();
}
public static void main(String[] args) {
System.out.println(DateUtil.between(DateUtil.endOfHour(DateUtil.date()), DateUtil.date(), DateUnit.MS));
}
}