HCNetTools.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package com.sckj.camera.hik;
  2. import com.sun.jna.Pointer;
  3. import com.sun.jna.ptr.IntByReference;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import java.time.LocalDateTime;
  7. import java.time.format.DateTimeFormatter;
  8. import java.util.ArrayList;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. public class HCNetTools {
  12. private final Logger logger = LoggerFactory.getLogger(getClass());
  13. static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
  14. //海康播放库(SDK里的PlayCtrl不是此处的PlayCtrl)
  15. //static PlayCtrl playControl = PlayCtrl.INSTANCE;
  16. private HCNetSDK.NET_DVR_WORKSTATE_V30 m_strWorkState;
  17. private HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo;//设备信息
  18. private HCNetSDK.NET_DVR_IPPARACFG m_strIpparaCfg;//IP参数
  19. private HCNetSDK.NET_DVR_CLIENTINFO m_strClientInfo;//用户参数
  20. private boolean bRealPlay;//是否在预览.
  21. private String m_sDeviceIP;//已登录设备的IP地址
  22. private int lUserID;//用户句柄
  23. private int loadHandle;//下载句柄
  24. private int lPreviewHandle;//预览句柄
  25. private IntByReference m_lPort;//回调预览时播放库端口指针
  26. private IntByReference m_err;//错误号
  27. public HCNetTools() {
  28. lUserID = -1;
  29. lPreviewHandle = -1;
  30. m_lPort = new IntByReference(-1);
  31. m_err = new IntByReference(-1);
  32. }
  33. /**
  34. * 初始化资源配置
  35. */
  36. public int initDevices() {
  37. boolean b = hCNetSDK.NET_DVR_Init();
  38. if (!b) {
  39. //初始化失败
  40. //throw new RuntimeException("初始化失败");
  41. System.out.println("初始化失败");
  42. return 1;
  43. }
  44. return 0;
  45. }
  46. /**
  47. * 设备注册
  48. *
  49. * @param name 设备用户名
  50. * @param password 设备登录密码
  51. * @param ip IP地址
  52. * @param port 端口
  53. * @return 结果
  54. */
  55. public int deviceLogin(String ip, String port,String name, String password) {
  56. if (bRealPlay) {//判断当前是否在预览
  57. return 2;//"注册新用户请先停止当前预览";
  58. }
  59. if (lUserID > -1) {//先注销,在登录
  60. hCNetSDK.NET_DVR_Logout_V30(lUserID);
  61. lUserID = -1;
  62. }
  63. //注册(既登录设备)开始
  64. m_sDeviceIP = ip;
  65. short iPort = Integer.valueOf(port).shortValue();
  66. m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();//获取设备参数结构
  67. lUserID = hCNetSDK.NET_DVR_Login_V30(ip, iPort, name, password, m_strDeviceInfo);//登录设备
  68. long userID = lUserID;
  69. if (userID == -1) {
  70. int iErr = hCNetSDK.NET_DVR_GetLastError();
  71. System.out.println(":注册失败,错误号:" + iErr);
  72. System.out.println(hCNetSDK.NET_DVR_GetErrorMsg(m_err));
  73. m_sDeviceIP = "";//登录未成功,IP置为空
  74. return 3;//"注册失败";
  75. }
  76. return 0;
  77. }
  78. /**
  79. * 注销登陆
  80. */
  81. public void deviceLogout() {
  82. //如果在预览,先停止预览, 释放句柄
  83. if (lPreviewHandle > -1)
  84. {
  85. hCNetSDK.NET_DVR_StopRealPlay(lPreviewHandle);
  86. }
  87. //如果已经注册,注销
  88. if (lUserID> -1) {
  89. hCNetSDK.NET_DVR_Logout_V30(lUserID);
  90. }
  91. hCNetSDK.NET_DVR_Cleanup();
  92. }
  93. /**
  94. * 获取设备通道
  95. */
  96. public List<String> getChannelNumber() {
  97. List<String> channelList = new ArrayList<>();
  98. IntByReference ibrBytesReturned = new IntByReference(0);//获取IP接入配置参数
  99. boolean bRet = false;
  100. m_strIpparaCfg = new HCNetSDK.NET_DVR_IPPARACFG();
  101. m_strIpparaCfg.write();
  102. Pointer lpIpParaConfig = m_strIpparaCfg.getPointer();
  103. bRet = (m_strDeviceInfo.byIPChanNum != 0);
  104. String devices = "";
  105. if (!bRet) {
  106. //设备不支持,则表示没有IP通道
  107. for (int iChannum = 0; iChannum < m_strDeviceInfo.byChanNum; iChannum++) {
  108. devices = "Camera" + (iChannum + m_strDeviceInfo.byStartChan);
  109. channelList.add(devices);
  110. }
  111. } else {
  112. //设备支持IP通道
  113. boolean ok = hCNetSDK.NET_DVR_GetDVRConfig(lUserID, HCNetSDK.NET_DVR_GET_IPPARACFG, 0, lpIpParaConfig, m_strIpparaCfg.size(), ibrBytesReturned);
  114. if (!ok) {
  115. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  116. logger.info("获取配置失败:" + m_err.getValue() + "," + err);
  117. }
  118. m_strIpparaCfg.read();
  119. for (int iChannum = 0; iChannum < m_strDeviceInfo.byChanNum; iChannum++) {
  120. if(m_strIpparaCfg.byAnalogChanEnable[iChannum] == 1)
  121. {
  122. devices = "Camera" + (iChannum + m_strDeviceInfo.byStartChan);
  123. channelList.add(devices);
  124. }
  125. }
  126. for (int iChannum = 0; iChannum < HCNetSDK.MAX_IP_CHANNEL; iChannum++) {
  127. if (m_strIpparaCfg.struIPChanInfo[iChannum].byEnable == 1) {
  128. devices = "IP" + (hCNetSDK.NET_DVR_SDKChannelToISAPI(lUserID,iChannum + m_strDeviceInfo.byStartDChan,true));
  129. String channelIP = (new String(m_strIpparaCfg.struIPDevInfo[iChannum].struIP.sIpV4));
  130. channelIP = channelIP.trim();
  131. devices = devices + "," + channelIP;
  132. channelList.add(devices);
  133. }
  134. }
  135. }
  136. return channelList;
  137. }
  138. /**
  139. * 抓拍图片
  140. *
  141. * @param channel 通道号
  142. */
  143. public boolean getDVRPic(int channel, String path) {
  144. HCNetSDK.NET_DVR_WORKSTATE_V30 devwork = new HCNetSDK.NET_DVR_WORKSTATE_V30();
  145. if (!hCNetSDK.NET_DVR_GetDVRWorkState_V30(lUserID, devwork)) {
  146. // 返回Boolean值,判断是否获取设备能力
  147. logger.info("hksdk(抓图)-返回设备状态失败");
  148. }
  149. //图片质量
  150. HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
  151. //设置图片分辨率
  152. jpeg.wPicSize = 4;
  153. //设置图片质量
  154. jpeg.wPicQuality = 0;
  155. IntByReference a = new IntByReference();
  156. //需要加入通道
  157. //byte[] bytes = path.getBytes(StandardCharsets.UTF_8);
  158. boolean ok = hCNetSDK.NET_DVR_CaptureJPEGPicture(lUserID,channel,jpeg,path);
  159. if (ok) {
  160. logger.info("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
  161. } else {
  162. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  163. logger.info("hksdk(抓图)-抓取失败,错误码:" + m_err.getValue() + "," + err);
  164. }
  165. return ok;
  166. }
  167. /**
  168. * 下载录像
  169. * @return boolean
  170. */
  171. public boolean downloadBack(LocalDateTime startTime, LocalDateTime endTime, String filePath, int channel) throws InterruptedException {
  172. loadHandle = -1;
  173. loadHandle = hCNetSDK.NET_DVR_GetFileByTime(lUserID, channel, getHkTime(startTime), getHkTime(endTime), filePath);
  174. if (loadHandle >= 0) {
  175. //开始下载
  176. boolean downloadFlag = hCNetSDK.NET_DVR_PlayBackControl(loadHandle, HCNetSDK.NET_DVR_PLAYSTART, 0, null);
  177. int tmp = -1;
  178. IntByReference pos = new IntByReference(0);
  179. while (loadHandle >= 0) {
  180. boolean backFlag = hCNetSDK.NET_DVR_PlayBackControl(loadHandle, HCNetSDK.NET_DVR_PLAYGETPOS, 0, pos);
  181. if (!backFlag) {//防止单个线程死循环
  182. return downloadFlag;
  183. }
  184. int produce = pos.getValue();
  185. if ((produce % 10) == 0 && tmp != produce) {//输出进度
  186. tmp = produce;
  187. logger.info("视频下载进度:" + "==" + produce + "%");
  188. }
  189. if (produce == 100) {//下载成功
  190. hCNetSDK.NET_DVR_StopGetFile(loadHandle);
  191. loadHandle = -1;
  192. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  193. logger.info("下载结束,last error: " + m_err.getValue() + "," + err);
  194. return true;
  195. }
  196. if (produce > 100) {//下载失败
  197. hCNetSDK.NET_DVR_StopGetFile(loadHandle);
  198. loadHandle = -1;
  199. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  200. logger.warn("下载异常终止!错误原因:" + m_err.getValue() + "," + err);
  201. return false;
  202. }
  203. Thread.sleep(500);
  204. }
  205. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  206. logger.warn("下载异常终止!错误原因:" + m_err.getValue() + "," + err);
  207. return false;
  208. } else {
  209. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  210. logger.warn("获取录像文件错误!错误原因:" + m_err.getValue() + "," + err);
  211. return false;
  212. }
  213. }
  214. /**
  215. * 获取录像文件信息
  216. * @Return:
  217. */
  218. public List<HashMap<String, String>> getVideoFileList(LocalDateTime startTime, LocalDateTime endTime, int channel) {
  219. List<HashMap<String, String>> fileList = new ArrayList<>();
  220. // 搜索条件
  221. HCNetSDK.NET_DVR_FILECOND m_strFilecond = new HCNetSDK.NET_DVR_FILECOND();
  222. m_strFilecond.struStartTime = getHkTime(startTime);
  223. m_strFilecond.struStopTime = getHkTime(endTime);
  224. m_strFilecond.lChannel = channel;//通道号
  225. int lFindFile = hCNetSDK.NET_DVR_FindFile_V30(lUserID, m_strFilecond);
  226. HCNetSDK.NET_DVR_FINDDATA_V30 strFile;
  227. if (lFindFile < 0) {
  228. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  229. logger.warn("获取录像文件错误!错误原因:" + m_err.getValue() + "," + err);
  230. return null;
  231. }
  232. int lnext;
  233. strFile = new HCNetSDK.NET_DVR_FINDDATA_V30();
  234. HashMap<String, String> map = new HashMap<>();
  235. boolean flag=true;
  236. while (flag) {
  237. lnext = hCNetSDK.NET_DVR_FindNextFile_V30(lFindFile, strFile);
  238. if (lnext == HCNetSDK.NET_DVR_FILE_SUCCESS) {
  239. //搜索成功
  240. //添加文件名信息
  241. String[] s = new String[2];
  242. s = new String(strFile.sFileName).split("\0", 2);
  243. map.put("fileName:", new String(s[0]));
  244. int iTemp;
  245. String MyString;
  246. if (strFile.dwFileSize < 1024 * 1024) {
  247. iTemp = (strFile.dwFileSize) / (1024);
  248. MyString = iTemp + "K";
  249. } else {
  250. iTemp = (strFile.dwFileSize) / (1024 * 1024);
  251. MyString = iTemp + "M ";
  252. iTemp = ((strFile.dwFileSize) % (1024 * 1024)) / (1204);
  253. MyString = MyString + iTemp + "K";
  254. }
  255. map.put("fileSize", MyString); //添加文件大小信息
  256. map.put("struStartTime", strFile.struStartTime.toStringTime()); //添加开始时间信息
  257. map.put("struStopTime", strFile.struStopTime.toStringTime()); //添加结束时间信息
  258. fileList.add(map);
  259. } else {
  260. if (lnext == HCNetSDK.NET_DVR_ISFINDING) {//搜索中
  261. //System.out.println("搜索中");
  262. continue;
  263. } else {
  264. flag=false;
  265. if (lnext == HCNetSDK.NET_DVR_FILE_NOFIND) {
  266. //flag=false;
  267. } else {
  268. //flag=false;
  269. System.out.println("搜索文件结束");
  270. boolean flag2 = hCNetSDK.NET_DVR_FindClose_V30(lFindFile);
  271. if (flag2 == false) {
  272. System.out.println("结束搜索失败");
  273. }
  274. }
  275. }
  276. }
  277. }
  278. return fileList;
  279. }
  280. public boolean playControl(String command, int mill, int channel) throws InterruptedException {
  281. HCPlayControlEnum controlEnum = HCPlayControlEnum.valueOf(command);
  282. boolean playHandle = false;
  283. //开始控制
  284. playHandle = hCNetSDK.NET_DVR_PTZControl_Other(lUserID,channel,controlEnum.getCode(),0);
  285. if(!playHandle){
  286. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  287. logger.warn("(开始)控制失败!错误原因:" + m_err.getValue() + "," + err);
  288. return false;
  289. }
  290. //控制时间
  291. Thread.sleep(mill);
  292. //停止控制
  293. playHandle = hCNetSDK.NET_DVR_PTZControl_Other(lUserID,channel,controlEnum.getCode(),1);
  294. if(!playHandle){
  295. String err = hCNetSDK.NET_DVR_GetErrorMsg(m_err);
  296. logger.warn("(停止)控制失败!错误原因:" + m_err.getValue() + "," + err);
  297. return false;
  298. }
  299. return true;
  300. }
  301. /**
  302. * 获取海康录像机格式的时间
  303. *
  304. * @param time
  305. * @return
  306. */
  307. public HCNetSDK.NET_DVR_TIME getHkTime(LocalDateTime time) {
  308. HCNetSDK.NET_DVR_TIME structTime = new HCNetSDK.NET_DVR_TIME();
  309. String str = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss").format(time);
  310. String[] times = str.split("-");
  311. structTime.dwYear = Integer.parseInt(times[0]);
  312. structTime.dwMonth = Integer.parseInt(times[1]);
  313. structTime.dwDay = Integer.parseInt(times[2]);
  314. structTime.dwHour = Integer.parseInt(times[3]);
  315. structTime.dwMinute = Integer.parseInt(times[4]);
  316. structTime.dwSecond = Integer.parseInt(times[5]);
  317. return structTime;
  318. }
  319. public static boolean isLinux() {
  320. return System.getProperty("os.name").toLowerCase().contains("linux");
  321. }
  322. public static boolean isWindows() {
  323. return System.getProperty("os.name").toLowerCase().contains("windows");
  324. }
  325. }