From bc3e9b68c66fdeeb7c49155ff46ed68d3650cc18 Mon Sep 17 00:00:00 2001
From: czt <czt18638530771@163.com>
Date: 星期一, 15 十二月 2025 18:35:33 +0800
Subject: [PATCH] 安防视频调整

---
 fzzy-igdss-web/src/main/java/com/fzzy/Application.java                                |    2 
 fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiWebrtcPlayTypeService.java |   45 +
 fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiPtzOnvifService.java       |   83 +++
 fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java |   45 +
 fzzy-igdss-web/src/main/resources/templates/security/video-list-dept.html             |  160 ++++-
 fzzy-igdss-web/src/main/resources/static/security/video-list-dept.js                  |  939 ++++++++++++++++++++++++++++++++-------
 fzzy-igdss-web/src/main/resources/static/security/video-control.js                    |    6 
 fzzy-igdss-web/src/main/resources/static/security/video-list.css                      |    2 
 /dev/null                                                                             |   51 --
 fzzy-igdss-core/pom.xml                                                               |    7 
 fzzy-igdss-core/src/main/java/com/fzzy/igds/service/DicService.java                   |    2 
 fzzy-igdss-core/src/main/java/com/fzzy/igds/service/SecCameraService.java             |    8 
 fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java            |   69 ++
 13 files changed, 1,147 insertions(+), 272 deletions(-)

diff --git a/fzzy-igdss-core/pom.xml b/fzzy-igdss-core/pom.xml
index 133f218..d24cdd1 100644
--- a/fzzy-igdss-core/pom.xml
+++ b/fzzy-igdss-core/pom.xml
@@ -54,6 +54,13 @@
             <version>1.7</version>
         </dependency>
 
