From 418a8806dba90a2463f194da759ed6338018d7d2 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: 星期一, 28 八月 2023 16:02:28 +0800
Subject: [PATCH] 增加实时报警聚合接口all
---
/dev/null | 80 --------
ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java | 7
ard-work/src/main/resources/templates/test.html | 37 --
ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java | 1
ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java | 172 ++++++++++++++++
ard-work/src/main/resources/templates/mediaMTX.html | 283 ++++++++++++++++++++++++++++
ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java | 5
7 files changed, 469 insertions(+), 116 deletions(-)
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java b/ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java
index ae518cb..0b7e7a6 100644
--- a/ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java
+++ b/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)
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java b/ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java
index ecdb659..c4b6d45 100644
--- a/ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java
+++ b/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();
diff --git a/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java b/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java
index 4cefccd..1572fae 100644
--- a/ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java
+++ b/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]
@@ -542,9 +703,8 @@
}
//鎸夊叴瓒g偣鍘婚噸,鐒跺悗鎸夊紩瀵奸�昏緫杩涜寮曞鍏ラ槦
ardAlarmRadars = ardAlarmRadars.stream()
- .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new java.util.TreeSet<>(java.util.Comparator.comparing(ArdAlarmRadar::getName))), ArrayList::new));
- for(ArdAlarmRadar ardAlarmRadar : ardAlarmRadars)
- {
+ .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new java.util.TreeSet<>(java.util.Comparator.comparing(ArdAlarmRadar::getName))), ArrayList::new));
+ for (ArdAlarmRadar ardAlarmRadar : ardAlarmRadars) {
//閬嶅巻鎶ヨ鏁版嵁杩涜寮曞
if (StringUtils.isNull(ardAlarmRadar.getLongitude()) || StringUtils.isNull(ardAlarmRadar.getLatitude())) {
//鍧愭爣涓虹┖涓嶅紩瀵�
@@ -766,10 +926,8 @@
return " ";
}
}
- }
- catch (Exception ex)
- {
- log.error("鑾峰彇闄勮繎寮�鍚姤璀﹀紩瀵煎姛鑳藉厜鐢靛紓甯�:"+ex.getMessage());
+ } catch (Exception ex) {
+ log.error("鑾峰彇闄勮繎寮�鍚姤璀﹀紩瀵煎姛鑳藉厜鐢靛紓甯�:" + ex.getMessage());
}
return minDistanceCameraId;
}
diff --git a/ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java b/ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
index 5ea793d..2053d50 100644
--- a/ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
+++ b/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) {
diff --git a/ard-work/src/main/resources/static/js/WHEPClient.js b/ard-work/src/main/resources/static/js/WHEPClient.js
deleted file mode 100644
index f84398b..0000000
--- a/ard-work/src/main/resources/static/js/WHEPClient.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import negotiateConnectionWithClientOffer from "./negotiateConnectionWithClientOffer.js";
-/**
- * Example implementation of a client that uses WHEP to playback video over WebRTC
- *
- * https://www.ietf.org/id/draft-murillo-whep-00.html
- */
-export default class WHEPClient {
- constructor(endpoint, videoElement) {
- this.endpoint = endpoint;
- this.videoElement = videoElement;
- this.stream = new MediaStream();
- /**
- * Create a new WebRTC connection, using public STUN servers with ICE,
- * allowing the client to disover its own IP address.
- * https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols#ice
- */
- this.peerConnection = new RTCPeerConnection({
- iceServers: [
- {
- urls: "stun:stun.cloudflare.com:3478",
- },
- ],
- bundlePolicy: "max-bundle",
- });
- /** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTransceiver */
- this.peerConnection.addTransceiver("video", {
- direction: "recvonly",
- });
- this.peerConnection.addTransceiver("audio", {
- direction: "recvonly",
- });
- /**
- * When new tracks are received in the connection, store local references,
- * so that they can be added to a MediaStream, and to the <video> element.
- *
- * https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/track_event
- */
- this.peerConnection.ontrack = (event) => {
- const track = event.track;
- const currentTracks = this.stream.getTracks();
- const streamAlreadyHasVideoTrack = currentTracks.some(
- (track) => track.kind === "video"
- );
- const streamAlreadyHasAudioTrack = currentTracks.some(
- (track) => track.kind === "audio"
- );
- switch (track.kind) {
- case "video":
- if (streamAlreadyHasVideoTrack) {
- break;
- }
- this.stream.addTrack(track);
- break;
- case "audio":
- if (streamAlreadyHasAudioTrack) {
- break;
- }
- this.stream.addTrack(track);
- break;
- default:
- console.log("got unknown track " + track);
- }
- };
- this.peerConnection.addEventListener("connectionstatechange", (ev) => {
- if (this.peerConnection.connectionState !== "connected") {
- return;
- }
- if (!this.videoElement.srcObject) {
- this.videoElement.srcObject = this.stream;
- }
- });
- this.peerConnection.addEventListener("negotiationneeded", (ev) => {
- negotiateConnectionWithClientOffer(this.peerConnection, this.endpoint);
- });
- }
-}
diff --git a/ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js b/ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js
deleted file mode 100644
index 26c70b6..0000000
--- a/ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Performs the actual SDP exchange.
- *
- * 1. Constructs the client's SDP offer
- * 2. Sends the SDP offer to the server,
- * 3. Awaits the server's offer.
- *
- * SDP describes what kind of media we can send and how the server and client communicate.
- *
- * https://developer.mozilla.org/en-US/docs/Glossary/SDP
- * https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html#name-protocol-operation
- */
-export default async function negotiateConnectionWithClientOffer(
- peerConnection,
- endpoint
-) {
- /** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer */
- const offer = await peerConnection.createOffer();
- /** https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription */
- await peerConnection.setLocalDescription(offer);
- /** Wait for ICE gathering to complete */
- let ofr = await waitToCompleteICEGathering(peerConnection);
- if (!ofr) {
- throw Error("failed to gather ICE candidates for offer");
- }
- /**
- * As long as the connection is open, attempt to...
- */
- while (peerConnection.connectionState !== "closed") {
- /**
- * This response contains the server's SDP offer.
- * This specifies how the client should communicate,
- * and what kind of media client and server have negotiated to exchange.
- */
- let response = await postSDPOffer(endpoint, ofr.sdp);
- if (response.status === 201) {
- let answerSDP = await response.text();
- await peerConnection.setRemoteDescription(
- new RTCSessionDescription({ type: "answer", sdp: answerSDP })
- );
- return response.headers.get("Location");
- } else if (response.status === 405) {
- console.error("Update the URL passed into the WHIP or WHEP client");
- } else {
- const errorMessage = await response.text();
- console.error(errorMessage);
- }
- /** Limit reconnection attempts to at-most once every 5 seconds */
- await new Promise((r) => setTimeout(r, 5000));
- }
-}
-async function postSDPOffer(endpoint, data) {
- return await fetch(endpoint, {
- method: "POST",
- mode: "cors",
- headers: {
- "content-type": "application/sdp",
- },
- body: data,
- });
-}
-/**
- * Receives an RTCPeerConnection and waits until
- * the connection is initialized or a timeout passes.
- *
- * https://www.ietf.org/archive/id/draft-ietf-wish-whip-01.html#section-4.1
- * https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceGatheringState
- * https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icegatheringstatechange_event
- */
-async function waitToCompleteICEGathering(peerConnection) {
- return new Promise((resolve) => {
- /** Wait at most 1 second for ICE gathering. */
- setTimeout(function () {
- resolve(peerConnection.localDescription);
- }, 1000);
- peerConnection.onicegatheringstatechange = (ev) =>
- peerConnection.iceGatheringState === "complete" &&
- resolve(peerConnection.localDescription);
- });
-}
diff --git a/ard-work/src/main/resources/templates/mediaMTX.html b/ard-work/src/main/resources/templates/mediaMTX.html
new file mode 100644
index 0000000..2ae58db
--- /dev/null
+++ b/ard-work/src/main/resources/templates/mediaMTX.html
@@ -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>
\ No newline at end of file
diff --git a/ard-work/src/main/resources/templates/test.html b/ard-work/src/main/resources/templates/test.html
index a55bf5e..3c125fa 100644
--- a/ard-work/src/main/resources/templates/test.html
+++ b/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,15 +127,12 @@
<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">
- var cameraId, opt,optOpen,optClose, token;
+<script th:inline="javascript" th:type="module">
+
+ var cameraId, opt, optOpen, optClose, token;
window.onload = function () {
$.ajax({
url: "../hik/list",
@@ -179,7 +162,6 @@
}
}
})
-
opt = {"username": "admin", "password": "admin123"};
$.ajax({
headers: {
@@ -479,8 +461,8 @@
var defogflag = true;
$("#Defogcfg").click(function () {
cameraId = $('#select option:selected').val();
- optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
- optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
+ optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
+ optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
if (defogflag) {
$(this).text("鍏抽棴閫忛浘");
defogflag = false;
@@ -521,8 +503,8 @@
var infrareflag = true;
$("#Infrarecfg").click(function () {
cameraId = $('#select option:selected').val();
- optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
- optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
+ optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
+ optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
if (infrareflag) {
$(this).text("鍏抽棴绾㈠");
infrareflag = false;
@@ -563,8 +545,8 @@
var focusModeflag = true;
$("#FocusMode").click(function () {
cameraId = $('#select option:selected').val();
- optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
- optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
+ optOpen = {"cameraId": cameraId, "channelNum": 1, "enable": true};
+ optClose = {"cameraId": cameraId, "channelNum": 1, "enable": false};
if (focusModeflag) {
$(this).text("鑷姩鑱氱劍");
focusModeflag = false;
@@ -846,6 +828,5 @@
webRtcServer.disconnect();
}
</script>
-
</body>
</html>
\ No newline at end of file
--
Gitblit v1.9.3