CameraUtil.java 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718
  1. package com.ozs.utils;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONArray;
  4. import com.alibaba.fastjson2.JSONObject;
  5. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.hikvision.artemis.sdk.ArtemisHttpUtil;
  8. import com.hikvision.artemis.sdk.config.ArtemisConfig;
  9. import com.ozs.common.config.BaseConfig;
  10. import com.ozs.common.constant.Constants;
  11. import com.ozs.common.core.domain.AjaxResult;
  12. import com.ozs.common.core.domain.entity.SysDictData;
  13. import com.ozs.common.core.redis.RedisCache;
  14. import com.ozs.common.exception.base.BaseException;
  15. import com.ozs.common.utils.DateUtils;
  16. import com.ozs.common.utils.HttpClientUtil;
  17. import com.ozs.common.utils.http.HttpUtils;
  18. import com.ozs.entity.BaseCameraManagement;
  19. import com.ozs.entity.BaseTerminal;
  20. import com.ozs.entity.BaseTerminalLog;
  21. import com.ozs.entity.MsgHeartbeatAlarmMessage;
  22. import com.ozs.entity.response.BaseCameraManagementResponse;
  23. import com.ozs.entity.vo.CamerasVo;
  24. import com.ozs.entity.vo.PlaybackVo;
  25. import com.ozs.framework.config.ServerConfig;
  26. import com.ozs.service.BaseCameraManagementService;
  27. import com.ozs.service.BaseTerminalLogService;
  28. import com.ozs.service.BaseTerminalService;
  29. import com.ozs.service.MsgHeartbeatAlarmMessageService;
  30. import com.ozs.system.mapper.SysDictDataMapper;
  31. import com.ozs.system.service.ISysDictTypeService;
  32. import lombok.SneakyThrows;
  33. import lombok.extern.slf4j.Slf4j;
  34. import org.apache.commons.lang3.StringUtils;
  35. import org.springframework.beans.factory.annotation.Autowired;
  36. import org.springframework.context.annotation.Configuration;
  37. import org.springframework.util.ObjectUtils;
  38. import javax.annotation.PostConstruct;
  39. import java.io.BufferedReader;
  40. import java.io.BufferedWriter;
  41. import java.io.File;
  42. import java.io.FileFilter;
  43. import java.io.IOException;
  44. import java.io.InputStreamReader;
  45. import java.io.OutputStreamWriter;
  46. import java.io.PrintWriter;
  47. import java.text.ParseException;
  48. import java.text.SimpleDateFormat;
  49. import java.time.Duration;
  50. import java.time.Instant;
  51. import java.time.LocalDateTime;
  52. import java.time.OffsetDateTime;
  53. import java.time.ZoneOffset;
  54. import java.time.ZonedDateTime;
  55. import java.time.format.DateTimeFormatter;
  56. import java.util.ArrayList;
  57. import java.util.Calendar;
  58. import java.util.Date;
  59. import java.util.GregorianCalendar;
  60. import java.util.HashMap;
  61. import java.util.List;
  62. import java.util.Map;
  63. import java.util.Random;
  64. import java.util.Set;
  65. import java.util.UUID;
  66. import java.util.concurrent.Callable;
  67. import java.util.concurrent.CompletableFuture;
  68. import java.util.concurrent.ExecutionException;
  69. import java.util.concurrent.ExecutorService;
  70. import java.util.concurrent.Executors;
  71. import java.util.concurrent.TimeUnit;
  72. import java.util.concurrent.TimeoutException;
  73. import java.util.stream.Collectors;
  74. /**
  75. * 相机工具
  76. */
  77. @Configuration
  78. @Slf4j
  79. public class CameraUtil {
  80. private static final ExecutorService executor = Executors.newFixedThreadPool(20);
  81. private static String historyUrl;
  82. private static String ffmpegPath;
  83. private static String filePath;
  84. private static String transcribeFilePath;
  85. private static String webUrl;
  86. private static String bakUrl;
  87. private static String bakUrlRtsp;
  88. private static String wsUrl;
  89. private static String wsUrls;
  90. private static String httpUrl;
  91. private static String httpUrls;
  92. private static CmdCameraUtil cUtil;
  93. private static RedisCache rc;
  94. private static ServerConfig sc;
  95. private static String recordUrl;
  96. private static String hkUrl;
  97. private static String host;
  98. private static String appKey;
  99. private static String appSecret;
  100. private static String rtmpUrl;
  101. @Autowired
  102. private CaneraConfig caneraConfig;
  103. @Autowired
  104. private CmdCameraUtil cmdCameraUtil;
  105. @Autowired
  106. private SysDictDataMapper dictDataMapper;
  107. @Autowired
  108. private RedisCache redisCache;
  109. @Autowired
  110. private ServerConfig serverConfig;
  111. @Autowired
  112. private BaseTerminalService baseTerminalService;
  113. @Autowired
  114. private MsgHeartbeatAlarmMessageService msgHeartbeatAlarmMessageService;
  115. @Autowired
  116. private ISysDictTypeService dictTypeService;
  117. @Autowired
  118. private RtspToMP4 rtspToMP4;
  119. @Autowired
  120. private BaseCameraManagementService baseCameraManagementService;
  121. @Autowired
  122. private BaseTerminalLogService baseTerminalLogService;
  123. private Map<String, Process> map = new HashMap<>();
  124. public final static String tsFilekey = "mergeVideoTsFile";
  125. /**
  126. * 历史回放
  127. *
  128. * @param fromVideoFileList
  129. * @param ph
  130. * @return
  131. * @throws IOException
  132. */
  133. public static String historyPlay(List<String> fromVideoFileList, String ph, boolean flay) {
  134. // 视频服务映射路径
  135. String NewfilePath = BaseConfig.getProfile() + "/" + ph;
  136. log.info("NewfilePath:{}", NewfilePath);
  137. log.info("fromVideoFileList:{}", fromVideoFileList);
  138. if (ObjectUtils.isEmpty(fromVideoFileList) || fromVideoFileList.size() <= 0) {
  139. throw new BaseException("当前相机无视频录像");
  140. }
  141. executor.submit(new Runnable() {
  142. @Override
  143. public void run() {
  144. try {
  145. txConvetor(fromVideoFileList, NewfilePath, flay);
  146. } catch (IOException e) {
  147. log.error(e.getMessage());
  148. e.printStackTrace();
  149. }
  150. }
  151. });
  152. // executor.shutdown();
  153. return Constants.RESOURCE_PREFIX + "/" + ph;
  154. }
  155. @SneakyThrows
  156. public static void txConvetor(List<String> fromVideoFileList,
  157. String newfilePath,
  158. boolean fly) throws IOException {
  159. /*
  160. * ffmpeg -i 20230411_155847_155947-d4c2265d-d83e-11ed-8e7f-fa163e4e1e9f.flv -c:v copy 1.ts
  161. ffmpeg -i 20230411_155948_160048-f91fea03-d83e-11ed-8e7f-fa163e4e1e9f.flv -c:v copy 2.ts
  162. ffmpeg -i "concat:1.ts|2.ts" -c copy output.mp4
  163. * */
  164. File file = new File(newfilePath);
  165. boolean flay = false;
  166. if (!file.getParentFile().exists()) {
  167. boolean mkdirs = file.getParentFile().mkdirs();
  168. log.info("创建文件夹:{}", file.getParentFile().getPath());
  169. log.info("创建文件夹结果:{}", mkdirs);
  170. flay = true;
  171. }
  172. cUtil.cmd("chomd -R 777 " + file.getParentFile().getPath());
  173. log.info("newfilePath:{}", newfilePath);
  174. StringBuffer sm = new StringBuffer(ffmpegPath + " -i \"concat:");
  175. List<String> fileTs = new ArrayList<>();
  176. for (int t = 0; t < fromVideoFileList.size(); t++) {
  177. File ft = new File(fromVideoFileList.get(t));
  178. if (ft.exists()) {
  179. log.info("file:{}", fromVideoFileList.get(t));
  180. String substring = fromVideoFileList.get(t).substring(0, fromVideoFileList.get(t).lastIndexOf("."));
  181. int x;//定义两变量
  182. Random ne = new Random();//实例化一个random的对象ne
  183. x = ne.nextInt(9999 - 1000 + 1) + 1000;//为变量赋随机值1000-9999
  184. substring = substring + x;//定义两变量
  185. String cmdstr = ffmpegPath + " -i " + fromVideoFileList.get(t) + " -c:v copy " + substring + ".ts";
  186. log.info("转换命令:{}", cmdstr);
  187. cUtil.cmd(cmdstr);
  188. fileTs.add(substring + ".ts");
  189. if (t != fromVideoFileList.size() - 1) {
  190. sm.append(substring + ".ts|");
  191. } else {
  192. sm.append(substring + ".ts\" ");
  193. }
  194. }
  195. }
  196. if (fileTs.size() > 0) {
  197. Map<String, Object> mergeVideoTsFile = rc.getCacheMap(tsFilekey);
  198. if (ObjectUtils.isEmpty(mergeVideoTsFile)) {
  199. mergeVideoTsFile = new HashMap<>();
  200. }
  201. if (!flay) {
  202. // 如果没有解除,把生成的文件放入要删除的定时任务 redis key 中
  203. fileTs.add(newfilePath);
  204. }
  205. mergeVideoTsFile.put(System.currentTimeMillis() + "", fileTs);
  206. rc.deleteObject(tsFilekey);
  207. if (mergeVideoTsFile.size() > 0) {
  208. rc.setCacheMap(tsFilekey, mergeVideoTsFile);
  209. }
  210. sm.append("-c copy " + newfilePath);
  211. log.info("合并命令:{}", sm.toString());
  212. cUtil.cmd(sm.toString());
  213. }
  214. }
  215. /**
  216. * 实时播放的拼接流
  217. *
  218. * @param cameraCode 相机编码
  219. * @param channel 相机通道
  220. * @return
  221. */
  222. public static String getPlayFlv(String cameraCode, String channel, boolean flay, String state) {
  223. log.info("getPlayFlv----master---------"+wsUrl);
  224. return wsUrl + "/ws/" + cameraCode + "/" + channel + ".flv";
  225. // if (!flay) {
  226. // return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  227. // }
  228. // return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  229. }
  230. public static String getPlayFlv(String cameraCode, String channel, boolean flay) {
  231. if (!flay) {
  232. return bakUrl + "/hdl/" + cameraCode + "/" + channel + ".flv";
  233. }
  234. return wsUrl + "/ws/" + cameraCode + "/" + channel + ".flv";
  235. // if (!flay) {
  236. // return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  237. // }
  238. // return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  239. }
  240. /**
  241. * Rtsp实时播放的拼接流 心跳接口使用
  242. *
  243. * @param cameraCode 相机编码
  244. * @param channel 相机通道
  245. * @return
  246. */
  247. public static String getPlayFlvRtsp(String cameraCode, String channel, boolean flay, String url) {
  248. log.info("---------getPlayFlvRtsp----url--"+url);
  249. if (url.contains("10.48.31.84")) {
  250. log.info("-----getPlayFlvRtsp------11------>" + bakUrlRtsp + "/master/hdl/" + cameraCode + "/" + channel + ".flv");
  251. return bakUrlRtsp + "/master/hdl/" + cameraCode + "/" + channel + "/h264_720.flv";
  252. }else {
  253. log.info("-------getPlayFlvRtsp----22------>" + bakUrlRtsp + "/slave/hdl/" + cameraCode + "/" + channel + ".flv");
  254. return bakUrlRtsp + "/slave/hdl/" + cameraCode + "/" + channel + "/h264_720.flv";
  255. }
  256. // if (!flay) {
  257. // return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  258. // }
  259. // return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  260. }
  261. /**
  262. * 点播的时候使用
  263. *
  264. * @param cameraCode
  265. * @param channel
  266. * @param flay
  267. * @return
  268. */
  269. public static String getPlayFlvRtsps(String cameraCode, String channel, boolean flay) {
  270. if (!flay) {
  271. log.info("-----getPlayFlvRtsps------11------>" + bakUrlRtsp + "/hdl/" + cameraCode + "/" + channel + ".flv");
  272. return bakUrlRtsp + "/hdl/" + cameraCode + "/" + channel + ".flv";
  273. }
  274. log.info("-------getPlayFlvRtsps----22------>" + bakUrlRtsp + "/hdl/" + cameraCode + "/" + channel + ".flv");
  275. return bakUrlRtsp + "/hdl/" + cameraCode + "/" + channel + ".flv";
  276. // if (!flay) {
  277. // return bakUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  278. // }
  279. // return webUrl + "/ws/" + channel + "/" + cameraCode + ".flv";
  280. }
  281. /**
  282. * web页面实时流接口
  283. *
  284. * @param cameraCode
  285. * @param channel
  286. * @return
  287. */
  288. public String getPlayFlv(String cameraCode, String channel) {
  289. int maxRetries = 3;
  290. int retryCount = 0;
  291. boolean success = false;
  292. JSONArray jsonArray = null;
  293. List<String> pathList = new ArrayList<>();
  294. String data = HttpUtils.sendGet(webUrl + "/rtsp/api/list");
  295. if (StringUtils.isNotEmpty(data)) {
  296. log.info("---------------data---" + data);
  297. while (!success && retryCount < maxRetries) {
  298. try {
  299. jsonArray = JSONArray.parseArray(data);
  300. success = true;
  301. } catch (Exception e) {
  302. e.printStackTrace();
  303. log.info("Exception caught: " + e.getMessage());
  304. // 增加重试计数
  305. retryCount++;
  306. }
  307. }
  308. log.info("---------------jsonArray---" + jsonArray);
  309. if (!ObjectUtils.isEmpty(jsonArray)) {
  310. for (int i = 0; i < jsonArray.size(); i++) {
  311. JSONObject jsonObject = jsonArray.getJSONObject(i);
  312. String name = jsonObject.getString("Path");
  313. pathList.add(name);
  314. }
  315. boolean contains = pathList.contains(cameraCode + "/" + channel);
  316. if (contains) {
  317. String cacheObject = redisCache.getCacheObject(cameraCode);
  318. return getPlayFlv(cameraCode, channel, true, cacheObject);
  319. } else {
  320. /**
  321. * jsonBody.put("cameraIndexCode", "01ea43e6676f4e47bd6c5cd9e02aa006");
  322. * jsonBody.put("streamType", 0);
  323. * jsonBody.put("protocol","rtsp");
  324. * jsonBody.put("transmode", 1);
  325. * jsonBody.put("expand","streamform=rtp");
  326. */
  327. CamerasVo camerasVo = new CamerasVo();
  328. camerasVo.setCameraIndexCode(cameraCode);
  329. String urLs = previewURLs(camerasVo, channel,httpUrl);
  330. log.info("web实时流---"+urLs);
  331. if (!urLs.contains("无视频")) {
  332. return getPlayFlv(cameraCode, channel, true, urLs);
  333. }else {
  334. return urLs;
  335. }
  336. }
  337. } else {
  338. CamerasVo camerasVo = new CamerasVo();
  339. camerasVo.setCameraIndexCode(cameraCode);
  340. String urLs = previewURLs(camerasVo, channel,httpUrl);
  341. log.info("web实时流---"+urLs);
  342. if (!urLs.contains("无视频")) {
  343. return getPlayFlv(cameraCode, channel, true, urLs);
  344. }else {
  345. return urLs;
  346. }
  347. }
  348. } else {
  349. CamerasVo camerasVo = new CamerasVo();
  350. camerasVo.setCameraIndexCode(cameraCode);
  351. String urLs = previewURLs(camerasVo, channel,httpUrl);
  352. if (!urLs.contains("无视频")) {
  353. return getPlayFlv(cameraCode, channel, true, urLs);
  354. }else {
  355. return urLs;
  356. }
  357. }
  358. }
  359. public String heartbeatgetPlayFlv(String cameraCode, String channel, boolean type) {
  360. int maxRetries = 3;
  361. int retryCount = 0;
  362. boolean success = false;
  363. JSONArray jsonArray = null;
  364. List<String> pathList = new ArrayList<>();
  365. //从redis中获取该相机的IP地址
  366. String cacheObject = redisCache.getCacheObject(cameraCode);
  367. if(StringUtils.isEmpty(cacheObject)){
  368. cacheObject=httpUrl;
  369. }
  370. while (!success && retryCount < maxRetries) {
  371. try {
  372. String data = HttpUtils.sendGet(cacheObject + "/rtsp/api/list");
  373. log.info("data------------------>" + data);
  374. if (StringUtils.isNotEmpty(data)) {
  375. jsonArray = JSONArray.parseArray(data);
  376. success = true;
  377. }
  378. } catch (Exception e) {
  379. log.info("Exception caught: " + e.getMessage());
  380. // 增加重试计数
  381. retryCount++;
  382. }
  383. }
  384. log.info("jsonArray------------------>" + jsonArray);
  385. if (!ObjectUtils.isEmpty(jsonArray)) {
  386. for (int i = 0; i < jsonArray.size(); i++) {
  387. JSONObject jsonObject = jsonArray.getJSONObject(i);
  388. String name = jsonObject.getString("Path");
  389. pathList.add(name);
  390. }
  391. boolean contains = pathList.contains(cameraCode + "/" + channel);
  392. if (!contains) {
  393. return null;
  394. } else {
  395. return getPlayFlvRtsp(cameraCode, channel,type, cacheObject);
  396. }
  397. }
  398. return null;
  399. }
  400. public List<String> rtspApiList() {
  401. List<String> pathList = new ArrayList<>();
  402. String data = HttpUtils.sendGet(webUrl + "/rtsp/api/list");
  403. log.info("data------------------>" + data);
  404. if (StringUtils.isNotEmpty(data)) {
  405. JSONArray jsonArray = JSONArray.parseArray(data);
  406. log.info("jsonArray------------------>" + jsonArray);
  407. if (!ObjectUtils.isEmpty(jsonArray)) {
  408. for (int i = 0; i < jsonArray.size(); i++) {
  409. JSONObject jsonObject = jsonArray.getJSONObject(i);
  410. String name = jsonObject.getString("Path");
  411. pathList.add(name);
  412. }
  413. return pathList;
  414. }
  415. return null;
  416. }
  417. return null;
  418. }
  419. public String heartbeatgetUrl(String cameraCode, String channel, boolean type,String url) throws Exception {
  420. CamerasVo camerasVo = new CamerasVo();
  421. camerasVo.setCameraIndexCode(cameraCode);
  422. String s = previewURLs(camerasVo, channel,url);
  423. log.info("-------heartbeatgetUrl---------" + s);
  424. if (s.contains("无视频")) {
  425. log.info("-------无视频---------");
  426. return s;
  427. } else {
  428. log.info("-------getPlayFlvRtsp---------" + getPlayFlvRtsp(cameraCode, channel, type, url));
  429. return getPlayFlvRtsp(cameraCode, channel, type, url);
  430. }
  431. }
  432. public String heartbeatgetUrls(String cameraCode, String channel, boolean type) throws Exception {
  433. CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
  434. CamerasVo camerasVo = new CamerasVo();
  435. camerasVo.setCameraIndexCode(cameraCode);
  436. String s = previewURLs(camerasVo, channel,httpUrl);
  437. if (s.contains("无视频")) {
  438. return s;
  439. } else {
  440. return getPlayFlvRtsps(cameraCode, channel, type);
  441. }
  442. });
  443. return future.get();
  444. }
  445. public static String invite(String cameraCode, String channel) {
  446. String result = null;
  447. String url = bakUrl + "/api/gb28181/invite?id=" + cameraCode + "&channel=" + channel;
  448. try {
  449. result = HttpClientUtil.get(url);
  450. log.info("result:{}", result);
  451. } catch (Exception e) {
  452. log.info(e.getMessage());
  453. e.printStackTrace();
  454. }
  455. return result;
  456. }
  457. /**
  458. * 开启录制功能
  459. *
  460. * @param cameraCode 相机编码
  461. * @param channel 相机通道
  462. * @return
  463. */
  464. public static String startRecording(String cameraCode, String channel) {
  465. log.info("-----startRecording------" + historyUrl + "/recordpro/api/start?streamPath=" + cameraCode + "/" + channel+"&type=mp4");
  466. return historyUrl + "/recordpro/api/start?streamPath=" + cameraCode + "/" + channel+"&type=mp4";
  467. }
  468. /**
  469. * 关闭录制功能
  470. *
  471. * @param taskId 录像接口返回的任务ID
  472. * @return
  473. */
  474. public static String endRecording(String taskId) {
  475. return historyUrl + "/recordpro/api/stop?id=" + taskId;
  476. }
  477. /**
  478. * 历史回放流(获取)
  479. *
  480. * @param channel 相机通道
  481. * @param startTm 开始时间
  482. * @param endTm 结束时间
  483. * @return
  484. */
  485. public static String historyPlayListStr(String channel, Date startTm, Date endTm, boolean flay) {
  486. List<String> list = filterPlayList(channel, startTm, endTm, filePath);
  487. String uuid = UUID.randomUUID().toString();
  488. String ph = "record/flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date())
  489. + "/" + channel + "/"
  490. + uuid + ".mp4";
  491. if (!ObjectUtils.isEmpty(list)) {
  492. try {
  493. return historyPlay(list, ph, flay);
  494. } catch (Exception e) {
  495. log.error(e.getMessage());
  496. e.printStackTrace();
  497. }
  498. } else {
  499. throw new BaseException("当前相机无视频录像");
  500. }
  501. return null;
  502. }
  503. /**
  504. * 过滤符合条件的视频
  505. *
  506. * @param channel
  507. * @param startTm
  508. * @param endTm
  509. * @param mappingUrl
  510. * @return
  511. */
  512. public static List<String> filterPlayList(String channel, Date startTm, Date endTm, String mappingUrl) {
  513. if (StringUtils.isBlank(channel)
  514. || ObjectUtils.isEmpty(startTm)
  515. || ObjectUtils.isEmpty(endTm)) {
  516. return null;
  517. }
  518. List<String> ls = new ArrayList<>();
  519. Map<Date, String> m = new HashMap<>();
  520. // 调用视频服务返回参数
  521. String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTm);
  522. String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endTm);
  523. String param = "channel=" + channel + "&startTime=" + startTime + "&endTime=" + endTime;
  524. String s = HttpUtils.sendGet(historyUrl + "/api/record/flv/list", param);
  525. // 视频拼接
  526. if (!StringUtils.isBlank(s) && !"null".equals(s) && !s.startsWith("<!DOCTYPE html>")) {
  527. List<Map<String, Object>> maps = JSON.parseArray(s, Map.class);
  528. if (ObjectUtils.isEmpty(maps)) {
  529. return null;
  530. }
  531. for (Map<String, Object> map : maps) {
  532. Object path = map.get("Path");
  533. if (!ObjectUtils.isEmpty(path)) {
  534. String s1 = path.toString();
  535. String substring = s1.substring(s1.lastIndexOf("/") + 1, s1.length());
  536. String substring1 = substring.substring(0, substring.indexOf("-"));
  537. String[] s2 = substring1.split("_");
  538. if (!ObjectUtils.isEmpty(s2)) {
  539. String s3 = s2[0] + s2[1];
  540. String s4 = s2[0] + s2[2];
  541. Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s3);
  542. if (s2[1].startsWith("23") && s2[2].startsWith("00")) {
  543. sdate = DateUtils.addDays(sdate, -1);
  544. }
  545. Date edate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s4);
  546. /* sdate |startTm| edate |endTm| */
  547. if (startTm.compareTo(sdate) >= 0
  548. && startTm.compareTo(edate) <= 0
  549. && endTm.compareTo(edate) >= 0) {
  550. m.put(sdate, mappingUrl + path.toString());
  551. /* |startTm| sdate edate |endTm| */
  552. } else if (startTm.compareTo(sdate) <= 0 && endTm.compareTo(edate) >= 0) {
  553. m.put(sdate, mappingUrl + path.toString());
  554. /* |startTm| sdate |endTm| edate */
  555. } else if (startTm.compareTo(sdate) <= 0
  556. && endTm.compareTo(sdate) >= 0
  557. && endTm.compareTo(edate) <= 0) {
  558. m.put(sdate, mappingUrl + path.toString());
  559. /* sdate |startTm| |endTm| edate */
  560. } else if (startTm.compareTo(sdate) >= 0 && endTm.compareTo(edate) <= 0) {
  561. m.put(sdate, mappingUrl + path.toString());
  562. }
  563. }
  564. }
  565. }
  566. }
  567. if (!ObjectUtils.isEmpty(m) && m.size() > 0) {
  568. Set<Date> dates = m.keySet();
  569. // 排序
  570. dates.stream().parallel().collect(Collectors.toList()).stream().sorted().forEach(d -> {
  571. ls.add(m.get(d));
  572. });
  573. return ls;
  574. }
  575. return null;
  576. }
  577. /**
  578. * 合并视频(转化文件)
  579. *
  580. * @param fromVideoFileList 视频路径
  581. * @param newfilePath 生产新的视频文件路径
  582. * @throws IOException
  583. */
  584. public static Map<String, String> myConvetor(List<String> fromVideoFileList,
  585. String newfilePath,
  586. String uuid) throws IOException {
  587. /*
  588. * for f in *.flv; do echo "file '$f'" >> mylist.txt; done
  589. ffmpeg -f concat -i mylist.txt -c copy output.flv
  590. * */
  591. File file = new File(newfilePath);
  592. boolean flay = false;
  593. if (!file.getParentFile().exists()) {
  594. file.getParentFile().mkdirs();
  595. log.info("创建文件夹:{}", file.getParentFile().getPath());
  596. flay = true;
  597. }
  598. log.info("newfilePath:{}", newfilePath);
  599. StringBuffer sm = new StringBuffer("for f in ");
  600. String pathStr = null;
  601. for (int t = 0; t < fromVideoFileList.size(); t++) {
  602. File ft = new File(fromVideoFileList.get(t));
  603. if (ft.exists()) {
  604. if (t != fromVideoFileList.size() - 1) {
  605. // sm.append(fromVideoFileList.get(t) + " ");
  606. sm.append(fromVideoFileList.get(t).substring(fromVideoFileList.get(t).lastIndexOf("/") + 1, fromVideoFileList.get(t).length()) + " ");
  607. } else {
  608. // sm.append(fromVideoFileList.get(t));
  609. sm.append(fromVideoFileList.get(t).substring(fromVideoFileList.get(t).lastIndexOf("/") + 1, fromVideoFileList.get(t).length()));
  610. pathStr = fromVideoFileList.get(t).substring(0, fromVideoFileList.get(t).lastIndexOf("/"));
  611. }
  612. }
  613. }
  614. // String substring = newfilePath.substring(0, newfilePath.lastIndexOf("."));
  615. // substring = substring + ".txt";
  616. String substring = uuid + ".txt";
  617. log.info("临时转化的文件:{}", substring);
  618. sm.append("; do echo \"file '$f'\" >> " + substring + "; done");
  619. String commit = sm.toString();
  620. log.info("合并转化文件的命令:{}", commit);
  621. Process proc = Runtime.getRuntime().exec("/bin/bash", null, null);
  622. BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
  623. PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
  624. try {
  625. String commit1 = ffmpegPath + " -f concat -safe 0 -i " + pathStr + "/" + substring + " -c copy " + newfilePath;
  626. log.info("合并视频命令:{}", commit1);
  627. List<String> commands = new ArrayList<>();
  628. if (flay) {
  629. commands.add("chomd -R 777 " + file.getParentFile().getPath());
  630. }
  631. //
  632. commands.add("cd " + pathStr);
  633. // 合并成一个临时文件
  634. commands.add(commit);
  635. // 临时文件转化为 flv
  636. // commands.add(commit1);
  637. log.info("录像视频命令:{}", commands);
  638. for (String line : commands) {
  639. log.info("命令:{}", line);
  640. out.println(line);
  641. }
  642. out.println("exit");// 这个命令必须执行,否则in流不结束。
  643. log.info("命令:{}", "exit");
  644. String rspLine = "";
  645. while ((rspLine = in.readLine()) != null) {
  646. log.info("*****:{}", rspLine);
  647. }
  648. proc.waitFor();
  649. Map<String, String> map = new HashMap<>();
  650. map.put("cmd", commit1);
  651. map.put("path", pathStr + "/" + substring);
  652. return map;
  653. } catch (InterruptedException e) {
  654. log.error(e.getMessage());
  655. e.printStackTrace();
  656. } finally {
  657. in.close();
  658. out.close();
  659. proc.destroy();
  660. }
  661. return null;
  662. }
  663. @PostConstruct
  664. public void init() {
  665. historyUrl = caneraConfig.getHistoryUrl();
  666. ffmpegPath = caneraConfig.getFfmpegPath();
  667. filePath = caneraConfig.getFilePath();
  668. transcribeFilePath = caneraConfig.getTranscribeFilePath();
  669. webUrl = caneraConfig.getWebUrl();
  670. bakUrl = caneraConfig.getBakUrl();
  671. bakUrlRtsp = caneraConfig.getBakUrlRtsp();
  672. rc = redisCache;
  673. cUtil = cmdCameraUtil;
  674. sc = serverConfig;
  675. wsUrl = caneraConfig.getWsUrl();
  676. wsUrls = caneraConfig.getWsUrls();
  677. httpUrl = caneraConfig.getHttpUrl();
  678. httpUrls = caneraConfig.getHttpUrls();
  679. recordUrl = caneraConfig.getRecordUrl();
  680. hkUrl = caneraConfig.getHkUrl();
  681. host = caneraConfig.getHost();
  682. appKey = caneraConfig.getAppKey();
  683. appSecret = caneraConfig.getAppSecret();
  684. rtmpUrl = caneraConfig.getRtmpUrl();
  685. }
  686. /**
  687. * 定时任务参数flv文件
  688. *
  689. * @throws IOException
  690. * @throws InterruptedException
  691. */
  692. public void deleteFlv() throws IOException, InterruptedException {
  693. SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
  694. Date date = new Date();
  695. Calendar calendar = new GregorianCalendar();
  696. calendar.setTime(date);
  697. calendar.add(Calendar.DATE, -1); //把日期往后增加一天,整数 往后推,负数往前移动
  698. date = calendar.getTime(); //这个时间就是日期往后推一天的结果
  699. String path = BaseConfig.getProfile() + "/flv/" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date);
  700. File file = new File(path);
  701. if (file.exists()) {
  702. List<String> rspList = new ArrayList<String>();
  703. Process proc = Runtime.getRuntime().exec("/bin/bash", null, null);
  704. BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
  705. PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
  706. String commit = " rm -rf " + path;
  707. List<String> commands = new ArrayList<>();
  708. // 删除
  709. commands.add(commit);
  710. log.info("删除昨天的录像视频命令:{}", commands);
  711. for (String line : commands) {
  712. out.println(line);
  713. }
  714. out.println("exit");// 这个命令必须执行,否则in流不结束。
  715. String rspLine = "";
  716. while ((rspLine = in.readLine()) != null) {
  717. System.out.println(rspLine);
  718. rspList.add(rspLine);
  719. }
  720. int i = proc.waitFor();
  721. log.info("执行结果:{}", i);
  722. in.close();
  723. out.close();
  724. proc.destroy();
  725. }
  726. }
  727. /**
  728. * 定时任务:删除超过配置时长的录制视频
  729. *
  730. * @throws IOException
  731. * @throws InterruptedException
  732. */
  733. public void deleteFlvExceed() throws IOException, InterruptedException, ParseException {
  734. //字典中设置的值
  735. List<SysDictData> sysCameraRecordTime = dictDataMapper.selectDictDataByType("sys_camera_record_time");
  736. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
  737. Date date = new Date();
  738. Calendar calendar = new GregorianCalendar();
  739. calendar.setTime(date);
  740. //正数,日期天数加
  741. //负数,日期天数减 提前45天
  742. if (!ObjectUtils.isEmpty(sysCameraRecordTime)) {
  743. String dictValue = sysCameraRecordTime.get(0).getDictValue();
  744. calendar.add(Calendar.DAY_OF_YEAR, Integer.parseInt("-" + dictValue));
  745. } else {
  746. calendar.add(Calendar.DAY_OF_YEAR, -45);
  747. }
  748. date = calendar.getTime();
  749. //遍历每个进行视频录制的摄像头
  750. File file = new File(transcribeFilePath);
  751. log.info("file.Name()======================================" + file.getName());
  752. log.info("file.exists()======================================" + file.exists());
  753. if (file.exists() && file.isDirectory()) {
  754. //获取文件夹中所有的子文件夹和文件
  755. File[] files = file.listFiles();
  756. if (!ObjectUtils.isEmpty(files) && files.length > 0) {
  757. for (File file1 : files) {
  758. // file1=/opt/streams/record/flv/34020000001320000167
  759. log.info("file1.Name()======================================" + file1.getName());
  760. if (file1.exists() && file1.isDirectory()) {
  761. //相机文件
  762. File[] fs = file1.listFiles();
  763. if (!ObjectUtils.isEmpty(fs) && fs.length > 0) {
  764. for (File f : fs) {
  765. // f=/opt/streams/record/flv/34020000001320000167/20230328_192033_192037-91509173-cd5a-11ed-8a42-fa163e4e1e9f.flv
  766. //fName=20230328_192033_192037-91509173-cd5a-11ed-8a42-fa163e4e1e9f.flv
  767. String fName = f.getName();
  768. log.info("fName======================================" + fName);
  769. String[] split = fName.split("_");
  770. if (split.length > 0) {
  771. //20230328
  772. String s = split[0];
  773. Date parse = sdf.parse(s);
  774. long fTime = parse.getTime();
  775. long dateTime = date.getTime();
  776. //删除过期文件
  777. if (fTime < dateTime) {
  778. f.delete();
  779. }
  780. }
  781. }
  782. }
  783. }
  784. }
  785. }
  786. }
  787. }
  788. public static File[] getCurFilesList(String filePath) {
  789. File path = new File(filePath);
  790. File[] listFiles = path.listFiles(new FileFilter() {
  791. @Override
  792. public boolean accept(File pathname) {
  793. if (pathname.isFile()) {
  794. return true;
  795. } else {
  796. return false;
  797. }
  798. }
  799. });
  800. return listFiles;
  801. }
  802. public static void execute(String command) {
  803. try {
  804. ProcessBuilder process = new ProcessBuilder(command);
  805. process.inheritIO().start().waitFor();
  806. } catch (Exception e) {
  807. e.printStackTrace();
  808. }
  809. }
  810. /**
  811. * web页面视频回放接口
  812. *
  813. * @param code
  814. * @param startTm
  815. * @param endTm
  816. * @return
  817. */
  818. public static String getRecordList(String code, Date startTm, Date endTm, String channel) {
  819. PlaybackVo playbackVo = new PlaybackVo();
  820. playbackVo.setCameraIndexCode(code);
  821. // 将 Date 转换为 Instant
  822. Instant startInstant = startTm.toInstant();
  823. Instant endInstant = endTm.toInstant();
  824. // 将 Instant 转换为 OffsetDateTime
  825. OffsetDateTime startOffsetDateTime = startInstant.atOffset(ZoneOffset.UTC);
  826. OffsetDateTime endOffsetDateTime = endInstant.atOffset(ZoneOffset.UTC);
  827. // 格式化为字符串
  828. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
  829. String formattedStartTime = startOffsetDateTime.format(formatter);
  830. String formattedEndTime = endOffsetDateTime.format(formatter);
  831. // 将格式化后的时间设置到 playbackVo 中
  832. playbackVo.setBeginTime(formattedStartTime);
  833. playbackVo.setEndTime(formattedEndTime);
  834. playbackVo.setProtocol("rtsp");
  835. playbackVo.setExpand("streamform=rtp");
  836. //对象转换json字符串
  837. String body = JSONObject.toJSONString(playbackVo);
  838. //调用天网接口
  839. String playbackURLs = getPreviewURLs("/api/video/v1/cameras/playbackURLs", body);
  840. if (StringUtils.isEmpty(playbackURLs)) {
  841. return "调用天网接口失败";
  842. }
  843. JSONObject outJson = (JSONObject) JSONObject.parse(playbackURLs);
  844. log.info("outJson-------->" + outJson);
  845. if ("0".equals(outJson.getString("code"))) {
  846. JSONObject data = outJson.getJSONObject("data");
  847. String urls = data.getString("url");
  848. log.info("urls----------->" + urls);
  849. try {
  850. TimeUnit.SECONDS.sleep(3);
  851. String msg = HttpUtils.sendGet(httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/" + channel + "&save=0");
  852. log.info("msg---------->" + msg);
  853. } catch (InterruptedException e) {
  854. e.printStackTrace();
  855. }
  856. return getPlayFlv(code, channel, true, "master");
  857. } else {
  858. return "调用天网接口失败";
  859. }
  860. // return filterRecordList(channel, startTm, endTm, filePath, recordUrl + "profile/");
  861. }
  862. /**
  863. * HTTP流转RTSP流
  864. */
  865. public String streamConversion(String code) {
  866. ExecutorService executor = Executors.newSingleThreadExecutor();
  867. Callable<String> task = new Callable<String>() {
  868. @Override
  869. public String call() throws Exception {
  870. // 执行网络请求...
  871. log.info(ffmpegPath + " -re -i /opt/streams/map/70b0bd685b0d4df1b4faf74ff5c1e7fd.mp4 -c:v copy -c:a copy -f flv rtmp://10.48.36.47:1935/live/70b0bd685b0d4df1b4faf74ff5c1e7fd");
  872. cmdCameraUtil.cmd(ffmpegPath + " -re -i /opt/streams/map/" + code + ".mp4 -c:v copy -c:a copy -f flv " + rtmpUrl + "/live/" + code);
  873. return "Response";
  874. }
  875. };
  876. try {
  877. String result = executor.submit(task).get(5, TimeUnit.SECONDS); // 设置5秒超时时间
  878. System.out.println("Response: " + result);
  879. } catch (InterruptedException | ExecutionException | TimeoutException e) {
  880. // 请求超时处理逻辑
  881. System.out.println("Request timeout");
  882. }
  883. executor.shutdown();
  884. return bakUrlRtsp + "/live/" + code + ".flv";
  885. }
  886. /**
  887. * RTSP流视频压缩
  888. */
  889. public void videoCompression(String code) {
  890. // 执行网络请求...
  891. /**
  892. * /usr/bin/ffmpeg -i /opt/streams/map/70b0bd685b0d4df1b4faf74ff5c1e7fd.mp4 -c:v libx264 -s 640x480 -c:a aac -ar 44100 /opt/streams/compress/70b0bd685b0d4df1b4faf74ff5c1e7fd.mp4
  893. */
  894. log.info(ffmpegPath + " -i /opt/streams/map/" + code + ".mp4 -c:v libx264 -s 640x480 -c:a aac -ar 44100 /opt/streams/compress/" + code + ".mp4");
  895. cmdCameraUtil.cmd(ffmpegPath + " -i /opt/streams/map/" + code + ".mp4 -c:v libx264 -s 640x480 -c:a aac -ar 44100 /opt/streams/compress/" + code + ".mp4");
  896. }
  897. public static List<Map<String, Object>> filterRecordList(String channel,
  898. Date startTm,
  899. Date endTm,
  900. String mappingUrl,
  901. String wUrl) {
  902. List<Map<String, Object>> rmaps = new ArrayList<>();
  903. if (StringUtils.isBlank(channel)
  904. || ObjectUtils.isEmpty(startTm)
  905. || ObjectUtils.isEmpty(endTm)) {
  906. return null;
  907. }
  908. Map<Date, Map<String, Object>> m = new HashMap<>();
  909. // 调用视频服务返回参数
  910. String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTm);
  911. String endTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endTm);
  912. String param = "channel=" + channel + "&startTime=" + startTime + "&endTime=" + endTime;
  913. // /api/record/flv/list
  914. String s = HttpUtils.sendGet(webUrl + "/recordpro/api/list", param);
  915. // 视频拼接
  916. if (!StringUtils.isBlank(s) || "null".equals(s)) {
  917. List<Map<String, Object>> maps = JSON.parseArray(s, Map.class);
  918. if (ObjectUtils.isEmpty(maps)) {
  919. return null;
  920. }
  921. for (Map<String, Object> map : maps) {
  922. Object path = map.get("Path");
  923. Object size = map.get("Size");
  924. Object duration = map.get("Duration");
  925. if (!ObjectUtils.isEmpty(path)) {
  926. String s1 = path.toString();
  927. String substring = s1.substring(s1.lastIndexOf("/") + 1, s1.length());
  928. String substring1 = substring.substring(0, substring.indexOf("-"));
  929. String[] s2 = substring1.split("_");
  930. if (!ObjectUtils.isEmpty(s2)) {
  931. Map<String, Object> mo = new HashMap<>();
  932. String s3 = s2[0] + s2[1];
  933. String s4 = s2[0] + s2[2];
  934. Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s3);
  935. if (s2[1].startsWith("23") && s2[2].startsWith("00")) {
  936. sdate = DateUtils.addDays(sdate, -1);
  937. }
  938. Date edate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s4);
  939. mo.put("startTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, sdate));
  940. mo.put("entTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, edate));
  941. mo.put("url", wUrl + path.toString());
  942. mo.put("path", mappingUrl + path.toString());
  943. mo.put("fileName", substring);
  944. mo.put("size", size);
  945. mo.put("duration", duration);
  946. /* sdate |startTm| edate |endTm| */
  947. if (startTm.compareTo(sdate) >= 0
  948. && startTm.compareTo(edate) <= 0
  949. && endTm.compareTo(edate) >= 0) {
  950. m.put(sdate, mo);
  951. /* |startTm| sdate edate |endTm| */
  952. } else if (startTm.compareTo(sdate) <= 0 && endTm.compareTo(edate) >= 0) {
  953. m.put(sdate, mo);
  954. /* |startTm| sdate |endTm| edate */
  955. } else if (startTm.compareTo(sdate) <= 0
  956. && endTm.compareTo(sdate) >= 0
  957. && endTm.compareTo(edate) <= 0) {
  958. m.put(sdate, mo);
  959. /* sdate |startTm| |endTm| edate */
  960. } else if (startTm.compareTo(sdate) >= 0 && endTm.compareTo(edate) <= 0) {
  961. m.put(sdate, mo);
  962. }
  963. }
  964. }
  965. }
  966. }
  967. if (!ObjectUtils.isEmpty(m) && m.size() > 0) {
  968. Set<Date> dates = m.keySet();
  969. // 排序
  970. dates.stream().parallel().collect(Collectors.toList()).stream().sorted().forEach(d -> {
  971. rmaps.add(m.get(d));
  972. });
  973. log.info("rmaps:{}", rmaps);
  974. return rmaps;
  975. }
  976. return null;
  977. }
  978. /**
  979. * 机车状态修改
  980. */
  981. public void heartbeat() {
  982. log.info("机车状态修改---------------执行了");
  983. List<BaseTerminal> list = baseTerminalService.list();
  984. for (BaseTerminal baseTerminal : list) {
  985. QueryWrapper<BaseTerminalLog> wrapper = new QueryWrapper<>();
  986. wrapper.eq("terminal_code", baseTerminal.getTerminalCode());
  987. wrapper.orderByDesc("create_time");
  988. wrapper.last("limit 1");
  989. BaseTerminalLog baseTerminalLog = baseTerminalLogService.getOne(wrapper);
  990. if (ObjectUtils.isEmpty(baseTerminalLog)) {
  991. baseTerminal.setStatus(2);
  992. baseTerminalService.updateById(baseTerminal);
  993. } else {
  994. List<SysDictData> heartbeat = dictTypeService.selectDictDataByType("heartbeat");
  995. long timeNow = System.currentTimeMillis();
  996. long createTime = baseTerminalLog.getCreateTime().getTime();
  997. int times = Integer.parseInt(heartbeat.get(0).getDictValue());
  998. long thereHourMillis = 60 * 1000 * 3 * times;
  999. long timeNew = timeNow - thereHourMillis;
  1000. if (timeNew > createTime) {
  1001. baseTerminal.setStatus(2);
  1002. baseTerminalService.updateById(baseTerminal);
  1003. } else {
  1004. baseTerminal.setStatus(1);
  1005. baseTerminalService.updateById(baseTerminal);
  1006. }
  1007. }
  1008. }
  1009. }
  1010. public static String getCameraPreviewURL() {
  1011. /**
  1012. * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
  1013. */
  1014. ArtemisConfig.host = host; // 平台的ip端口
  1015. ArtemisConfig.appKey = appKey; // 密钥appkey
  1016. ArtemisConfig.appSecret = appSecret;// 密钥appSecret
  1017. /**
  1018. * STEP2:设置OpenAPI接口的上下文
  1019. */
  1020. final String ARTEMIS_PATH = "/artemis";
  1021. /**
  1022. * STEP3:设置接口的URI地址
  1023. */
  1024. final String previewURLsApi = ARTEMIS_PATH+"/api/resource/v1/camera/advance/cameraList";
  1025. Map<String, String> path = new HashMap<String, String>(2) {
  1026. {
  1027. put("https://", previewURLsApi);//根据现场环境部署确认是http还是https
  1028. }
  1029. };
  1030. /**
  1031. * STEP4:设置参数提交方式
  1032. */
  1033. String contentType = "application/json";
  1034. /**
  1035. * STEP5:组装请求参数
  1036. */
  1037. JSONObject jsonBody = new JSONObject();
  1038. jsonBody.put("pageNo", 1);
  1039. jsonBody.put("pageSize", 999);
  1040. String body = jsonBody.toJSONString();
  1041. /**
  1042. * STEP6:调用接口
  1043. */
  1044. String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);// post请求application/json类型参数
  1045. log.info("GetCameraPreviewURL----->"+result);
  1046. return result;
  1047. }
  1048. /**
  1049. * 天网接口
  1050. *
  1051. * @return
  1052. */
  1053. public static String getPreviewURLs(String url, String body) {
  1054. long begin = System.currentTimeMillis();
  1055. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
  1056. log.info("天网接口请求时间: " + sdf.format(new Date(begin)));
  1057. /**
  1058. * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数.
  1059. */
  1060. ArtemisConfig.host = host; // 平台的ip端口
  1061. ArtemisConfig.appKey = appKey; // 密钥appkey
  1062. ArtemisConfig.appSecret = appSecret;// 密钥appSecret
  1063. /**
  1064. * STEP2:设置OpenAPI接口的上下文
  1065. */
  1066. final String ARTEMIS_PATH = "/artemis";
  1067. /**
  1068. * STEP3:设置接口的URI地址
  1069. */
  1070. final String previewURLsApi = ARTEMIS_PATH + url;
  1071. log.info("天网url:{}" + previewURLsApi);
  1072. Map<String, String> path = new HashMap<String, String>(2) {
  1073. {
  1074. put("https://", previewURLsApi);//根据现场环境部署确认是http还是https
  1075. }
  1076. };
  1077. /**
  1078. * STEP4:设置参数提交方式
  1079. */
  1080. String contentType = "application/json";
  1081. /**
  1082. * STEP6:调用接口
  1083. */
  1084. String result = null;// post请求application/json类型参数
  1085. try {
  1086. result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);
  1087. } catch (Exception e) {
  1088. log.info("天网异常信息----->" + e.getMessage());
  1089. }
  1090. log.info("GetCameraPreviewURL----->" + result);
  1091. long end = System.currentTimeMillis();
  1092. log.info("接受天网接口相应时间: " + sdf.format(new Date(end)));
  1093. log.info("天网接口请求用时时间:" + (end - begin) + "毫秒");
  1094. return result;
  1095. }
  1096. /**
  1097. * 车载终端实时流调用的远程天网接口
  1098. *
  1099. * @param camerasVo
  1100. */
  1101. public String apiPreviewURLs(CamerasVo camerasVo) {
  1102. long begin = System.currentTimeMillis();
  1103. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
  1104. StringBuilder stringBuilder = new StringBuilder();
  1105. /**
  1106. * jsonBody.put("cameraIndexCode", "01ea43e6676f4e47bd6c5cd9e02aa006");
  1107. * jsonBody.put("streamType", 0);
  1108. * jsonBody.put("protocol","rtsp");
  1109. * jsonBody.put("transmode", 1);
  1110. * jsonBody.put("expand","streamform=rtp");
  1111. */
  1112. camerasVo.setStreamType(0);
  1113. camerasVo.setProtocol("rtsp");
  1114. camerasVo.setTransmode(0);
  1115. camerasVo.setExpand("streamform=rtp");
  1116. String body = JSONObject.toJSONString(camerasVo);
  1117. String previewURLs = getPreviewURLs("/api/video/v1/cameras/previewURLs", body);
  1118. log.info("-------------------------------->>>>>previewURLs" + previewURLs);
  1119. log.info("天网接口请求参数:{}"+camerasVo);
  1120. if (StringUtils.isEmpty(previewURLs)) {
  1121. log.info("天网接口异常");
  1122. return "天网接口异常";
  1123. } else {
  1124. long end = System.currentTimeMillis();
  1125. JSONObject outJson = JSONObject.parse(previewURLs);
  1126. // stringBuilder.append("测试结果:" + ("0".equals(outJson.getString("code")) ? "成功" : "失败") + "\t");
  1127. // stringBuilder.append("调用时间:" + sdf.format(new Date(begin)) + "\t");
  1128. // stringBuilder.append("数据返回时间:" + sdf.format(new Date(end)) + "\t");
  1129. // stringBuilder.append("延迟:" + (end - begin) + "毫秒");
  1130. stringBuilder.append("结果:"+previewURLs);
  1131. return stringBuilder.toString();
  1132. }
  1133. }
  1134. public String stopStream(String cameraIndexCode, String channel) {
  1135. try {
  1136. //http://10.48.36.47:9080/api/gateway/stop?stream=0235538f5ec241abad7c29cb423f16bb/1
  1137. log.info("code-----1111----->" + httpUrl + "/api/gateway/stop?stream=" + cameraIndexCode + "/" + channel + "/h264_720");
  1138. String code = HttpClientUtil.getURL(httpUrl + "/api/gateway/stop?stream=" + cameraIndexCode + "/" + channel + "/h264_720");
  1139. log.info("code---111111------->" + code);
  1140. return code;
  1141. } catch (Exception e) {
  1142. e.printStackTrace();
  1143. }
  1144. return null;
  1145. }
  1146. public String hostStopStream(String straem) {
  1147. try {
  1148. //http://10.48.36.47:9080/api/gateway/stop?stream=0235538f5ec241abad7c29cb423f16bb/1
  1149. log.info("code-----1111----->" + httpUrl + "/api/gateway/stop?stream=" + straem);
  1150. String code = HttpClientUtil.getURL(httpUrl + "/api/gateway/stop?stream=" + straem);
  1151. log.info("code---111111------->" + code);
  1152. return code;
  1153. } catch (Exception e) {
  1154. e.printStackTrace();
  1155. }
  1156. return null;
  1157. }
  1158. /**
  1159. * web页面实时流调用的远程天网接口
  1160. *
  1161. * @param camerasVo
  1162. * @param channel
  1163. */
  1164. public static String previewURLs(CamerasVo camerasVo, String channel,String url) {
  1165. /**
  1166. * jsonBody.put("cameraIndexCode", "01ea43e6676f4e47bd6c5cd9e02aa006");
  1167. * jsonBody.put("streamType", 0);
  1168. * jsonBody.put("protocol","rtsp");
  1169. * jsonBody.put("transmode", 1);
  1170. * jsonBody.put("expand","streamform=rtp");
  1171. */
  1172. camerasVo.setStreamType(0);
  1173. camerasVo.setProtocol("rtsp");
  1174. camerasVo.setTransmode(0);
  1175. camerasVo.setExpand("streamform=rtp");
  1176. String body = JSONObject.toJSONString(camerasVo);
  1177. String previewURLs = getPreviewURLs("/api/video/v1/cameras/previewURLs", body);
  1178. if (StringUtils.isEmpty(previewURLs)) {
  1179. return "天网无视频-" + camerasVo.getCameraIndexCode();
  1180. }
  1181. log.info("-------------------------------->>>>>previewURLs" + previewURLs);
  1182. log.info("-------------------------------->>>>>天网接口参数:{}" + camerasVo);
  1183. JSONObject outJson = JSONObject.parse(previewURLs);
  1184. if ("0".equals(outJson.getString("code"))) {
  1185. log.info("outJson----->" + outJson);
  1186. JSONObject data = outJson.getJSONObject("data");
  1187. String urls = data.getString("url");
  1188. log.info("urls----->" + urls);
  1189. try {
  1190. log.info("httpUrl---------->" + url + "/rtsp/api/pull?target=" + urls + "&streamPath=" + camerasVo.getCameraIndexCode() + "/" + channel + "&save=0");
  1191. String msg = HttpUtils.sendGet(url + "/rtsp/api/pull?target=" + urls + "&streamPath=" + camerasVo.getCameraIndexCode() + "/" + channel + "&save=0");
  1192. log.info("msg---------->" + msg);
  1193. log.info("boolen--------------" + msg.contains("ok"));
  1194. if (!msg.contains("ok")) {
  1195. return "暂无视频-" + camerasVo.getCameraIndexCode();
  1196. }
  1197. rc.setCacheObject(camerasVo.getCameraIndexCode(),url);
  1198. return "ok";
  1199. } catch (Exception e) {
  1200. return "暂无视频-" + camerasVo.getCameraIndexCode();
  1201. }
  1202. } else {
  1203. return "天网无视频-" + camerasVo.getCameraIndexCode();
  1204. }
  1205. }
  1206. /**
  1207. * 报警回放本地测试
  1208. * 从天网拉回放流,然后根据url把流下载下来变成文件,然后进行视频压缩
  1209. *
  1210. * @param list
  1211. * @param alarmPlayTimeValue
  1212. */
  1213. public String playbackURLs(String code, String frontValue, String laterValue) {
  1214. try {
  1215. log.info("--------------->playbackURLs-----异步开始-");
  1216. log.info("frontValue------------->" + frontValue);
  1217. log.info("laterValue------------->" + laterValue);
  1218. // TimeUnit.SECONDS.sleep(65 * Integer.parseInt(laterValue));
  1219. log.info("--------------->playbackURLs");
  1220. PlaybackVo playbackVo = new PlaybackVo();
  1221. playbackVo.setCameraIndexCode(code);
  1222. // 获取当前时间
  1223. OffsetDateTime currentTime = OffsetDateTime.now();
  1224. log.info("currentTime------------->" + currentTime);
  1225. // 获取报警前的时间
  1226. OffsetDateTime beforeTenMinutes = currentTime.minusMinutes(Long.parseLong(frontValue));
  1227. log.info("beforeTenMinutes------------->" + beforeTenMinutes);
  1228. // 获取报警后的时间
  1229. OffsetDateTime afterTenMinutes = currentTime.plusMinutes(Long.parseLong("0"));
  1230. log.info("afterTenMinutes------------->" + afterTenMinutes);
  1231. // 格式化时间
  1232. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
  1233. playbackVo.setBeginTime(beforeTenMinutes.format(formatter));
  1234. log.info("playbackVo.getBeginTime()------------->" + playbackVo.getBeginTime());
  1235. playbackVo.setEndTime(afterTenMinutes.format(formatter));
  1236. log.info("playbackVo.getEndTime()------------->" + playbackVo.getEndTime());
  1237. // jsonBody.put("protocol","rtsp");
  1238. // jsonBody.put("expand","streamform=rtp");
  1239. playbackVo.setProtocol("rtsp");
  1240. playbackVo.setExpand("streamform=rtp");
  1241. //对象转换json字符串
  1242. String body = JSONObject.toJSONString(playbackVo);
  1243. //调用天网接口
  1244. log.info("body----->" + body);
  1245. //获取回放视频的url
  1246. String playbackURLs = getPreviewURLs("/api/video/v1/cameras/playbackURLs", body);
  1247. if (StringUtils.isEmpty(playbackURLs)) {
  1248. return "天网无视频-" + code;
  1249. }
  1250. log.info("playbackURLs----->" + playbackURLs);
  1251. JSONObject outJson = (JSONObject) JSONObject.parse(playbackURLs);
  1252. if ("0".equals(outJson.getString("code"))) {
  1253. log.info("outJson----->" + outJson);
  1254. JSONObject data = outJson.getJSONObject("data");
  1255. String urls = data.getString("url");
  1256. log.info("--------------->urls::" + urls);
  1257. //向流媒体推报警回放视频
  1258. log.info("msg---------->" + httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1259. String msg = HttpUtils.sendGet(httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1260. log.info("msg---------->" + msg);
  1261. if (!msg.equals("ok")) {
  1262. return "暂无视频-" + code;
  1263. }
  1264. /**
  1265. * //两个流媒体的个数
  1266. * //第一个是性能高的
  1267. * int urlCount = urlCount(httpUrl);
  1268. * //第二个是性能低的
  1269. * int urlCounts = urlCount(httpUrls);
  1270. * //向流媒体推报警回放视频
  1271. * if (urlCount == 0) {
  1272. * log.info("msg---------->" + httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1273. * String msg = HttpUtils.sendGet(httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1274. * log.info("msg---------->" + msg);
  1275. * if (!msg.equals("ok")) {
  1276. * return "暂无视频-" + code;
  1277. * }
  1278. * return "master";
  1279. * } else {
  1280. * if (urlCounts * 2 > urlCount) {
  1281. * log.info("msg---------->" + httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1282. * String msg = HttpUtils.sendGet(httpUrl + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1283. * log.info("msg---------->" + msg);
  1284. * if (!msg.equals("ok")) {
  1285. * return "暂无视频-" + code;
  1286. * }
  1287. * return "master";
  1288. * } else {
  1289. * log.info("msg---------->" + httpUrls + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1290. * String msg = HttpUtils.sendGet(httpUrls + "/rtsp/api/pull?target=" + urls + "&streamPath=" + code + "/playback&save=0");
  1291. * log.info("msg---------->" + msg);
  1292. * if (!msg.equals("ok")) {
  1293. * return "暂无视频-" + code;
  1294. * }
  1295. * return "slave";
  1296. * }
  1297. * }
  1298. */
  1299. // String FilePath = "/opt/streams/map/" + code + ".mp4";
  1300. // Process process = rtspToMP4.StartRecord(ffmpegPath, urls, FilePath);
  1301. // log.info("------playbackURLs----->>>>:" + process);
  1302. // if (null != process) {
  1303. // map.put(code, process);
  1304. // }
  1305. // try {
  1306. // TimeUnit.SECONDS.sleep(204 * Integer.parseInt(alarmPlayTimeValue));
  1307. // } catch (InterruptedException e) {
  1308. // e.printStackTrace();
  1309. // }
  1310. // log.info("------videoCompression----->>>>:");
  1311. // videoCompression(code);
  1312. } else {
  1313. return "天网无视频-" + code;
  1314. }
  1315. } catch (Exception e) {
  1316. e.printStackTrace();
  1317. }
  1318. return "正常";
  1319. }
  1320. public AjaxResult stop(String id) {
  1321. if (map.containsKey(id)) {
  1322. Process process = map.get(id);
  1323. log.info("-----stop------>>>" + process);
  1324. if (null != process) {
  1325. rtspToMP4.stopRecord(process);
  1326. return AjaxResult.success();
  1327. }
  1328. }
  1329. return AjaxResult.error();
  1330. }
  1331. public static void main(String[] args) throws InterruptedException, ParseException, IOException {
  1332. // CameraUtil cameraUtil = new CameraUtil();
  1333. // cameraUtil.closeRecording();
  1334. // String s = "/opt/streams/record/flv/42010001541320001116/20230403_235506_000506-22e1523b-d170-11ed-8a42-fa163e4e1e9f.flv";
  1335. // String fileStr = s.substring(s.lastIndexOf("/") + 1, s.length());
  1336. // String pathStr = s.substring(0, s.lastIndexOf("/"));
  1337. // System.out.println(fileStr);
  1338. // System.out.println(pathStr);
  1339. String s = "20230403235512";
  1340. Date sdate = DateUtils.dateTime(DateUtils.YYYYMMDDHHMMSS, s);
  1341. sdate = DateUtils.addDays(sdate, -1);
  1342. System.out.println(DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, sdate));
  1343. }
  1344. public List<BaseCameraManagementResponse> heartbeatGetPlayFlv() {
  1345. int maxRetries = 5;
  1346. int retryCount = 0;
  1347. boolean success = false;
  1348. JSONArray streamArray = null;
  1349. List<BaseCameraManagementResponse> baseCameraManagementResponseList = new ArrayList<>();
  1350. while (!success && retryCount < maxRetries) {
  1351. try {
  1352. String data = HttpClientUtil.gets(webUrl + "/api/summary");
  1353. log.info("data------------------>" + data);
  1354. if (StringUtils.isNotEmpty(data)) {
  1355. JSONObject jsonObject = JSONObject.parseObject(data);
  1356. streamArray = jsonObject.getJSONArray("Streams");
  1357. success = true;
  1358. }
  1359. } catch (Exception e) {
  1360. // 增加重试计数
  1361. retryCount++;
  1362. }
  1363. }
  1364. for (int i = 0; i < streamArray.size(); i++) {
  1365. BaseCameraManagementResponse baseCameraManagementResponse = new BaseCameraManagementResponse();
  1366. JSONObject subObj = streamArray.getJSONObject(i);
  1367. String subValue = subObj.getString("Subscribers");
  1368. String PathValue = subObj.getString("Path");
  1369. String type = subObj.getString("Type");
  1370. String timestampString = subObj.getString("StartTime");
  1371. ZonedDateTime givenTime = ZonedDateTime.parse(timestampString);
  1372. // 当前时间
  1373. Instant currentTime = Instant.now();
  1374. // 将给定时间转换为Instant对象
  1375. Instant givenInstant = givenTime.toInstant();
  1376. // 计算时间差
  1377. Duration duration = Duration.between(givenInstant, currentTime);
  1378. //封装
  1379. // 获取小时差
  1380. baseCameraManagementResponse.setStartTime(duration.toHours() + "小时前");
  1381. baseCameraManagementResponse.setStreamPath(PathValue);
  1382. baseCameraManagementResponse.setSubscribers(subValue);
  1383. baseCameraManagementResponse.setType(type);
  1384. // 寻找第一个斜杠的位置
  1385. int slashIndex = PathValue.indexOf("/");
  1386. if (slashIndex != -1) {
  1387. BaseCameraManagementResponse response = new BaseCameraManagementResponse();
  1388. String result = PathValue.substring(0, slashIndex);
  1389. BaseCameraManagement cameraManagement = baseCameraManagementService.getOne(new LambdaQueryWrapper<BaseCameraManagement>()
  1390. .eq(BaseCameraManagement::getCameraCode, result));
  1391. if (!ObjectUtils.isEmpty(cameraManagement)) {
  1392. baseCameraManagementResponse.setCameraCode(cameraManagement.getCameraCode());
  1393. baseCameraManagementResponse.setInstallMile(cameraManagement.getInstallMile());
  1394. }
  1395. }
  1396. //取出AudioTracks
  1397. JSONArray audioJson = subObj.getJSONArray("AudioTracks");
  1398. if (audioJson != null && audioJson.size() > 0) {
  1399. for (int v = 0; v < audioJson.size(); v++) {
  1400. BaseCameraManagementResponse.AudioTracks audioTracks = new BaseCameraManagementResponse.AudioTracks();
  1401. JSONObject arrayJSONObject = audioJson.getJSONObject(v);
  1402. String name = arrayJSONObject.getString("Name");
  1403. String sampleRate = arrayJSONObject.getString("SampleRate");
  1404. String channels = arrayJSONObject.getString("Channels");
  1405. String bps = arrayJSONObject.getString("BPS");
  1406. audioTracks.setBps(bps);
  1407. audioTracks.setChannels(channels);
  1408. audioTracks.setName(name);
  1409. audioTracks.setSampleRate(sampleRate);
  1410. baseCameraManagementResponse.setAudioTracks(audioTracks);
  1411. }
  1412. }
  1413. //取出VideoTracks
  1414. JSONArray videoJson = subObj.getJSONArray("VideoTracks");
  1415. if (videoJson != null && videoJson.size() > 0) {
  1416. for (int v = 0; v < videoJson.size(); v++) {
  1417. BaseCameraManagementResponse.VideoTracks videoTracks = new BaseCameraManagementResponse.VideoTracks();
  1418. JSONObject arrayJSONObject = videoJson.getJSONObject(v);
  1419. String name = arrayJSONObject.getString("Name");
  1420. String width = arrayJSONObject.getString("Width");
  1421. String height = arrayJSONObject.getString("Height");
  1422. String resolution = width + "*" + height;
  1423. String gop = arrayJSONObject.getString("GOP");
  1424. String bps = arrayJSONObject.getString("BPS");
  1425. videoTracks.setBps(bps);
  1426. videoTracks.setGop(gop);
  1427. videoTracks.setName(name);
  1428. videoTracks.setResolution(resolution);
  1429. baseCameraManagementResponse.setVideoTracks(videoTracks);
  1430. }
  1431. }
  1432. baseCameraManagementResponseList.add(baseCameraManagementResponse);
  1433. }
  1434. return baseCameraManagementResponseList;
  1435. }
  1436. public void removePlayFlv(Integer lineDir, Integer currentMile, Integer visualDistance) {
  1437. LambdaQueryWrapper<BaseCameraManagement> wrapper = new LambdaQueryWrapper<>();
  1438. if (lineDir == 1) {
  1439. wrapper.gt(BaseCameraManagement::getEndMile, currentMile + visualDistance)
  1440. .in(BaseCameraManagement::getMonitoringDirection, 1, 3);
  1441. } else if (lineDir == 2) {
  1442. wrapper.lt(BaseCameraManagement::getBeginMile, currentMile - visualDistance)
  1443. .in(BaseCameraManagement::getMonitoringDirection, 2, 3);
  1444. }
  1445. wrapper.eq(BaseCameraManagement::getEnableOrNot, 1);
  1446. //获取应该注销的相机
  1447. List<BaseCameraManagement> list = baseCameraManagementService.list(wrapper);
  1448. ArrayList<String> codeList = new ArrayList<>();
  1449. if (!ObjectUtils.isEmpty(list)) {
  1450. for (BaseCameraManagement baseCameraManagement : list) {
  1451. codeList.add(baseCameraManagement.getCameraCode() + "/" + baseCameraManagement.getGraphicsCard());
  1452. }
  1453. }
  1454. String data = HttpUtils.sendGet(webUrl + "/api/summary");
  1455. log.info("data------------------>" + data);
  1456. ArrayList<String> arrayList = new ArrayList();
  1457. if (StringUtils.isNotEmpty(data)) {
  1458. JSONObject jsonObject = JSONObject.parseObject(data);
  1459. log.info("jsonObject------------------>" + jsonObject);
  1460. JSONArray streamArray = jsonObject.getJSONArray("Streams");
  1461. log.info("streamArray------------------>" + streamArray);
  1462. if (!ObjectUtils.isEmpty(streamArray)) {
  1463. for (int i = 0; i < streamArray.size(); i++) {
  1464. JSONObject subObj = streamArray.getJSONObject(i);
  1465. log.info("subObj------------------>" + subObj);
  1466. String subValue = subObj.getString("Subscribers");
  1467. String pathValue = subObj.getString("Path");
  1468. //从缓存取出预拉的流的集合
  1469. log.info("subValue------------------>" + subValue);
  1470. log.info("pathValue------------------>" + pathValue);
  1471. //判断主码流是否订阅者是2
  1472. if (subValue.equals("0")) {
  1473. arrayList.add(pathValue);
  1474. }
  1475. }
  1476. }
  1477. }
  1478. if (!ObjectUtils.isEmpty(codeList) && !ObjectUtils.isEmpty(arrayList)) {
  1479. codeList.retainAll(arrayList);
  1480. if (!ObjectUtils.isEmpty(codeList)) {
  1481. for (String pathValue : codeList) {
  1482. hostStopStream(pathValue);
  1483. }
  1484. }
  1485. }
  1486. }
  1487. /**
  1488. * 根据相机ID找出分组并排序
  1489. *
  1490. * @param baseCameraManagement
  1491. */
  1492. public List<BaseCameraManagement> getBaseCameraManagementList(Long id, Integer line) {
  1493. //根据ID获取当前相机的信息
  1494. BaseCameraManagement baseCameraManagement = baseCameraManagementService.getById(id);
  1495. if (!ObjectUtils.isEmpty(baseCameraManagement)) {
  1496. LambdaQueryWrapper<BaseCameraManagement> wrapper = new LambdaQueryWrapper<>();
  1497. //找出同一分组的相机
  1498. wrapper.eq(BaseCameraManagement::getGrou, baseCameraManagement.getGrou());
  1499. if (line == 1) {
  1500. wrapper.orderByAsc(BaseCameraManagement::getSort);
  1501. } else if (line == 2) {
  1502. wrapper.orderByDesc(BaseCameraManagement::getSort);
  1503. }
  1504. List<BaseCameraManagement> list = baseCameraManagementService.list(wrapper);
  1505. if (!ObjectUtils.isEmpty(list)) {
  1506. return list;
  1507. } else {
  1508. return null;
  1509. }
  1510. } else {
  1511. return null;
  1512. }
  1513. }
  1514. /**
  1515. * 根据设备id和通道ID和日期获取设备录像文件
  1516. *
  1517. * @param baseCameraManagement
  1518. */
  1519. public String getQueryRecords(String streamPath, String date) {
  1520. log.info("-----getQueryRecords------streamPath-----" + streamPath);
  1521. log.info("-----getQueryRecords-------date----" + date);
  1522. String param = "{\n" +
  1523. " \"streamPath\":\"" + streamPath + "\",\n" +
  1524. " \"date\":\"" + date + "\"\n" +
  1525. "}";
  1526. String jsonStr = HttpUtils.sendPost(httpUrl + "/recordpro/api/query/records", param);
  1527. log.info("-----getQueryRecords-------jsonStr----" + jsonStr);
  1528. JSONObject jsonObj = JSON.parseObject(jsonStr);
  1529. log.info("-----getQueryRecords-------jsonObj----" + jsonObj);
  1530. JSONArray resultArray = jsonObj.getJSONArray("result");
  1531. log.info("-----getQueryRecords-------resultArray----" + resultArray);
  1532. JSONObject resultObj = resultArray.getJSONObject(0);
  1533. log.info("-----getQueryRecords-------resultObj----" + resultObj);
  1534. String path = resultObj.getString("Path");
  1535. log.info("-----getQueryRecords-------path----" + path);
  1536. return caneraConfig.getRecordUrl() + Constants.RESOURCE_PREFIX + path;
  1537. }
  1538. /**
  1539. * 流媒体的条数
  1540. *
  1541. * @return
  1542. */
  1543. // public static int urlCount(String url) {
  1544. // long begin = System.currentTimeMillis();
  1545. // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  1546. // log.info("urlCountf方法开始时间: " + sdf.format(new Date(begin)));
  1547. // int maxRetries = 5;
  1548. // int retryCount = 0;
  1549. // int count = 0;
  1550. // boolean success = false;
  1551. // JSONArray streamArray = null;
  1552. // while (!success && retryCount < maxRetries) {
  1553. // try {
  1554. // String data = HttpClientUtil.gets(url + "/api/summary");
  1555. // log.info("data------------------>" + data);
  1556. // if (StringUtils.isNotEmpty(data)) {
  1557. // JSONObject jsonObject = JSONObject.parseObject(data);
  1558. // streamArray = jsonObject.getJSONArray("Streams");
  1559. // success = true;
  1560. // }
  1561. // } catch (Exception e) {
  1562. // log.info("Exception caught: " + e.getMessage());
  1563. // // 增加重试计数
  1564. // retryCount++;
  1565. // }
  1566. // }
  1567. // long zhong = System.currentTimeMillis();
  1568. // log.info("urlCountf方法循环时间: " + sdf.format(new Date(zhong)));
  1569. // if (!ObjectUtils.isEmpty(streamArray)) {
  1570. //// for (int i = 0; i < streamArray.size(); i++) {
  1571. //// JSONObject subObj = streamArray.getJSONObject(i);
  1572. //// String PathValue = subObj.getString("Path");
  1573. //// if (PathValue.contains("/h264_720")) {
  1574. //// count++;
  1575. //// }
  1576. //// }
  1577. // long end = System.currentTimeMillis();
  1578. // log.info("urlCountf方法结束时间: " + sdf.format(new Date(end)));
  1579. // return streamArray.size();
  1580. // } else {
  1581. // long end = System.currentTimeMillis();
  1582. // log.info("urlCountf方法结束时间: " + sdf.format(new Date(end)));
  1583. // return count;
  1584. // }
  1585. // }
  1586. }