+        <!--onvif鍗忚瀹炵幇-->
+        <dependency>
+            <groupId>com.ld.onvif</groupId>
+            <artifactId>ld-onvif</artifactId>
+            <version>1.0.0-RELEASE</version>
+        </dependency>
+
     </dependencies>
 
 
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiPtzOnvifService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiPtzOnvifService.java
new file mode 100644
index 0000000..9172fd4
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiPtzOnvifService.java
@@ -0,0 +1,83 @@
+package com.fzzy.igds.camera.impl;
+
+import com.fzzy.igds.camera.AbstractApiCameraService;
+import com.fzzy.igds.camera.data.ApiCameraData;
+import com.fzzy.igds.camera.data.ApiCameraResp;
+import com.fzzy.igds.constant.CameraPtzType;
+import com.ld.onvif.OnvifService;
+import com.ld.onvif.data.OnvifResult;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * ONVIF鎾斁鎺ュ彛瀹炵幇锛屽彧璐熻矗瀹炵幇PTZ鎺ュ彛
+ */
+@Component
+public class ApiPtzOnvifService extends AbstractApiCameraService {
+
+    @Resource
+    private OnvifService onvifService;
+
+    @Override
+    public String getType() {
+        return CameraPtzType.PTZ_TYPE_FZZY_ONVIF.getCode();
+    }
+
+    @Override
+    public ApiCameraResp ptzMedia(ApiCameraData apiData) {
+
+        if (StringUtils.isEmpty(apiData.getIp())
+                || null == apiData.getWebPort()
+                || StringUtils.isEmpty(apiData.getLoginId())
+                || StringUtils.isEmpty(apiData.getPwd())) {
+
+            return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "鍙傛暟涓嶅叏锛屼笉鏀寔浜戝彴鎺у埗");
+        }
+        try {
+            OnvifResult result = onvifService.ptz(apiData.getIp(),
+                    apiData.getWebPort(),
+                    apiData.getLoginId(),
+                    apiData.getPwd(),
+                    apiData.getCommand(), 0.5);
+
+            String code = result.get("code") + "";
+            if ("0".equals(code) || "200".equals(code)) {
+                code = ApiCameraResp.CODE_SUCCESS;
+            }else {
+                code = ApiCameraResp.CODE_ERROR;
+            }
+            return new ApiCameraResp(code, (String) result.get("msg"));
+        } catch (Exception e) {
+            return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "鍚庣鎵ц寮傚父" + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiCameraResp ptzPreset(ApiCameraData apiData) {
+        try {
+            if (StringUtils.isEmpty(apiData.getIp()) || null == apiData.getWebPort()
+                    || StringUtils.isEmpty(apiData.getLoginId())
+                    || StringUtils.isEmpty(apiData.getPwd())) {
+                return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "娌℃湁鑾峰彇鍒板綋鍓嶆憚鍍忔満淇℃伅锛屼笉鏀寔浜戝彴鎺у埗");
+            }
+
+            OnvifResult result = onvifService.preset(apiData.getIp(), apiData.getWebPort(),
+                    apiData.getLoginId(), apiData.getPwd(), apiData.getPreset());
+
+
+            String code = result.get("code") + "";
+            if ("0".equals(code) || "200".equals(code)) {
+                code = ApiCameraResp.CODE_SUCCESS;
+            }else {
+                code = ApiCameraResp.CODE_ERROR;
+            }
+
+            return new ApiCameraResp(code, (String) result.get("msg"));
+
+        } catch (Exception e) {
+            return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "鍚庣鎵ц寮傚父" + e.getMessage());
+        }
+    }
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiWebrtcPlayTypeService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiWebrtcPlayTypeService.java
new file mode 100644
index 0000000..313d8cd
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/camera/impl/ApiWebrtcPlayTypeService.java
@@ -0,0 +1,45 @@
+package com.fzzy.igds.camera.impl;
+
+import com.fzzy.igds.camera.AbstractApiCameraService;
+import com.fzzy.igds.camera.data.ApiCameraData;
+import com.fzzy.igds.camera.data.ApiCameraResp;
+import com.fzzy.igds.constant.CameraPlayType;
+import com.ruoyi.common.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Desc WEB-RTC
+ * @Author CZT
+ * @Date 2024/12/12 09:38
+ */
+@Slf4j
+@Component
+public class ApiWebrtcPlayTypeService extends AbstractApiCameraService {
+
+    @Override
+    public String getType() {
+        return CameraPlayType.PLAY_TYPE_WEB_RTC.getCode();
+    }
+
+    @Override
+    public ApiCameraResp getPlayAddr(ApiCameraData apiCameraDto) {
+
+        ApiCameraResp apiCameraResp = null;
+        //澶栫綉鎾斁鍦板潃
+        if (apiCameraDto.isExtNetwork()) {
+            if (StringUtils.isEmpty(apiCameraDto.getUrlOut())) {
+                return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "鎽勫儚澶存病鏈夐厤缃缃戞挱鏀惧湴鍧�");
+            }
+            apiCameraResp = new ApiCameraResp(apiCameraDto.getUrlOut());
+        } else {
+            if (StringUtils.isEmpty(apiCameraDto.getUrlIn())) {
+                return new ApiCameraResp(ApiCameraResp.CODE_ERROR, "鎽勫儚澶存病鏈夐厤缃唴缃戞挱鏀惧湴鍧�");
+            }
+
+            apiCameraResp = new ApiCameraResp(apiCameraDto.getUrlIn());
+        }
+
+        return apiCameraResp;
+    }
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/PlayType.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/PlayType.java
deleted file mode 100644
index 75ef5e5..0000000
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/PlayType.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.fzzy.igds.constant;
-
-/**
- * @Description 鎶撴媿鏂瑰紡
- * @Author CZT
- * @Date 2025/11/25 15:30
- */
-public enum PlayType {
-
-    PLAY_TYPE_DEFAULT("DEFAULT", "绯荤粺榛樿"),
-    PLAY_TYPE_WEB_RTC_DH("WEB_RTC_DH", "WEB-RTC-澶у崕"),
-    PLAY_TYPE_WEB_RTC_HIK("WEB_RTC_HIK", "WEB-RTC-娴峰悍"),
-    PLAY_TYPE_HIK_WEB_WS("HIK_WEB_WS", "娴峰悍web鏃犳彃浠�"),
-    PLAY_TYPE_DH_WEB_WS("DH_WEB_WS", "澶у崕web鏃犳彃浠�"),
-    PLAY_TYPE_VLC("VLC", "VLC鎻掍欢"),
-    HTTP_CZKJ_CH("HTTP_CZKJ_CH", "鍒涘崜瑙嗛"),
-
-    PLAY_TYPE_HIK_WEB4("HIK_WEB4", "娴峰悍web鎻掍欢"),
-    PLAY_TYPE_HIK_MEDIA("MEDIA_HIK", "娴峰悍缁煎悎瀹夐槻骞冲彴");
-
-    private String code;
-    private String name;
-
-    private PlayType(String code, String name) {
-        this.code = code;
-        this.name = name;
-    }
-
-    public String getCode() {
-        return code;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public static String getName(String code){
-        if(null == code) {
-            return null;
-        }
-        if(PlayType.PLAY_TYPE_DEFAULT.getCode().equals(code)) return PlayType.PLAY_TYPE_DEFAULT.getName();
-        if(PlayType.PLAY_TYPE_WEB_RTC_DH.getCode().equals(code)) return PlayType.PLAY_TYPE_WEB_RTC_DH.getName();
-        if(PlayType.PLAY_TYPE_WEB_RTC_HIK.getCode().equals(code)) return PlayType.PLAY_TYPE_WEB_RTC_HIK.getName();
-        if(PlayType.PLAY_TYPE_HIK_WEB_WS.getCode().equals(code)) return PlayType.PLAY_TYPE_HIK_WEB_WS.getName();
-        if(PlayType.PLAY_TYPE_DH_WEB_WS.getCode().equals(code)) return PlayType.PLAY_TYPE_DH_WEB_WS.getName();
-        if(PlayType.PLAY_TYPE_VLC.getCode().equals(code)) return PlayType.PLAY_TYPE_VLC.getName();
-        if(PlayType.PLAY_TYPE_HIK_WEB4.getCode().equals(code)) return PlayType.PLAY_TYPE_HIK_WEB4.getName();
-        if(PlayType.PLAY_TYPE_HIK_MEDIA.getCode().equals(code)) return PlayType.PLAY_TYPE_HIK_MEDIA.getName();
-        return code;
-    }
-}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/DicService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/DicService.java
index ccc74f9..c259205 100644
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/DicService.java
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/DicService.java
@@ -176,7 +176,7 @@
      */
     public List<SysDictData> triggerPlayType() {
         List<SysDictData> list = new ArrayList<SysDictData>();
-        for (PlayType w : PlayType.values()) {
+        for (CameraPlayType w : CameraPlayType.values()) {
             list.add(new SysDictData(w.getName(), w.getCode()));
         }
         return list;
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/SecCameraService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/SecCameraService.java
index 2203fde..83b5c7d 100644
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/SecCameraService.java
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/SecCameraService.java
@@ -86,14 +86,16 @@
         if (data.getChanNum() == 0) {
             data.setChanNum(1);
         }
+        data.setUpdateBy(ContextUtil.getLoginUserName());
+        data.setUpdateTime(new Date());
         if(StringUtils.isEmpty(data.getId())){
             data.setId(ContextUtil.generateId());
             data.setCreateBy(ContextUtil.getLoginUserName());
             data.setCreateTime(new Date());
+            cameraMapper.insert(data);
+        }else {
+            cameraMapper.updateById(data);
         }
-        data.setUpdateBy(ContextUtil.getLoginUserName());
-        data.setUpdateTime(new Date());
-        cameraMapper.insert(data);
     }
 
     /**
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/Application.java b/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
index ccb9ee6..9860bb1 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
@@ -24,7 +24,7 @@
  */
 @EnableRedisHttpSession
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
-@ComponentScan(basePackages = {"com.fzzy", "com.ruoyi"})
+@ComponentScan(basePackages = {"com.fzzy", "com.ruoyi", "com.ld"})
 
 @MapperScan("com.fzzy.igds.mapper")
 @EntityScan(basePackages = {"com.fzzy.*.*.domain"})
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java b/fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java
index 037aa65..4e36fa2 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java
@@ -1,5 +1,7 @@
 package com.fzzy.sys.controller.security;
 
+import com.fzzy.igds.camera.data.ApiCameraData;
+import com.fzzy.igds.camera.data.ApiCameraResp;
 import com.fzzy.igds.constant.CameraPlayType;
 import com.fzzy.igds.constant.Constant;
 import com.fzzy.igds.data.PageResponse;
@@ -7,6 +9,7 @@
 import com.fzzy.igds.domain.Dept;
 import com.fzzy.igds.service.CoreDeptService;
 import com.fzzy.igds.utils.ContextUtil;
+import com.fzzy.igds.utils.SystemUtil;
 import com.fzzy.sys.manager.security.SecManager;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import lombok.extern.slf4j.Slf4j;
@@ -18,6 +21,7 @@
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -159,6 +163,47 @@
         return viewUrl;
     }
 
+    /**
+     * 鑾峰彇瑙嗛鎾斁鍦板潃
+     *
+     * @param param
+     * @return
+     */
+    @RequestMapping("/get-media")
+    @ResponseBody
+    public ApiCameraResp getMedia(HttpServletRequest request, @RequestBody Camera param) {
+        //鑾峰彇璇锋眰鏂笽P
+        String ip = SystemUtil.getIP(request);
+        return secManager.getPlayAddr(param, ip);
+    }
+
+    /**
+     * 瑙嗛浜戝彴鎺у埗锛屾墍鏈夌被鍨嬬殑浜戝彴鎺у埗鍏ュ彛
+     *
+     * @param param 鍓嶇杞崲鐨勫弬鏁�
+     * @return 鎵ц缁撴灉
+     */
+    @RequestMapping("/ptz-media")
+    @ResponseBody
+    public ApiCameraResp ptzMedia(@RequestBody ApiCameraData param) {
+
+        //log.debug("-----浜戝彴璋冪敤-----{}",param);
+        return secManager.ptzMedia(param);
+    }
+
+
+    /**
+     * 瑙嗛浜戝彴棰勭疆浣嶈缃�
+     *
+     * @param param
+     * @return
+     */
+    @RequestMapping("/ptz-preset")
+    @ResponseBody
+    public ApiCameraResp ptzPreset(@RequestBody ApiCameraData param) {
+        return secManager.ptzPreset(param);
+    }
+
     /***
      * 瑙嗛楦熺灠鍥句腑鏇存敼鎽勫儚澶翠綅缃�
      *
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java b/fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java
index dfaa182..0c6cc2e 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java
@@ -1,5 +1,8 @@
 package com.fzzy.sys.manager.security;
 
+import com.fzzy.igds.camera.ApiCameraManager;
+import com.fzzy.igds.camera.data.ApiCameraData;
+import com.fzzy.igds.camera.data.ApiCameraResp;
 import com.fzzy.igds.constant.RespCodeEnum;
 import com.fzzy.igds.data.PageResponse;
 import com.fzzy.igds.domain.Camera;
@@ -23,6 +26,8 @@
 
     @Resource
     private SecCameraService secCameraService;
+    @Resource
+    private ApiCameraManager apiCameraManager;
 
     /**
      *
@@ -61,6 +66,70 @@
     }
 
     /**
+     * 鑾峰彇鎾斁淇℃伅
+     * @param param
+     * @return
+     */
+    public ApiCameraResp getPlayAddr(Camera param, String requireIp) {
+
+        if (StringUtils.isEmpty(param.getId())) {
+            log.error("娌℃湁鑾峰彇鍒扮洃鎺т俊鎭紒");
+            return new ApiCameraResp("ERROR", "娌℃湁鑾峰彇鍒扮洃鎺т俊鎭紒");
+        }
+
+        // 鏍规嵁id鑾峰彇璁惧淇℃伅
+        Camera camera = secCameraService.getCameraById(ContextUtil.getCompanyId(), param.getId());
+        if(null == camera){
+            log.error("缂撳瓨涓病鏈夎幏鍙栧埌鎽勫儚澶翠俊鎭�"+ param.toString());
+            return new ApiCameraResp("ERROR", "缂撳瓨涓病鏈夎幏鍙栧埌鎽勫儚澶翠俊鎭紒");
+        }
+
+        //閫氳繃缁熶竴鍏ュ彛鑾峰彇鎾斁鍦板潃
+        ApiCameraData apiCameraData = new ApiCameraData();
+        apiCameraData.setCompanyId(camera.getCompanyId());
+        apiCameraData.setDeptId(camera.getDeptId());
+        apiCameraData.setCameraId(camera.getId());
+        apiCameraData.setIp(camera.getIp());
+        apiCameraData.setCtrlPort(camera.getControlPort());
+        apiCameraData.setWebPort(camera.getWebPort());
+        apiCameraData.setPlayType(camera.getPlayType());
+        apiCameraData.setSnapType(camera.getSnapType());
+        apiCameraData.setSn(camera.getSn());
+        apiCameraData.setChannel(camera.getChanNum());
+        apiCameraData.setLoginId(camera.getLoginId());
+        apiCameraData.setPwd(camera.getPwd());
+        apiCameraData.setUrlIn(camera.getUrlIn());
+        apiCameraData.setUrlOut(camera.getUrlOut());
+        apiCameraData.setMediaAddr(camera.getMediaAddr());
+
+        //鏍规嵁鎾斁鏂瑰紡鑾峰彇瀵瑰簲鐨勬挱鏀惧湴鍧�
+        ApiCameraResp resp = apiCameraManager.getApiCameraService(camera.getPlayType()).getPlayAddr(apiCameraData);
+        return resp;
+    }
+
+    /**
+     * 浜戝彴鎺у埗
+     * @param param
+     * @return
+     */
+    public ApiCameraResp ptzMedia(ApiCameraData param) {
+
+        if(StringUtils.isEmpty(param.getCompanyId())){
+            param.setCompanyId(ContextUtil.getCompanyId());
+        }
+        return apiCameraManager.getApiCameraService(param.getPtzType()).ptzMedia(param);
+    }
+
+    /**
+     * 棰勭疆浣嶈缃�
+     * @param param
+     * @return
+     */
+    public ApiCameraResp ptzPreset(ApiCameraData param) {
+        return apiCameraManager.getApiCameraService(param.getPlayType()).ptzPreset(param);
+    }
+
+    /**
      *
      * @param params
      * @return
diff --git a/fzzy-igdss-web/src/main/resources/static/security/video-control.js b/fzzy-igdss-web/src/main/resources/static/security/video-control.js
index 849b9ba..c2b107f 100644
--- a/fzzy-igdss-web/src/main/resources/static/security/video-control.js
+++ b/fzzy-igdss-web/src/main/resources/static/security/video-control.js
@@ -32,7 +32,7 @@
 function ptzControl(command) {
    // layer.msg('寮�濮嬭皟鐢ㄤ簯鍙扳�︹��', {icon: 1, time: 1200,offset:'rb'});
     const param = getParam(command, null);
-    const url = "../../basic/security/ptz-media";
+    const url = "/security/ptz-media";
     sendControlCommand(url, param);
 }
 
@@ -41,7 +41,7 @@
     //layer.msg('寮�濮嬫墽琛屸�︹��', {icon: 1, time: 1200,offset:'rb'});
     const preset = $("#preset").val();
     const param = getParam(command, preset);
-    const url = "../../basic/security/ptz-media";
+    const url = "/security/ptz-media";
     sendControlCommand(url, param);
 }
 
@@ -49,7 +49,7 @@
 function moveStop() {
     //layer.msg('寮�濮嬭皟鐢ㄤ簯鍙扳�︹��', {icon: 1, time: 1200,offset:'rb'});
     const param = getParam(0, null);
-    const url = "../../basic/security/ptz-media";
+    const url = "/security/ptz-media";
     sendControlCommand(url, param);
 }
 
diff --git a/fzzy-igdss-web/src/main/resources/static/security/video-list-dept.js b/fzzy-igdss-web/src/main/resources/static/security/video-list-dept.js
index 3c0f2ae..2ad4c1b 100644
--- a/fzzy-igdss-web/src/main/resources/static/security/video-list-dept.js
+++ b/fzzy-igdss-web/src/main/resources/static/security/video-list-dept.js
@@ -1,99 +1,108 @@
 var layer;
 var splitWin = 1;  //鍒嗗睆鏁帮紝榛樿1鍒嗗睆
-var windowsNum = 1; //鎾斁绐楀彛涓嬫爣锛屾墜鍔ㄩ�夋嫨妯″紡涓嬩娇鐢�
+var windowsNum = null; //鎾斁绐楀彛涓嬫爣锛屾墜鍔ㄩ�夋嫨妯″紡涓嬩娇鐢�
 var timer;
 var table;
-var cameraData;
-var playUrl= null;
+var curCamera = null;
+var playCamera = null;
+var playList = {};
+
+var playUrl1 = null;
+var videoId1 = null;
+let webrtc1;
+let mediaStream1;
+var playUrl2 = null;
+var videoId2 = null;
+let webrtc2;
+let mediaStream2;
+var playUrl3 = null;
+var videoId3 = null;
+let webrtc3;
+let mediaStream3;
+var playUrl4 = null;
+var videoId4 = null;
+let webrtc4;
+let mediaStream4;
+var playUrl5 = null;
+var videoId5 = null;
+let webrtc5;
+let mediaStream5;
+var playUrl6 = null;
+var videoId6 = null;
+let webrtc6;
+let mediaStream6;
+var playUrl7 = null;
+var videoId7 = null;
+let webrtc7;
+let mediaStream7;
+var playUrl8 = null;
+var videoId8 = null;
+let webrtc8;
+let mediaStream8;
+var playUrl9 = null;
+var videoId9 = null;
+let webrtc9;
+let mediaStream9;
 
 $(function () {
     layui.use(['layer', 'table'], function () {
         layer = layui.layer;
         table = layui.table;
     });
-    
-    showPtz = function(){
-        $("#ptz-block").css("opacity",1);
-    };
-
-    disPtz = function(){
-        $("#ptz-block").css("opacity",0);
-    };
 
     //鍒濆鍖栨覆鏌撴挱鏀惧垪琛�
     renderList();
 });
 
 /**
- * 鎾斁绐楀彛閫変腑
- * @param win1 鍒嗗睆鏁�
- * @param win2 閫変腑绐楀彛鏁�
+ * 娓叉煋鐩戞帶鍒楄〃
  */
-function selectWin(win1,win2) {
-    removeSelectCss();
-    splitWin = win1;
-    windowsNum = win2;
-    addSelectCss();
-}
-
-/**
- * 鍘婚櫎閫変腑CSS
- */
-function removeSelectCss() {
-    $("#f" + splitWin + "_d" + windowsNum).removeClass("selectWin");
-}
-
-/**
- * 澧炲姞閫変腑CSS
- */
-function addSelectCss() {
-    $("#f" + splitWin + "_d" + windowsNum).addClass("selectWin");
-}
-
-/**
- * 鍒嗗睆鍒囨崲
- * @param tagNum  鍒嗗睆鏁�
- */
-function fenping(tagNum) {
-
-    //鍒囨崲鍒嗗睆鍥炬爣鍙婇〉闈�
-    if (tagNum == 1) {
-        $("#f_1").attr("src", "/img/web/group/fp_1_active.png");
-        $("#f_4").attr("src", "/img/web/group/fp_4.png");
-        $("#f_9").attr("src", "/img/web/group/fp_9.png");
-        $("#video_1").css('display', 'block');
-        $("#video_4").css('display', 'none');
-        $("#video_9").css('display', 'none');
+function renderList() {
+    if (!listCamera || listCamera.length == 0) {
+        return;
     }
-    if (tagNum == 4) {
-        $("#f_1").attr("src", "/img/web/group/fp_1.png");
-        $("#f_4").attr("src", "/img/web/group/fp_4_active.png");
-        $("#f_9").attr("src", "/img/web/group/fp_9.png");
-        $("#video_1").css('display', 'none');
-        $("#video_4").css('display', 'block');
-        $("#video_9").css('display', 'none');
-    }
-    if (tagNum == 9) {
-        $("#f_1").attr("src", "/img/web/group/fp_1.png");
-        $("#f_4").attr("src", "/img/web/group/fp_4.png");
-        $("#f_9").attr("src", "/img/web/group/fp_9_active.png");
-        $("#video_1").css('display', 'none');
-        $("#video_4").css('display', 'none');
-        $("#video_9").css('display', 'block');
-    }
+    var eleTable = document.getElementById("cameraList");
+    var _tr;
+    var _td;
+
+    $.each(listCamera, function (index, item) {
+
+        _tr = document.createElement("tr");
+        _tr.ondblclick = function () {
+            getMedia(index);
+        };
+
+        _td = document.createElement("td");
+        _td.innerText = item.name;
+        _tr.appendChild(_td);
+
+        _td = document.createElement("td");
+        _td.innerText = item.type == "01" ? "鏋満" : "鐞冩満";
+        _tr.appendChild(_td);
+
+        _td = document.createElement("td");
+        _td.innerText = item.status == "OFF" ? "绂荤嚎" : "鍦ㄧ嚎";
+        _tr.appendChild(_td);
+
+        eleTable.appendChild(_tr);
+    })
 }
 
 /**
- * 鐐瑰嚮鎾斁
- * @param cameraId
+ * 鐐瑰嚮鑾峰彇鎾斁淇℃伅
+ * @param index
  */
-play = function (data) {
-    layer.msg("姝e湪鑾峰彇鎾斁淇℃伅鈥︹��");
-    cameraData = null;
-    playUrl = null;
+function getMedia(index) {
+    if(windowsNum == null){
+        windowsNum = 1;
+    }
+    playCamera = null;
+    var camera = listCamera[index];
+    playList[windowsNum] = camera;
+
     var data = {
-        id: data.id,
-        playType: data.playType
+        id: camera.id,
+        playType: camera.playType
     };
     $.ajax({
         type: 'POST',
@@ -105,144 +114,226 @@
             if (result.code != "SUCCESS") {
                 layer.msg(result.msg);
             } else {
-                cameraData = result;
-                playUrl = result.playUrl;
-                play2();
+                playCamera = result;
+                startPlay();
             }
         },
         error: function (result) {
-            play2();
+            layer.msg(result.msg);
+            startPlay();
         }
     });
 };
 
-play2 = function () {
-
-    if (!cameraData) {
-        layer.alert("鏈幏鍙栧埌褰撳墠鎽勫儚澶存挱鏀句俊鎭紒锛�");
-        return;
+/**
+ * 鎾斁绐楀彛閫変腑
+ * @param win1 鍒嗗睆鏁�
+ * @param win2 閫変腑绐楀彛鏁�
+ */
+function selectWin(win1, win2) {
+    if (windowsNum) {
+        removeSelectCss();
     }
+    splitWin = win1;
+    windowsNum = win2;
+    addSelectCss();
 
-    if(PlayType.VLC == cameraData.playType){ //璇存槑浣跨敤鏈湴VLC鎾斁
-        vlcToPlay();
-    }
-
-    if (PlayType.PLAY_TYPE_WEB_RTC_DH == cameraData.playType
-    || PlayType.PLAY_TYPE_WEB_RTC_HIK == cameraData.playType) {//浣跨敤web-rtc鎾斁
-        webRtcToPlay();
-    }
-};
-
-
-function renderList() {
-    if (!listCamera || listCamera.length == 0) {
-        return;
-    }
-    var eleTable = document.getElementById("cameraList");
-    var _tr;
-    var _td;
-    listCamera.forEach(function (data) {
-        _tr = document.createElement("tr");
-        _tr.ondblclick = function () {
-            play(data);
-        };
-
-        _td = document.createElement("td");
-        _td.innerText = data.name;
-        _tr.appendChild(_td);
-
-        _td = document.createElement("td");
-        _td.innerText = data.type == "01" ? "鏋満" : "鐞冩満";
-        _tr.appendChild(_td);
-
-        _td = document.createElement("td");
-        _td.innerText = data.status == "OFF" ? "绂荤嚎" : "鍦ㄧ嚎";
-        _tr.appendChild(_td);
-
-        eleTable.appendChild(_tr);
-    });
+    curCamera = playList[windowsNum];
 }
-
 
 /**
- * 鎾斁杩樻槸鏆傚仠
+ * 鍘婚櫎閫変腑CSS
  */
-function playStop() {
-    var videL = $('#easyPlayer');
-    if (videL.paused) {
-        videL.play();
-    } else {
-        videL.pause();
+function removeSelectCss() {
+    const target = document.getElementById("f" + splitWin + "_d" + windowsNum);
+    target.classList.remove('active');
+}
+
+/**
+ * 澧炲姞閫変腑CSS
+ */
+function addSelectCss() {
+    const target = document.getElementById("f" + splitWin + "_d" + windowsNum);
+    target.classList.add('active');
+}
+
+/**
+ * 鍒嗗睆鍒囨崲
+ * @param tagNum  鍒嗗睆鏁�
+ */
+function fenping(tagNum) {
+    if (windowsNum) {
+        removeSelectCss();
+    }
+    playList = {};
+
+    //閲嶇疆鍒囨崲鍓嶇殑鍒嗗睆绐楀彛
+    reloadView(splitWin);
+
+    //璧嬪�煎綋鍓嶅垎灞忔暟
+    splitWin = tagNum;
+
+    //閲嶇疆鍒囨崲鍚庣殑鍒嗗睆绐楀彛
+    reloadView(splitWin);
+
+    //鍒囨崲鍒嗗睆鍥炬爣鍙婇〉闈�
+    if (tagNum === 1) {
+        $("#f_1").attr("src", "/img/web/group/fp_1_active.png");
+        $("#f_4").attr("src", "/img/web/group/fp_4.png");
+        $("#f_9").attr("src", "/img/web/group/fp_9.png");
+        $("#video_1").css('display', 'grid');
+        $("#video_4").css('display', 'none');
+        $("#video_9").css('display', 'none');
+    }
+    if (tagNum === 4) {
+        $("#f_1").attr("src", "/img/web/group/fp_1.png");
+        $("#f_4").attr("src", "/img/web/group/fp_4_active.png");
+        $("#f_9").attr("src", "/img/web/group/fp_9.png");
+        $("#video_1").css('display', 'none');
+        $("#video_4").css('display', 'grid');
+        $("#video_9").css('display', 'none');
+    }
+    if (tagNum === 9) {
+        $("#f_1").attr("src", "/img/web/group/fp_1.png");
+        $("#f_4").attr("src", "/img/web/group/fp_4.png");
+        $("#f_9").attr("src", "/img/web/group/fp_9_active.png");
+        $("#video_1").css('display', 'none');
+        $("#video_4").css('display', 'none');
+        $("#video_9").css('display', 'grid');
+    }
+    windowsNum = null;
+}
+
+/**
+ * 閲嶇疆鍒嗗睆鍓嶇殑绐楀彛
+ * @param num
+ */
+function reloadView(num) {
+    var html;
+    for (var i = 1; i <= num; i++) {
+        html = '';
+        html += '<video className="video" id="video' + num + '_' + i + ' autoPlay="" muted="" playsInline=""></video>';
+        $("#f" + num + "_d" + i).html(html);
     }
 }
-/*============= vlc瑙嗛鎾斁 ----- 寮�濮� ===============*/
-function vlcToPlay() {
-    $("#video").css('display','none');
-    $("#vlcPlayer").css('display','block');
-    var html = '';
-    html += '<object type="application/x-vlc-plugin"' +
-        'events="true" width="100%" height="100%"' +
-        'pluginspage="http://www.videolan.org"' +
-        'th:codebase="@{../../static/plugins/vlc/npapi-vlc-2.2.2.tar.xz}">' +
-        '<param name="mrl" value="' + playUrl + '"/>'+
-        '<param name="volume" value="50"/>' +
-        '<param name="autoplay" value="true"/>' +
-        '<param name="loop" value="false"/>' +
-        '<param name="fullscreen" value="true"/>' +
-        '<param name="toolbar" value="false"/>' +
-        '</object>';
-    $("#vlcPlayer").html(html);
+
+
+
+function startPlay() {
+
+    if(windowsNum > splitWin){
+        windowsNum = 1;
+    }
+    if (!playCamera) {
+        $("#f" + splitWin + "_d" + windowsNum).html("鏈幏鍙栧埌鎽勫儚澶存挱鏀句俊鎭紒锛�");
+    }
+
+    if (playCamera.playUrl) {
+        if (windowsNum === 1) {
+            playUrl1 = null;
+            mediaStream1 = null;
+            playUrl1 = playCamera.playUrl;
+            videoId1 = playCamera.cameraId;
+            webRtcToPlay1();
+        }else if (windowsNum === 2) {
+            playUrl2 = null;
+            mediaStream2 = null;
+            playUrl2 = playCamera.playUrl;
+            videoId2 = playCamera.cameraId;
+            webRtcToPlay2();
+        }else if (windowsNum === 3) {
+            playUrl3 = null;
+            mediaStream3 = null;
+            playUrl3 = playCamera.playUrl;
+            videoId3 = playCamera.cameraId;
+            webRtcToPlay3();
+        }else if (windowsNum === 4) {
+            playUrl4 = null;
+            mediaStream4 = null;
+            playUrl4 = playCamera.playUrl;
+            videoId4 = playCamera.cameraId;
+            webRtcToPlay4();
+        }else if (windowsNum === 5) {
+            playUrl5 = null;
+            mediaStream5 = null;
+            playUrl5 = playCamera.playUrl;
+            videoId5 = playCamera.cameraId;
+            webRtcToPlay5();
+        }else if (windowsNum === 6) {
+            playUrl6 = null;
+            mediaStream6 = null;
+            playUrl6 = playCamera.playUrl;
+            videoId6 = playCamera.cameraId;
+            webRtcToPlay6();
+        }else if (windowsNum === 7) {
+            playUrl7 = null;
+            mediaStream7 = null;
+            playUrl7 = playCamera.playUrl;
+            videoId7 = playCamera.cameraId;
+            webRtcToPlay7();
+        }else if (windowsNum === 8) {
+            playUrl8 = null;
+            mediaStream8 = null;
+            playUrl8 = playCamera.playUrl;
+            videoId8 = playCamera.cameraId;
+            webRtcToPlay8();
+        }else if (windowsNum === 9) {
+            playUr9 = null;
+            mediaStream9 = null;
+            playUrl9 = playCamera.playUrl;
+            videoId9 = playCamera.cameraId;
+            webRtcToPlay9();
+        }
+
+        curCamera = playList[windowsNum];
+    } else {
+        $("#f" + splitWin + "_d" + windowsNum).html("鏈幏鍙栧埌鎽勫儚澶�(" + playCamera.cameraName + ")鎾斁淇℃伅锛侊紒");
+    }
 }
 
-/*============= webRtc瑙嗛鎾斁 ----- 寮�濮� ===============*/
-
-/*============= webRtc瑙嗛鎾斁 ----- 寮�濮� ===============*/
+/*============= webRtc瑙嗛鎾斁1 ----- 寮�濮� ===============*/
 /**
  * 寮�濮嬫挱鏀�
  * @param winTag  鎾斁绐楀彛
  * @returns {Promise<void>}
  */
-async function webRtcToPlay() {
-    layer.msg("寮�濮嬪惎鍔ㄦ挱鏀锯�︹��");
-    $("#vlcPlayer").css('display','none');
-    $("#video").css('display','block');
-
-    if(playUrl){
-        mediaStream = new MediaStream();
-        $("#video")[0].srcObject = mediaStream;
-        webrtc = new RTCPeerConnection({
+async function webRtcToPlay1() {
+    if (playUrl1) {
+        mediaStream1 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream1;
+        webrtc1 = new RTCPeerConnection({
             iceServers: [{
                 urls: ["stun:stun.l.google.com:19302"]
             }],
             sdpSemantics: "unified-plan"
         });
-        webrtc.onsignalingstatechange = signalingstatechange;
+        webrtc1.onsignalingstatechange = signalingstatechange1;
 
-        webrtc.ontrack = ontrack
-        let offer = await webrtc.createOffer({
+        webrtc1.ontrack = ontrack1
+        let offer = await webrtc1.createOffer({
 
             offerToReceiveAudio: true,
             offerToReceiveVideo: true
         });
-        await webrtc.setLocalDescription(offer);
+        await webrtc1.setLocalDescription(offer);
     }
 }
 
-function ontrack(event) {
-    mediaStream.addTrack(event.track);
+function ontrack1(event) {
+    mediaStream1.addTrack(event.track);
 }
 
-async function signalingstatechange() {
-    switch (webrtc.signalingState) {
+async function signalingstatechange1() {
+    switch (webrtc1.signalingState) {
         case 'have-local-offer':
             // let uuid = $('#uuid').val();
-            let url = playUrl + "?uuid=" + cameraData.cameraId + "&channel=0";
+            let url = playUrl1 + "?uuid=" + videoId1 + "&channel=0";
             $.post(url, {
-                data: btoa(webrtc.localDescription.sdp)
+                data: btoa(webrtc1.localDescription.sdp)
             }, function (data) {
                 try {
                     console.log(data);
-                    webrtc.setRemoteDescription(new RTCSessionDescription({
+                    webrtc1.setRemoteDescription(new RTCSessionDescription({
                         type: 'answer',
                         sdp: atob(data)
                     }))
@@ -257,9 +348,519 @@
         case 'closed':
             break;
         default:
-            console.log(`unhandled signalingState is ${webrtc.signalingState}`);
+            console.log(`unhandled signalingState is ${webrtc1.signalingState}`);
             break;
     }
 }
+
 /*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
 
+/*============= webRtc瑙嗛鎾斁2 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay2() {
+    if (playUrl2) {
+        mediaStream2 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream2;
+        webrtc2 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc2.onsignalingstatechange = signalingstatechange2;
+
+        webrtc2.ontrack = ontrack2
+        let offer = await webrtc2.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc2.setLocalDescription(offer);
+    }
+}
+
+function ontrack2(event) {
+    mediaStream2.addTrack(event.track);
+}
+
+async function signalingstatechange2() {
+    switch (webrtc2.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl2 + "?uuid=" + videoId2 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc2.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc2.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc2.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+
+/*============= webRtc瑙嗛鎾斁3 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay3() {
+    if (playUrl3) {
+        mediaStream3 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream3;
+        webrtc3 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc3.onsignalingstatechange = signalingstatechange3;
+
+        webrtc3.ontrack = ontrack3
+        let offer = await webrtc3.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc3.setLocalDescription(offer);
+    }
+}
+
+function ontrack3(event) {
+    mediaStream3.addTrack(event.track);
+}
+
+async function signalingstatechange3() {
+    switch (webrtc3.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl3 + "?uuid=" + videoId3 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc3.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc3.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc3.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+
+/*============= webRtc瑙嗛鎾斁4 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay4() {
+    if (playUrl4) {
+        mediaStream4 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream4;
+        webrtc4 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc4.onsignalingstatechange = signalingstatechange4;
+
+        webrtc4.ontrack = ontrack4
+        let offer = await webrtc4.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc4.setLocalDescription(offer);
+    }
+}
+
+function ontrack4(event) {
+    mediaStream4.addTrack(event.track);
+}
+
+async function signalingstatechange4() {
+    switch (webrtc4.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl4 + "?uuid=" + videoId4 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc4.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc4.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc4.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+/*============= webRtc瑙嗛鎾斁5 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay5() {
+    if (playUrl5) {
+        mediaStream5 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream5;
+        webrtc5 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc5.onsignalingstatechange = signalingstatechange5;
+
+        webrtc5.ontrack = ontrack5
+        let offer = await webrtc4.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc5.setLocalDescription(offer);
+    }
+}
+
+function ontrack5(event) {
+    mediaStream5.addTrack(event.track);
+}
+
+async function signalingstatechange5() {
+    switch (webrtc5.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl5 + "?uuid=" + videoId5 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc5.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc5.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc5.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+/*============= webRtc瑙嗛鎾斁4 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay6() {
+    if (playUrl6) {
+        mediaStream6 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream6;
+        webrtc6 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc6.onsignalingstatechange = signalingstatechange6;
+
+        webrtc6.ontrack = ontrack6
+        let offer = await webrtc4.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc6.setLocalDescription(offer);
+    }
+}
+
+function ontrack6(event) {
+    mediaStream6.addTrack(event.track);
+}
+
+async function signalingstatechange6() {
+    switch (webrtc6.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl6 + "?uuid=" + videoId6 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc6.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc6.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc6.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+
+/*============= webRtc瑙嗛鎾斁7 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay7() {
+    if (playUrl7) {
+        mediaStream7 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream7;
+        webrtc7 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc7.onsignalingstatechange = signalingstatechange7;
+
+        webrtc7.ontrack = ontrack7
+        let offer = await webrtc7.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc7.setLocalDescription(offer);
+    }
+}
+
+function ontrack7(event) {
+    mediaStream7.addTrack(event.track);
+}
+
+async function signalingstatechange7() {
+    switch (webrtc7.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl7 + "?uuid=" + videoId7 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc7.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc7.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc7.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+
+/*============= webRtc瑙嗛鎾斁8 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay8() {
+    if (playUrl8) {
+        mediaStream8 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream8;
+        webrtc8 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrt8.onsignalingstatechange = signalingstatechange8;
+
+        webrtc8.ontrack = ontrack8
+        let offer = await webrtc8.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc8.setLocalDescription(offer);
+    }
+}
+
+function ontrack8(event) {
+    mediaStream8.addTrack(event.track);
+}
+
+async function signalingstatechange8() {
+    switch (webrtc8.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl8 + "?uuid=" + videoId8 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrtc8.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc8.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc8.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
+
+/*============= webRtc瑙嗛鎾斁9 ----- 寮�濮� ===============*/
+/**
+ * 寮�濮嬫挱鏀�
+ * @param winTag  鎾斁绐楀彛
+ * @returns {Promise<void>}
+ */
+async function webRtcToPlay9() {
+    if (playUrl9) {
+        mediaStream9 = new MediaStream();
+        $("#video" + splitWin + "_" + windowsNum)[0].srcObject = mediaStream9;
+        webrtc9 = new RTCPeerConnection({
+            iceServers: [{
+                urls: ["stun:stun.l.google.com:19302"]
+            }],
+            sdpSemantics: "unified-plan"
+        });
+        webrtc9.onsignalingstatechange = signalingstatechange9;
+
+        webrtc9.ontrack = ontrack9
+        let offer = await webrtc4.createOffer({
+
+            offerToReceiveAudio: true,
+            offerToReceiveVideo: true
+        });
+        await webrtc9.setLocalDescription(offer);
+    }
+}
+
+function ontrack9(event) {
+    mediaStream9.addTrack(event.track);
+}
+
+async function signalingstatechange9() {
+    switch (webrtc9.signalingState) {
+        case 'have-local-offer':
+            // let uuid = $('#uuid').val();
+            let url = playUrl9 + "?uuid=" + videoId9 + "&channel=0";
+            $.post(url, {
+                data: btoa(webrt9.localDescription.sdp)
+            }, function (data) {
+                try {
+                    console.log(data);
+                    webrtc9.setRemoteDescription(new RTCSessionDescription({
+                        type: 'answer',
+                        sdp: atob(data)
+                    }))
+                } catch (e) {
+                    console.warn(e);
+                }
+
+            });
+            break;
+        case 'stable':
+            break;
+        case 'closed':
+            break;
+        default:
+            console.log(`unhandled signalingState is ${webrtc9.signalingState}`);
+            break;
+    }
+}
+
+/*============= 瑙嗛鎾斁 ----- 缁撴潫 ===============*/
\ No newline at end of file
diff --git a/fzzy-igdss-web/src/main/resources/static/security/video-list.css b/fzzy-igdss-web/src/main/resources/static/security/video-list.css
index 3bef15c..50da9d7 100644
--- a/fzzy-igdss-web/src/main/resources/static/security/video-list.css
+++ b/fzzy-igdss-web/src/main/resources/static/security/video-list.css
@@ -354,7 +354,7 @@
 
 
 .sp-sxBtn{
-    /*float: left;*/
+    float: left;
 }
 
 .sp-fdBtn{
diff --git a/fzzy-igdss-web/src/main/resources/templates/security/video-list-dept.html b/fzzy-igdss-web/src/main/resources/templates/security/video-list-dept.html
index b16c4bb..72e6de3 100644
--- a/fzzy-igdss-web/src/main/resources/templates/security/video-list-dept.html
+++ b/fzzy-igdss-web/src/main/resources/templates/security/video-list-dept.html
@@ -16,6 +16,12 @@
             height: 100%;
             overflow-y: hidden;
         }
+        /* 椤甸潰鍩虹閲嶇疆 */
+        body {
+            margin: 0;
+            padding: 0;
+            background-color: #000;
+        }
 
         .layui-fluid {
             position: relative;
@@ -91,59 +97,127 @@
             color: #fff;
             cursor: pointer;
         }
-
+        .sp-table {
+            overflow: auto;
+        }
+        .sp-table::-webkit-scrollbar {
+            display: none; /* 闅愯棌婊氬姩鏉� */
+        }
         .fenping_icon {
             position: absolute;
             right: 30px;
             top: 16px;
         }
-
+        .div1 {
+            width: 100%;
+            height: 100%;
+            display: grid;
+            grid-template-columns: 1fr;
+            grid-template-rows: 1fr;
+            gap: 1px; /* 涓棿1px鐧借壊鍒嗛殧绾� */
+            background-color: #777; /* gap鍜宲adding鐨勯鑹�=鐧借壊鍒嗛殧绾� */
+            padding: 1px; /* 鍛ㄧ晫1px鐧借壊鍒嗛殧绾� */
+            box-sizing: border-box;
+            overflow: hidden;
+        }
         .div_v1 {
-            width: 99.8%;
-            height: 760px;
-            float: left;
             background-color: #333;
-
-            text-align: center;
-            color: #FFF;
-            font-size: 20px;
+            font-size: 24px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            cursor: pointer;
+            position: relative; /* 涓虹孩妗嗕吉鍏冪礌瀹氫綅 */
+            box-sizing: border-box;
+            z-index: 1; /* 鍩虹灞傜骇 */
         }
-
+        /* 閫変腑椤癸細绾㈣壊杈规锛堣鐩栬嚜韬懆杈圭殑鐧借壊鍒嗛殧绾匡級 */
+        .div_v1.active::after {
+            content: '';
+            position: absolute;
+            /* 绾㈡鑼冨洿锛氳秴鍑鸿嚜韬紝鍒氬ソ瑕嗙洊鍛ㄨ竟1px鐧界嚎 */
+            top: -1px;
+            left: -1px;
+            right: -1px;
+            bottom: -1px;
+            border: 2px solid red; /* 绾㈡瀹藉害鍙皟鏁� */
+            z-index: 2; /* 楂樹簬鑷韩锛岃鐩栫櫧绾匡紱浣庝簬鍏朵粬椤圭殑鍩虹灞傜骇锛屼笉閬尅鍏朵粬鐧界嚎 */
+            box-sizing: border-box;
+            transition: all 0.2s ease;
+        }
+        .div4 {
+            width: 100%;
+            height: 100%;
+            display: grid;
+            grid-template-columns: 1fr 1fr;
+            grid-template-rows: 1fr 1fr;
+            gap: 1px; /* 涓棿1px鐧借壊鍒嗛殧绾� */
+            background-color: #777; /* gap鍜宲adding鐨勯鑹�=鐧借壊鍒嗛殧绾� */
+            padding: 1px; /* 鍛ㄧ晫1px鐧借壊鍒嗛殧绾� */
+            box-sizing: border-box;
+            overflow: hidden;
+        }
         .div_v4 {
-            width: 49.88%;
-            height: 379.5px;
-            float: left;
             background-color: #333;
-
-            text-align: center;
-            color: #FFF;
-            font-size: 20px;
+            font-size: 24px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            cursor: pointer;
+            position: relative; /* 涓虹孩妗嗕吉鍏冪礌瀹氫綅 */
+            box-sizing: border-box;
+            z-index: 1; /* 鍩虹灞傜骇 */
         }
-
+        /* 閫変腑椤癸細绾㈣壊杈规锛堣鐩栬嚜韬懆杈圭殑鐧借壊鍒嗛殧绾匡級 */
+        .div_v4.active::after {
+            content: '';
+            position: absolute;
+            /* 绾㈡鑼冨洿锛氳秴鍑鸿嚜韬紝鍒氬ソ瑕嗙洊鍛ㄨ竟1px鐧界嚎 */
+            top: -1px;
+            left: -1px;
+            right: -1px;
+            bottom: -1px;
+            border: 2px solid red; /* 绾㈡瀹藉害鍙皟鏁� */
+            z-index: 2; /* 楂樹簬鑷韩锛岃鐩栫櫧绾匡紱浣庝簬鍏朵粬椤圭殑鍩虹灞傜骇锛屼笉閬尅鍏朵粬鐧界嚎 */
+            box-sizing: border-box;
+            transition: all 0.2s ease;
+        }
+        .div9 {
+            width: 100%;
+            height: 100%;
+            display: grid;
+            grid-template-columns: 1fr 1fr 1fr;
+            grid-template-rows: 1fr 1fr 1fr;
+            gap: 1px; /* 涓棿1px鐧借壊鍒嗛殧绾� */
+            background-color: #777; /* gap鍜宲adding鐨勯鑹�=鐧借壊鍒嗛殧绾� */
+            padding: 1px; /* 鍛ㄧ晫1px鐧借壊鍒嗛殧绾� */
+            box-sizing: border-box;
+            overflow: hidden;
+        }
         .div_v9 {
-            width: 33.22%;
-            height: 252.6px;
-            float: left;
             background-color: #333;
-
-            text-align: center;
-            color: #FFF;
-            font-size: 20px;
+            font-size: 24px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            cursor: pointer;
+            position: relative; /* 涓虹孩妗嗕吉鍏冪礌瀹氫綅 */
+            box-sizing: border-box;
+            z-index: 1; /* 鍩虹灞傜骇 */
         }
-        .bor_t_l {
-            border-top: 1px solid #777;
-            border-left: 1px solid #777;
-        }
-
-        .bor_b {
-            border-bottom: 1px solid #777;
-        }
-
-        .bor_r {
-            border-right: 1px solid #777;
-        }
-        .selectWin {
-            border: 1px solid #a52222;
+        /* 閫変腑椤癸細绾㈣壊杈规锛堣鐩栬嚜韬懆杈圭殑鐧借壊鍒嗛殧绾匡級 */
+        .div_v9.active::after {
+            content: '';
+            position: absolute;
+            /* 绾㈡鑼冨洿锛氳秴鍑鸿嚜韬紝鍒氬ソ瑕嗙洊鍛ㄨ竟1px鐧界嚎 */
+            top: -1px;
+            left: -1px;
+            right: -1px;
+            bottom: -1px;
+            border: 2px solid red; /* 绾㈡瀹藉害鍙皟鏁� */
+            z-index: 2; /* 楂樹簬鑷韩锛岃鐩栫櫧绾匡紱浣庝簬鍏朵粬椤圭殑鍩虹灞傜骇锛屼笉閬尅鍏朵粬鐧界嚎 */
+            box-sizing: border-box;
+            transition: all 0.2s ease;
         }
         .video {
             width: 100%;
@@ -171,16 +245,16 @@
                             </div>
                         </div>
 
-                        <div class="sp-tab-db" style="padding: 5px 10px 15px 10px;">
+                        <div class="sp-tab-db" style="padding: 5px 10px 15px 10px;height: 765px;">
                             <!--涓�鍒嗗睆 榛樿鏄剧ず-->
-                            <div id="video_1" class="right-videoWrap">
+                            <div id="video_1" class="div1">
                                 <div id="f1_d1" onclick="selectWin(1,1)" class="div_v1 bor_t_l bor_b bor_r">
                                     <video class="video" id="video1_1" autoplay="" muted="" playsinline=""></video>
                                 </div>
                             </div>
 
                             <!--鍥涘垎灞� 榛樿鏄剧ず-->
-                            <div id="video_4" class="right-videoWrap" style="display: none;">
+                            <div id="video_4" class="div4" style="display: none;">
                                 <div id="f4_d1" onclick="selectWin(4,1)" class="div_v4 bor_t_l">
                                     <video class="video" id="video4_1" autoplay="" muted="" playsinline=""></video>
                                 </div>
@@ -196,7 +270,7 @@
                             </div>
 
                             <!--涔濆垎灞� 榛樿闅愯棌-->
-                            <div id="video_9" class="right-videoWrap" style="display: none;">
+                            <div id="video_9" class="div9" style="display: none;">
                                 <div id="f9_d1" onclick="selectWin(9,1)" class="div_v9 bor_t_l">
                                     <video class="video" id="video9_1" autoplay="" muted="" playsinline=""></video>
                                 </div>

--
Gitblit v1.9.3