‘liusuyi’
2023-08-28 418a8806dba90a2463f194da759ed6338018d7d2
增加实时报警聚合接口all
已添加1个文件
已修改5个文件
已删除2个文件
661 ■■■■ 文件已修改
ard-work/src/main/java/com/ruoyi/alarm/global/controller/GlobalAlarmController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/alarm/global/service/IGlobalAlarmService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/alarm/global/service/impl/GlobalAlarmServiceImpl.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/static/js/WHEPClient.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/templates/mediaMTX.html 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/templates/test.html 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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]
@@ -542,9 +703,8 @@
                    }
                    //按兴趣点去重,然后按引导逻辑进行引导入队
                    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;
    }
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
ÎļþÒÑɾ³ý
ard-work/src/main/resources/static/js/negotiateConnectionWithClientOffer.js
ÎļþÒÑɾ³ý
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>
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>