| ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/resources/static/js/WHEPClient.js | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/resources/templates/mediaMTX.html | ●●●●● patch | view | raw | blame | history | |
| ard-work/src/main/resources/templates/test.html | ●●●●● patch | view | raw | blame | history |
ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java
@@ -45,6 +45,13 @@ List<GlobalAlarmData> result = globalAlarmService.selectAlarmLogs(condition); return AjaxResult.success(result); } @GetMapping("/AllList") @ApiOperation(value = "实时报警聚合接口(all)",notes = "按报警刷新时间聚合查询") @ApiOperationSupport(includeParameters = {"command"},order = 1) public AjaxResult selectAlarmLogAll() { List<GlobalAlarmData> result = globalAlarmService.selectAlarmLogsAll(); return AjaxResult.success(result); } @PostMapping("/view") @ApiOperation(value = "查看报警接口",notes = "指定查看某个报警数据") @ApiOperationSupport(includeParameters = {"command","id"},order = 3) ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java
@@ -15,6 +15,7 @@ **/ public interface IGlobalAlarmService { public List<GlobalAlarmData> selectAlarmLogs(GlobalAlarmCondition condition); public List<GlobalAlarmData> selectAlarmLogsAll(); Object updateAlarmViewTime(GlobalAlarmCondition condition); public void receiveAlarm(String topic,String message); public Map<String,Object> selectAlarmLogsCount(); ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java
@@ -278,6 +278,167 @@ } } @Override public List<GlobalAlarmData> selectAlarmLogsAll() { List<GlobalAlarmData> GlobalAlarmDataList = new ArrayList<>(); String refreshTime = configService.selectConfigByKey("refreshTime"); List<ArdAlarmStealelec> ardAlarmStealelecs = ardAlarmStealelecMapper.selectListAllByCommand(refreshTime); List<GlobalAlarmData> alarmData1001 = ardAlarmStealelecs.stream() .map(ardAlarmStealelec -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmStealelec.getId()) .setName(ardAlarmStealelec.getDescribe()) .setAlarmTime(ardAlarmStealelec.getStartTime()) .setLongitude(ardAlarmStealelec.getLongitude()) .setLatitude(ardAlarmStealelec.getLatitude()) .setAltitude(ardAlarmStealelec.getAltitude()) .setCount(ardAlarmStealelec.getCount()) .setTotal(ardAlarmStealelec.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1001.size()>0) { GlobalAlarmDataList.addAll(alarmData1001); } List<ArdAlarmCamera> ardAlarmCameras = ardAlarmCameraMapper.selectListAllByCommand(refreshTime); List<GlobalAlarmData> alarmData1002= ardAlarmCameras.stream() .map(ardAlarmCamera -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmCamera.getId()) .setName(ardAlarmCamera.getCameraName()) .setAlarmTime(ardAlarmCamera.getAlarmTime()) .setLongitude(ardAlarmCamera.getLongitude()) .setLatitude(ardAlarmCamera.getLatitude()) .setCount(ardAlarmCamera.getCount()) .setTotal(ardAlarmCamera.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1002.size()>0) { GlobalAlarmDataList.addAll(alarmData1002); } List<ArdAlarmRadar> ardAlarmRadars = ardAlarmRadarMapper.selectListAllByCommand(refreshTime, "运动目标检测"); List<GlobalAlarmData> alarmData1003= ardAlarmRadars.stream() .map(ardAlarmRadar -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmRadar.getId()) .setName(ardAlarmRadar.getName()) .setAlarmTime(ardAlarmRadar.getAlarmTime()) .setLongitude(ardAlarmRadar.getLongitude()) .setLatitude(ardAlarmRadar.getLatitude()) .setCount(ardAlarmRadar.getCount()) .setTotal(ardAlarmRadar.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1003.size()>0) { GlobalAlarmDataList.addAll(alarmData1003); } ardAlarmRadars = ardAlarmRadarMapper.selectListAllByCommand(refreshTime, "热源检测"); List<GlobalAlarmData> alarmData1004= ardAlarmRadars.stream() .map(ardAlarmRadar -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmRadar.getId()) .setName(ardAlarmRadar.getName()) .setAlarmTime(ardAlarmRadar.getAlarmTime()) .setLongitude(ardAlarmRadar.getLongitude()) .setLatitude(ardAlarmRadar.getLatitude()) .setCount(ardAlarmRadar.getCount()) .setTotal(ardAlarmRadar.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1004.size()>0) { GlobalAlarmDataList.addAll(alarmData1004); } List<ArdAlarmExternal> ardAlarmExternals = ardAlarmExternalMapper.selectListAllByCommand(refreshTime, "防区报警"); List<GlobalAlarmData> alarmData1005= ardAlarmExternals.stream() .map(ardAlarmExternal -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmExternal.getId()) .setName(ardAlarmExternal.getAlarmName()) .setAlarmTime(ardAlarmExternal.getAlarmTime()) .setLongitude(ardAlarmExternal.getLongitude()) .setLatitude(ardAlarmExternal.getLatitude()) .setCount(ardAlarmExternal.getCount()) .setTotal(ardAlarmExternal.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1005.size()>0) { GlobalAlarmDataList.addAll(alarmData1005); } List<ArdAlarmAccess> ardAlarmAccesses = ardAlarmAccessMapper.selectListAllByCommand(refreshTime); List<GlobalAlarmData> alarmData1006= ardAlarmAccesses.stream() .map(ardAlarmAccess -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmAccess.getId()) .setName(ardAlarmAccess.getAcsName()) .setAlarmTime(ardAlarmAccess.getAlarmTime()) .setLongitude(ardAlarmAccess.getLongitude()) .setLatitude(ardAlarmAccess.getLatitude()) .setCount(ardAlarmAccess.getCount()) .setTotal(ardAlarmAccess.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1006.size()>0) { GlobalAlarmDataList.addAll(alarmData1006); } ardAlarmRadars = ardAlarmRadarMapper.selectListAllByCommand(refreshTime, "雷达抽油机停机"); List<GlobalAlarmData> alarmData1007= ardAlarmRadars.stream() .map(ardAlarmRadar -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmRadar.getId()) .setName(ardAlarmRadar.getName()) .setAlarmTime(ardAlarmRadar.getAlarmTime()) .setLongitude(ardAlarmRadar.getLongitude()) .setLatitude(ardAlarmRadar.getLatitude()) .setCount(ardAlarmRadar.getCount()) .setTotal(ardAlarmRadar.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1007.size()>0) { GlobalAlarmDataList.addAll(alarmData1007); } List<ArdAlarmApponekey> ardAlarmApponekeys = ardAlarmApponekeyMapper.selectListAllByCommand(refreshTime); List<GlobalAlarmData> alarmData1009= ardAlarmApponekeys.stream() .map(ardAlarmApponekey -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmApponekey.getId()) .setName(ardAlarmApponekey.getName()) .setAlarmTime(ardAlarmApponekey.getCreateTime()) .setLongitude(ardAlarmApponekey.getLongitude()) .setLatitude(ardAlarmApponekey.getLatitude()) .setCount(ardAlarmApponekey.getCount()) .setTotal(ardAlarmApponekey.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1009.size()>0) { GlobalAlarmDataList.addAll(alarmData1009); } List<ArdAlarmTube> ardAlarmTubes = ardAlarmTubeMapper.selectListAllByCommand(refreshTime); List<GlobalAlarmData> alarmData1014= ardAlarmTubes.stream() .map(ardAlarmTube -> { GlobalAlarmData globalAlarmData = new GlobalAlarmData() .setId(ardAlarmTube.getId()) .setName(ardAlarmTube.getTubeName()) .setAlarmTime(ardAlarmTube.getAlarmTime()) .setLongitude(ardAlarmTube.getLongitude()) .setLatitude(ardAlarmTube.getLatitude()) .setAltitude(ardAlarmTube.getAltitude()) .setCount(ardAlarmTube.getCount()) .setTotal(ardAlarmTube.getTotal()); return globalAlarmData; }).collect(Collectors.toList()); if(alarmData1014.size()>0) { GlobalAlarmDataList.addAll(alarmData1014); } return GlobalAlarmDataList; } /** * @描述 历史报警查询 * @参数 [command, beginTime, endTime, pageNum, pageSize] @@ -543,8 +704,7 @@ //按兴趣点去重,然后按引导逻辑进行引导入队 ardAlarmRadars = ardAlarmRadars.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new java.util.TreeSet<>(java.util.Comparator.comparing(ArdAlarmRadar::getName))), ArrayList::new)); for(ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) { for (ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) { //遍历报警数据进行引导 if (StringUtils.isNull(ardAlarmRadar.getLongitude()) || StringUtils.isNull(ardAlarmRadar.getLatitude())) { //坐标为空不引导 @@ -766,9 +926,7 @@ return " "; } } } catch (Exception ex) { } catch (Exception ex) { log.error("获取附近开启报警引导功能光电异常:"+ex.getMessage()); } return minDistanceCameraId; ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
@@ -59,7 +59,10 @@ private String index() { return "test"; } @RequestMapping("/media") private String media() { return "mediaMTX"; } @GetMapping("/list") public @ResponseBody AjaxResult list(ArdCameras ardCamera) { ard-work/src/main/resources/static/js/WHEPClient.js
File was deleted ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js
File was deleted ard-work/src/main/resources/templates/mediaMTX.html
New file @@ -0,0 +1,283 @@ <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>测试页</title> <script th:src="@{/js/jquery-3.6.4.min.js}"></script> <link rel="stylesheet" th:href="@{/css/bootstrap.css}"/> <script th:src="@{/js/bootstrap.js}"></script> <style> .video-container { display: inline-block; vertical-align: top; width: 25%; /* 六个视频平均分配一行的宽度 */ /*padding: 2px; !* 可以根据需要调整内边距 *!*/ box-sizing: border-box; } .video-container video { width: 100%; height: 100%; /*object-fit: cover; !* 视频填充容器,保持宽高比 *!*/ } </style> <body> <div> <div class="row"> <div class="video-container"> <video id="video1" muted autoplay loop controls></video> </div> <div class="video-container"> <video id="video2" muted autoplay loop controls></video> </div> <div class="video-container"> <video id="video3" muted autoplay loop controls></video> </div> <div class="video-container"> <video id="video4" muted autoplay loop controls></video> </div> <div class="video-container"> <video id="video5" muted autoplay loop controls></video> </div> </div> </div> <script th:inline="javascript"> const restartPause = 2000; const linkToIceServers = (links) => ( (links !== null) ? links.split(', ').map((link) => { const m = link.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i); const ret = { urls: [m[1]], }; if (m[3] !== undefined) { ret.username = unquoteCredential(m[3]); ret.credential = unquoteCredential(m[4]); ret.credentialType = "password"; } return ret; }) : [] ); const parseOffer = (offer) => { const ret = { iceUfrag: '', icePwd: '', medias: [], }; for (const line of offer.split('\r\n')) { if (line.startsWith('m=')) { ret.medias.push(line.slice('m='.length)); } else if (ret.iceUfrag === '' && line.startsWith('a=ice-ufrag:')) { ret.iceUfrag = line.slice('a=ice-ufrag:'.length); } else if (ret.icePwd === '' && line.startsWith('a=ice-pwd:')) { ret.icePwd = line.slice('a=ice-pwd:'.length); } } return ret; }; const generateSdpFragment = (offerData, candidates) => { const candidatesByMedia = {}; for (const candidate of candidates) { const mid = candidate.sdpMLineIndex; if (candidatesByMedia[mid] === undefined) { candidatesByMedia[mid] = []; } candidatesByMedia[mid].push(candidate); } let frag = 'a=ice-ufrag:' + offerData.iceUfrag + '\r\n' + 'a=ice-pwd:' + offerData.icePwd + '\r\n'; let mid = 0; for (const media of offerData.medias) { if (candidatesByMedia[mid] !== undefined) { frag += 'm=' + media + '\r\n' + 'a=mid:' + mid + '\r\n'; for (const candidate of candidatesByMedia[mid]) { frag += 'a=' + candidate.candidate + '\r\n'; } } mid++; } return frag; } class WHEPClient { constructor(wurl, videoId) { this.video = videoId; this.url = new URL('whep', wurl); this.pc = null; this.restartTimeout = null; this.eTag = ''; this.queuedCandidates = []; this.start(); } start() { console.log("requesting ICE servers"); fetch(this.url, { method: 'OPTIONS', }) .then((res) => this.onIceServers(res)) .catch((err) => { console.log('error: ' + err); this.scheduleRestart(); }); } onIceServers(res) { this.pc = new RTCPeerConnection({ iceServers: linkToIceServers(res.headers.get('Link')), }); const direction = "sendrecv"; this.pc.addTransceiver("video", {direction}); this.pc.addTransceiver("audio", {direction}); this.pc.onicecandidate = (evt) => this.onLocalCandidate(evt); this.pc.oniceconnectionstatechange = () => this.onConnectionState(); this.pc.ontrack = (evt) => { console.log("new track:", evt.track.kind); document.getElementById(this.video).srcObject = evt.streams[0]; }; this.pc.createOffer() .then((offer) => this.onLocalOffer(offer)); } onLocalOffer(offer) { this.offerData = parseOffer(offer.sdp); this.pc.setLocalDescription(offer); console.log("sending offer"); fetch(this.url, { method: 'POST', headers: { 'Content-Type': 'application/sdp', }, body: offer.sdp, }) .then((res) => { if (res.status !== 201) { throw new Error('bad status code'); } this.eTag = res.headers.get('E-Tag'); return res.text(); }) .then((sdp) => this.onRemoteAnswer(new RTCSessionDescription({ type: 'answer', sdp, }))) .catch((err) => { console.log('error: ' + err); this.scheduleRestart(); }); } onConnectionState() { if (this.restartTimeout !== null) { return; } console.log("peer connection state:", this.pc.iceConnectionState); switch (this.pc.iceConnectionState) { case "disconnected": this.scheduleRestart(); } } onRemoteAnswer(answer) { if (this.restartTimeout !== null) { return; } this.pc.setRemoteDescription(new RTCSessionDescription(answer)); if (this.queuedCandidates.length !== 0) { this.sendLocalCandidates(this.queuedCandidates); this.queuedCandidates = []; } } onLocalCandidate(evt) { if (this.restartTimeout !== null) { return; } if (evt.candidate !== null) { if (this.eTag === '') { this.queuedCandidates.push(evt.candidate); } else { this.sendLocalCandidates([evt.candidate]) } } } sendLocalCandidates(candidates) { fetch(this.url, { method: 'PATCH', headers: { 'Content-Type': 'application/trickle-ice-sdpfrag', 'If-Match': this.eTag, }, body: generateSdpFragment(this.offerData, candidates), }) .then((res) => { if (res.status !== 204) { throw new Error('bad status code'); } }) .catch((err) => { console.log('error: ' + err); this.scheduleRestart(); }); } scheduleRestart() { if (this.restartTimeout !== null) { return; } if (this.pc !== null) { this.pc.close(); this.pc = null; } this.restartTimeout = window.setTimeout(() => { this.restartTimeout = null; this.start(); }, restartPause); this.eTag = ''; this.queuedCandidates = []; } } let videoMap = new Map(); $('video').click(function (e) { let ID = e.target.id;//获取当前点击事件的元素 console.log(ID); if (videoMap.get(ID) != null) { closeVideo(ID, videoMap.get(ID)); } else { let client = new WHEPClient("http://127.0.0.1:8889/165/", ID); videoMap.set(ID, client); } }); function closeVideo(id) { let elementById = document.getElementById(id); elementById.pause(); videoMap.delete(id); } </script> </body> </html> ard-work/src/main/resources/templates/test.html
@@ -13,20 +13,6 @@ margin-top: 10px; } </style> <!-- 导入 ECMAScript 模块 --> <script th:type="module" th:src="@{/js/WHEPClient.js}"></script> <!-- 内联脚本块,可以使用模块中的内容 --> <script th:inline="javascript"> /*<![CDATA[*/ // 在这里使用 WHEPClient 模块中的内容 $("#play").click(function webrtcClient(){ const url = "http://127.0.0.1:8889/165"; // add the webRTC URL from your live input here console.log(url) const videoElement = document.getElementById("remote-video"); const client = new WHEPClient(url, videoElement); }) /*]]>*/ </script> <body> <div class="container"> <div class="row "> @@ -141,14 +127,11 @@ <div class="row top-buffer"> <video id="video" muted autoplay loop controls style="width: 800px; height: 100%; object-fit: fill;"/> </div> <div class="row top-buffer"> <button id="play" type="button" class="btn btn-default" >播放</button> <video id="remote-video" controls autoplay muted></video> </div> </div> </div> </div> <script th:inline="javascript"> <script th:inline="javascript" th:type="module"> var cameraId, opt,optOpen,optClose, token; window.onload = function () { $.ajax({ @@ -179,7 +162,6 @@ } } }) opt = {"username": "admin", "password": "admin123"}; $.ajax({ headers: { @@ -846,6 +828,5 @@ webRtcServer.disconnect(); } </script> </body> </html>