HIKNvr.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #define NOMINMAX
  2. #include "./date/date.h"
  3. #include "HIKNvr.h"
  4. #include <ctime>
  5. #include <iostream>
  6. #include <chrono>
  7. HIKNvr::HIKNvr(){
  8. }
  9. /**
  10. * @brief Initializes the NVR with the given login information and channel.
  11. *
  12. * @param ip The IP address of the NVR.
  13. * @param port The port number of the NVR.
  14. * @param username The username for logging into the NVR.
  15. * @param password The password for logging into the NVR.
  16. * @param channel The channel number to set for the NVR.
  17. */
  18. bool HIKNvr::InitNvr(std::string ip, std::string port, std::string username, std::string password, int channel)
  19. {
  20. if (Login(ip, port, username, password) == 0){
  21. m_Channel = channel + 32;
  22. return true;
  23. }
  24. return false;
  25. }
  26. int HIKNvr::GetNvrUTCDiff(){
  27. NET_DVR_NETAPPCFG struNAC = {0};
  28. DWORD ZoneSize = 0;
  29. NET_DVR_GetDVRConfig(LoginID, NET_DVR_GET_NETAPPCFG, 0, &struNAC, sizeof(NET_DVR_NETAPPCFG), &ZoneSize);
  30. int nDiffHour = struNAC.struNtpClientParam.cTimeDifferenceH;
  31. int nDiffMin = struNAC.struNtpClientParam.cTimeDifferenceM;
  32. nDiffTotalMin = (nDiffHour < 0 ? -1 : 1) * (abs(nDiffHour) * 60 + nDiffMin);
  33. return (nDiffHour < 0 ? -1 : 1) * (abs(nDiffHour) * 60 + nDiffMin);
  34. }
  35. /**
  36. * @brief 用年和月查询日
  37. *
  38. * @param select_time The selected time.
  39. * @param available_date_vec The available date vector.
  40. * @return true if the time region is found, false otherwise.
  41. */
  42. int HIKNvr::CheckTimeRegionWithMonth(DateTime select_time,std::vector<int>& available_date_vec)
  43. {
  44. DateTime DateNow(select_time);
  45. // 查当月
  46. NET_DVR_MRD_SEARCH_PARAM struSearchParam = {0};
  47. NET_DVR_MRD_SEARCH_RESULT struSearchResult = {0};
  48. struSearchParam.dwSize = sizeof(NET_DVR_MRD_SEARCH_PARAM);
  49. struSearchParam.wYear = DateNow.year();
  50. struSearchParam.byMonth = DateNow.month();
  51. struSearchParam.struStreamInfo.dwChannel = m_Channel; // channel
  52. struSearchParam.byLocalOrUTC = true; // 0:local time, 1:UTC time (时区)
  53. struSearchParam.byDrawFrame = 0; // 0:不抽帧,1:抽帧
  54. struSearchParam.byStreamType = 0;// 0:主码流,1:子码流
  55. // 查记录
  56. if (!NET_DVR_GetDeviceConfig(this->LoginID, NET_DVR_GET_MONTHLY_RECORD_DISTRIBUTION, 0, &struSearchParam, sizeof(struSearchParam), NULL, &struSearchResult, sizeof(struSearchResult)))
  57. {
  58. int n = NET_DVR_GetLastError();
  59. return n == NET_DVR_NETWORK_FAIL_CONNECT ? NVR_ERR_CONNECT_7 : NVR_ERR_HIK;
  60. }
  61. for (int i = 0; i < 32; i++)
  62. {
  63. if (struSearchResult.byRecordDistribution[i])
  64. {
  65. available_date_vec.push_back(i + 1);
  66. }
  67. }
  68. return NVR_SUC;
  69. }
  70. /**
  71. * @brief Check if a given time falls within the available time range for the current day.
  72. *
  73. * @param select_time The time to check.
  74. * @param available_time_vec A vector of available time ranges for the current day.
  75. * @return true if the given time falls within the available time range, false otherwise.
  76. */
  77. int HIKNvr::CheckTimeRegionWithDay(DateTime select_time, std::vector<TimeRecord> &available_time_vec)
  78. {
  79. int nRet = NVR_SUC;
  80. GetNvrUTCDiff();
  81. DateTime DateNow(select_time);
  82. int nYear = DateNow.year();
  83. int nMonth = DateNow.month();
  84. int nDay = DateNow.day();
  85. NET_DVR_FILECOND FileCond;
  86. FileCond.dwFileType = 0xff;// 0xff:所有文件
  87. FileCond.dwIsLocked = 0xff;// 0xff:所有文件
  88. FileCond.dwUseCardNo = 0; //不使用卡号
  89. FileCond.lChannel = m_Channel;//通道号
  90. FileCond.struStartTime.dwYear = DateNow.year();
  91. FileCond.struStartTime.dwMonth = DateNow.month();
  92. FileCond.struStartTime.dwDay = DateNow.day();
  93. FileCond.struStartTime.dwHour = 0;
  94. FileCond.struStartTime.dwMinute = 0;
  95. FileCond.struStartTime.dwSecond = 0;
  96. FileCond.struStopTime.dwYear = DateNow.year();
  97. FileCond.struStopTime.dwMonth = DateNow.month();
  98. FileCond.struStopTime.dwDay = DateNow.day();
  99. FileCond.struStopTime.dwHour = 23;
  100. FileCond.struStopTime.dwMinute = 59;
  101. FileCond.struStopTime.dwSecond = 59;
  102. available_time_vec.clear();
  103. LONG hFindHandle = NET_DVR_FindFile_V30(LoginID, &FileCond);
  104. if (-1 == hFindHandle)
  105. {
  106. nRet = NET_DVR_GetLastError();
  107. return nRet == NET_DVR_NETWORK_FAIL_CONNECT?NVR_ERR_CONNECT_7:NVR_ERR_HIK;
  108. }
  109. else
  110. {
  111. NET_DVR_FINDDATA_V30 FindData; // 查找到的文件信息
  112. nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
  113. int ItemIndex = 0;
  114. while (nRet > 0)
  115. {
  116. if (NET_DVR_FILE_EXCEPTION == nRet)//查找文件时异常
  117. {
  118. break;
  119. }
  120. else if (NET_DVR_FILE_NOFIND == nRet)//没有文件
  121. {
  122. break;
  123. }
  124. else if (NET_DVR_NOMOREFILE == nRet) // 查找结束
  125. {
  126. break;
  127. }
  128. else if (NET_DVR_ISFINDING == nRet) // 正在查找
  129. {
  130. nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
  131. //请求过快,会出读错误。同时也是参考海康sdk写法。
  132. std::this_thread::sleep_for(std::chrono::milliseconds(5));
  133. }
  134. else if (NET_DVR_FILE_SUCCESS == nRet) // 获取文件信息成功
  135. {
  136. // 保存文件信息
  137. TimeRecord tR;
  138. if (nDay != FindData.struStartTime.dwDay)//起始不在今日
  139. {
  140. tR.TimeStart.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, nDay, 0, 0, 0);
  141. }
  142. else//起始在今日
  143. {
  144. tR.TimeStart.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, FindData.struStartTime.dwDay, FindData.struStartTime.dwHour, FindData.struStartTime.dwMinute, FindData.struStartTime.dwSecond);
  145. }
  146. if (nDay != FindData.struStopTime.dwDay)//结束不在今日
  147. {
  148. tR.TimeEnd.SetDateTime(FindData.struStartTime.dwYear, FindData.struStartTime.dwMonth, FindData.struStartTime.dwDay, 23, 59, 59);
  149. }
  150. else//结束在今日
  151. {
  152. tR.TimeEnd.SetDateTime(FindData.struStopTime.dwYear, FindData.struStopTime.dwMonth, FindData.struStopTime.dwDay,
  153. FindData.struStopTime.dwHour, FindData.struStopTime.dwMinute, FindData.struStopTime.dwSecond);
  154. }
  155. date::sys_days original_date_start{date::year{tR.TimeStart.year()} / date::month{static_cast<unsigned int>(tR.TimeStart.month())} / date::day{static_cast<unsigned int>(tR.TimeStart.day())}};
  156. date::sys_time<std::chrono::seconds> original_time_start{date::sys_days{original_date_start} + std::chrono::hours{tR.TimeStart.hour()} + std::chrono::minutes{tR.TimeStart.minute()} + std::chrono::seconds{tR.TimeStart.minute()}};
  157. date::sys_time<std::chrono::seconds> utc_plus_8_time_start = original_time_start - std::chrono::minutes{nDiffTotalMin};
  158. date::sys_days original_date_end{date::year{tR.TimeEnd.year()} / date::month{static_cast<unsigned int>(tR.TimeEnd.month())} / date::day{static_cast<unsigned int>(tR.TimeEnd.day())}};
  159. date::sys_time<std::chrono::seconds> original_time_end{date::sys_days{original_date_end} + std::chrono::hours{tR.TimeEnd.hour()} + std::chrono::minutes{tR.TimeEnd.minute()} + std::chrono::seconds{tR.TimeEnd.minute()}};
  160. date::sys_time<std::chrono::seconds> utc_plus_8_time_end = original_time_end - std::chrono::minutes{nDiffTotalMin};
  161. // 计算时间点到1970-01-01 00:00:00 UTC的时间间隔,即时间戳
  162. std::chrono::seconds timestamp = std::chrono::duration_cast<std::chrono::seconds>(utc_plus_8_time_start.time_since_epoch());
  163. tR.tmTimeStart = timestamp.count();
  164. timestamp = std::chrono::duration_cast<std::chrono::seconds>(utc_plus_8_time_end.time_since_epoch());
  165. tR.tmTimeEnd = timestamp.count();
  166. available_time_vec.emplace_back(tR);
  167. nRet = NET_DVR_FindNextFile_V30(hFindHandle, &FindData);
  168. }
  169. }
  170. // 关闭查找,释放句柄
  171. NET_DVR_FindClose_V30(hFindHandle);
  172. }
  173. return NVR_SUC;
  174. }
  175. /**
  176. * @brief Get the time region based on the selected time and value.
  177. *
  178. * @param SelectTime The selected time.
  179. * @param Value The value used to calculate the time region.
  180. * @param TimeStart The start time of the time region.
  181. * @param TimeEnd The end time of the time region.
  182. * @return true if the time region is found, false otherwise.
  183. */
  184. bool HIKNvr::GetTimeRegion(DateTime SelectTime, int Value, DateTime &TimeStart, DateTime &TimeEnd)
  185. {
  186. int nYear = SelectTime.year();
  187. int nMonth = SelectTime.month();
  188. int nDay = SelectTime.day();
  189. // 时间格式 转换,找时间区间
  190. int nHour = Value / 3600;
  191. int nMinute = Value / 60 - 60 * nHour;
  192. int nSecond = Value - (nMinute + 60 * nHour) * 60;
  193. TimeStart = SelectTime;
  194. TimeStart.hour() = nHour;
  195. TimeStart.minute() = nMinute;
  196. TimeStart.second() = nSecond;
  197. bool bHave = false;
  198. for (auto it : m_TimeRecords)
  199. {
  200. if (it.IsInRecord(TimeStart))
  201. {
  202. bHave = true;
  203. TimeEnd = it.TimeEnd;
  204. break;
  205. }
  206. }
  207. return bHave;
  208. }
  209. /**
  210. * @brief Turn the time to json.
  211. *
  212. * @param Time The time to be turned to json.
  213. * @param pAvailableDateVec The available date vector.
  214. * @return nlohmann::json& The json object.
  215. */
  216. nlohmann::json HIKNvr::TimeToJson(DateTime Time, std::vector<int> *pAvailableDateVec)
  217. {
  218. nlohmann::json Message;
  219. //year and month
  220. Message["year"] = Time.year();
  221. Message["month"] = Time.month();
  222. //date
  223. if (pAvailableDateVec != nullptr)
  224. {
  225. nlohmann::json data;
  226. for (auto date : *pAvailableDateVec)
  227. {
  228. data.push_back(date);
  229. }
  230. Message["day"] = data;
  231. }
  232. return Message;
  233. }
  234. /**
  235. * @brief Converts available time slots in a day to JSON format.
  236. *
  237. * @param Time The date and time of the day.
  238. * @param pAvailableTimeVec A pointer to a vector of available time slots.
  239. * @return nlohmann::json& A reference to the JSON object containing the converted time slots.
  240. */
  241. nlohmann::json HIKNvr::TimeToJsonInDay(DateTime Time, std::vector<TimeRecord> *pAvailableTimeVec)
  242. {
  243. nlohmann::json Message;
  244. if(pAvailableTimeVec != nullptr)
  245. {
  246. for(auto time : *pAvailableTimeVec)
  247. {
  248. nlohmann::json data;
  249. data["begin"] = time.tmTimeStart;
  250. data["end"] = time.tmTimeEnd;
  251. Message.push_back(data);
  252. }
  253. }
  254. return Message;
  255. }