czt
4 天以前 5d0ae87e23e997960bf607340570f7bbeb7160b4
安防页面提交1
已删除2个文件
已添加15个文件
已修改6个文件
2729 ■■■■■ 文件已修改
fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/CameraPlayType.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/Dept.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/pom.xml 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/Dept.view.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/FileUploadManage.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/file/FileController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecurityManager.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/img/web/security/ca-4.png 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/img/web/security/sp-arrow.png 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/img/web/security/tit-redBg.png 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/js/plugins/drag/drag-drop.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/video-aerial.js 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/video-list.css 613 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/video-list.js 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/video-webrtc.css 579 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/video-webrtc.js 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/common/preview-img.html 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/security/video-aerial.html 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/security/video-list.html 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/security/video-webrtc.html 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/security/video.html 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/CameraPlayType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package com.fzzy.igds.constant;
import lombok.Getter;
/**
 * @Description æŠ“拍方式
 * @Author CZT
 * @Date 2024/12/10 16:48
 */
@Getter
public enum CameraPlayType {
    PLAY_TYPE_DEFAULT("DEFAULT", "系统默认"),
    PLAY_TYPE_WEB_RTC("WEB_RTC", "WEB-RTC播放"),
    PLAY_TYPE_VLC("VLC", "VLC插件"),
    PLAY_TYPE_HIK_WEB4("HIK_WEB4", "海康web插件"),
    PLAY_TYPE_HIK_MEDIA("MEDIA_HIK", "海康综合安防平台");
    private String code;
    private String name;
    private CameraPlayType(String code, String name) {
        this.code = code;
        this.name = name;
    }
    public static String getName(String code){
        if(null == code) {
            return null;
        }
        if(CameraPlayType.PLAY_TYPE_DEFAULT.getCode().equals(code)) return CameraPlayType.PLAY_TYPE_DEFAULT.getName();
        if(CameraPlayType.PLAY_TYPE_WEB_RTC.getCode().equals(code)) return CameraPlayType.PLAY_TYPE_WEB_RTC.getName();
        if(CameraPlayType.PLAY_TYPE_VLC.getCode().equals(code)) return CameraPlayType.PLAY_TYPE_VLC.getName();
        if(CameraPlayType.PLAY_TYPE_HIK_WEB4.getCode().equals(code)) return CameraPlayType.PLAY_TYPE_HIK_WEB4.getName();
        if(CameraPlayType.PLAY_TYPE_HIK_MEDIA.getCode().equals(code)) return CameraPlayType.PLAY_TYPE_HIK_MEDIA.getName();
        return code;
    }
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/Dept.java
@@ -72,12 +72,12 @@
    /**
     * --------鸟瞰图信息--------
     **/
    @Column(name = "img_id", columnDefinition = "varchar(50) COMMENT '鸟瞰图id'")
    @TableField("img_id")
    private String imgId;
    @Column(name = "img_path", columnDefinition = "varchar(100) COMMENT '鸟瞰图全路径'")
    @TableField("img_path")
    private String imgPath;
    @Column(name = "file_name", columnDefinition = "varchar(50) COMMENT '鸟瞰图名称'")
    @TableField("file_name")
    @Column(name = "img_name", columnDefinition = "varchar(50) COMMENT '鸟瞰图名称'")
    @TableField("img_name")
    private String imgName;
}
fzzy-igdss-view/pom.xml
@@ -97,40 +97,16 @@
        </dependency>
        <dependency>
            <groupId>com.bstek.dorado</groupId>
            <artifactId>dorado-uploader</artifactId>
            <version>1.0.20</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-jcl</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-jdk14</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-jexl</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
    <groupId>com.thoughtworks.paranamer</groupId>
    <artifactId>paranamer</artifactId>
    <version>2.3</version>
</dependency>
            <groupId>com.thoughtworks.paranamer</groupId>
            <artifactId>paranamer</artifactId>
            <version>2.3</version>
        </dependency>
    </dependencies>
fzzy-igdss-view/src/main/java/com/fzzy/igds/Dept.view.xml
@@ -111,9 +111,9 @@
        <Property name="label">更新人</Property>
        <Property name="readOnly">true</Property>
      </PropertyDef>
      <PropertyDef name="imgId">
      <PropertyDef name="imgPath">
        <Property></Property>
        <Property name="label">鸟瞰图id</Property>
        <Property name="label">图路径</Property>
      </PropertyDef>
      <PropertyDef name="imgName">
        <Property></Property>
@@ -122,20 +122,20 @@
    </DataType>
  </Model>
  <View layout="padding:10">
    <ClientEvent name="onClick">/**&#xD;
    <ClientEvent name="onClick">
      /**&#xD;
      * é¢„览图片&#xD;
      */&#xD;
      showImg = function(){&#xD;
      var cur = view.get(&quot;#dsMain.data:#&quot;);&#xD;
      var imgName = cur.get(&quot;imgId&quot;);&#xD;
      var imgName = cur.get(&quot;imgName&quot;);&#xD;
      if(!imgName){&#xD;
      $alert(&quot;没有上传视频信息,无法预览。&quot;);&#xD;
      $alert(&quot;没有上传鸟瞰图信息,无法预览。&quot;);&#xD;
      return;&#xD;
      }&#xD;
      var id = cur.get(&quot;id&quot;);&#xD;
      var imgPath = cur.get(&quot;imgPath&quot;);&#xD;
      &#xD;
      view.get(&quot;#iFrameImg&quot;).set(&quot;path&quot;, &quot;./basic/file/dept-img?id=&quot; + id);&#xD;
      view.get(&quot;#iFrameImg&quot;).set(&quot;path&quot;, &quot;/file/dept-img?imgPath=&quot; + imgPath);&#xD;
      view.get(&quot;#dialogImg&quot;).show();&#xD;
      &#xD;
      };</ClientEvent>
@@ -345,9 +345,18 @@
          <Container>
            <Button layoutConstraint="left">
              <Property name="action">uploadFileImg</Property>
              <Property name="caption">鸟瞰图上传...</Property>
              <Property name="caption">鸟瞰图上传</Property>
              <Property name="exClassName">btn2</Property>
              <Property name="iconClass">fa fa-cloud-upload</Property>
            </Button>
            <Label layoutConstraint="left">
              <Property name="width">10px</Property>
            </Label>
            <Button layoutConstraint="left">
              <ClientEvent name="onClick">showImg();</ClientEvent>
              <Property name="caption">鸟瞰图预览</Property>
              <Property name="exClassName">btn4</Property>
              <Property name="iconClass">fa fa-picture-o</Property>
            </Button>
          </Container>
          <Link>
@@ -453,9 +462,9 @@
      </Container>
    </CustomDropDown>
    <UploadAction id="uploadFileImg">
      <ClientEvent name="onFileUploaded">var imgId = arg.returnValue;&#xD;
      <ClientEvent name="onFileUploaded">var imgPath = arg.returnValue;&#xD;
        var data = view.get(&quot;#dsMain.data:#&quot;);&#xD;
        data.set(&quot;imgId&quot;,imgId);&#xD;
        data.set(&quot;imgPath&quot;,imgPath);&#xD;
        data.set(&quot;imgName&quot;,arg.file.name);</ClientEvent>
      <Property name="fileResolver">fileUploadManage#imgFile</Property>
      <Property name="maxFileSize">50MB</Property>
fzzy-igdss-view/src/main/java/com/fzzy/igds/FileUploadManage.java
@@ -4,6 +4,7 @@
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.fzzy.igds.service.FileService;
import com.fzzy.igds.utils.ContextUtil;
import com.ruoyi.common.config.FrameworkConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
@@ -13,7 +14,6 @@
import java.io.IOException;
import java.util.Date;
import java.util.Map;
/**
 * @Description Dorado7 é™„件上传公共管理层
@@ -38,16 +38,22 @@
    @FileResolver
    public String imgFile(UploadFile file, Map<String, Object> parameter) {
        String fileId = null;
        String filePath = null;
        try {
            String basePath = fileService.getFileSavePath("DEPT");
            fileId = "aerial-" + ContextUtil.subDeptId(null)
            //新文件名
            String fileId = "aerial-" + ContextUtil.subDeptId(null)
                    + file.getFileName().substring(
                    file.getFileName().lastIndexOf("."));
            //文件全路径
            filePath = basePath + fileId;
            //保存
            file.transferTo(new File(filePath));
            file.transferTo(new File(basePath + fileId));
            //替换后文件全路径
            filePath = filePath.replace(FrameworkConfig.getProfile(), "/profile/");
        } catch (IllegalStateException e) {
            e.printStackTrace();
@@ -55,7 +61,7 @@
            e.printStackTrace();
        }
        return fileId;
        return filePath;
    }
    /**
fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/file/FileController.java
@@ -23,7 +23,7 @@
 */
@Slf4j
@Controller
@RequestMapping("basic/file")
@RequestMapping("file")
public class FileController {
    @Resource
@@ -35,15 +35,12 @@
     * @return
     */
    @RequestMapping("/dept-img")
    public String deptImg(@RequestParam(value = "id", required = true) String id,
    public String deptImg(@RequestParam(value = "imgPath", required = true) String imgPath,
                          ModelMap view) {
        if(StringUtils.isNotEmpty(id)){
            String imgPath = fileManager.getDeptFile(id);;
            view.put("imgPath", imgPath);
        }
        view.put("imgPath", imgPath);
        return "web/common/preview-img";
        return "common/preview-img";
    }
fzzy-igdss-web/src/main/java/com/fzzy/sys/controller/security/SecurityController.java
@@ -1,8 +1,25 @@
package com.fzzy.sys.controller.security;
import com.fzzy.igds.constant.CameraPlayType;
import com.fzzy.igds.constant.Constant;
import com.fzzy.igds.data.PageResponse;
import com.fzzy.igds.domain.Camera;
import com.fzzy.igds.domain.Dept;
import com.fzzy.igds.service.CoreDeptService;
import com.fzzy.igds.utils.ContextUtil;
import com.fzzy.sys.manager.security.SecManager;
import com.ruoyi.common.core.domain.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
/**
 * @Description å®‰é˜²controller层
@@ -11,15 +28,100 @@
 */
@Slf4j
@Controller
@RequestMapping("/security")
@RequestMapping("security")
public class SecurityController {
    private static final String prefix = "security";
    @Resource
    private SecManager secManager;
    @Resource
    private CoreDeptService deptService;
    /**
     * ç›‘控概览
     *
     * @param type 1.表示2.5D鸟瞰图页面预览;2.表示列表预览页面
     * @return
     */
    @RequestMapping("/aerial-video")
    public String aerialVideo(
            @RequestParam(value = "type", required = false) String type,
            ModelMap view) {
        SysUser user = ContextUtil.getLoginUser();
        view.put(Constant.MODEL_KEY_LOGIN_USER, user);
        String deptId = ContextUtil.subDeptId(user);
        List<Camera> listCamera = secManager.listCamera(deptId, user.getCompanyId());
        view.put("deptId", deptId);
        view.put("listCamera", listCamera);
        //默认监控列表页面
        String viewUrl = prefix + "/video-list";
        if (StringUtils.isNotBlank( type) && "1".equals(type)) {
            Dept dept = deptService.getDeptById(deptId);
            if (dept != null && StringUtils.isNotEmpty(dept.getImgPath())) {
                view.put("backgroundImg", dept.getImgPath());
                viewUrl = prefix + "/video-aerial";
            }
        }
        return viewUrl;
    }
    /**
     * é¸Ÿçž°å›¾é¡µé¢ -- è§†é¢‘播放,通过播放参数不同跳转不同页面播放
     *
     * @param cameraId æ‘„像机系统ID
     * @param playType é…ç½®çš„æ’­æ”¾æ–¹å¼
     * @param time     æ—¶é—´å‚数,无具体含义
     * @return
     */
    @RequestMapping("/video-play")
    public String play(@RequestParam(value = "cameraId", required = true) String cameraId,
                       @RequestParam(value = "playType", required = false) String playType,
                       @RequestParam(value = "time", required = false) String time,
                       ModelMap view) {
        SysUser user = ContextUtil.getLoginUser();
        // è®¾ç½®é»˜è®¤æ’­æ”¾æ–¹å¼
        if (org.apache.commons.lang3.StringUtils.isEmpty(playType)) {
            playType = CameraPlayType.PLAY_TYPE_VLC.getCode();
        }
        // è®¾ç½®æ‘„像头信息
        Camera camera = secManager.getCameraById(null, cameraId);
        if (camera == null) {
            view.put("errorMsg", "获取视频设备出错,请先刷新缓存!");
        }
        view.put("cameraData", camera);
        String viewUrl = prefix + "/video-webrtc";
        //WEB-RTC大华播放
        if (CameraPlayType.PLAY_TYPE_WEB_RTC.getCode().equals(playType)) {
            viewUrl = prefix + "/video-webrtc";
        }
        return viewUrl;
    }
    /***
     * è§†é¢‘鸟瞰图中更改摄像头位置
     *
     * @param params
     * @return
     */
    @RequestMapping("/update-pos")
    @ResponseBody
    public PageResponse<String> updatePos(
            @RequestBody List<Camera> params) {
        return secManager.updatePos(params);
    }
}
fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package com.fzzy.sys.manager.security;
import com.fzzy.igds.constant.RespCodeEnum;
import com.fzzy.igds.data.PageResponse;
import com.fzzy.igds.domain.Camera;
import com.fzzy.igds.service.SecCameraService;
import com.fzzy.igds.utils.ContextUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
/**
 * @Description
 * @Author CZT
 * @Date 2025/12/9 9:19
 */
@Slf4j
@Component
public class SecManager {
    @Resource
    private SecCameraService secCameraService;
    /**
     *
     * @param deptId
     * @param companyId
     * @return
     */
    public List<Camera> listCamera(String deptId, String companyId) {
        if (null == deptId){
            return null;
        }
        List<Camera> list = secCameraService.getCameraByDeptId(companyId, deptId);
        if (null == list || list.isEmpty()){
            return null;
        }
        return list;
    }
    /**
     * æ ¹æ®ç›‘控ID获取监控信息
     * @param companyId
     * @param cameraId
     * @return
     */
    public Camera getCameraById(String companyId, String cameraId) {
        if (StringUtils.isEmpty(companyId)) {
            companyId = ContextUtil.getCompanyId();
        }
        if (StringUtils.isEmpty(cameraId)){
            return null;
        }
        return secCameraService.getCameraById(companyId, cameraId);
    }
    /**
     *
     * @param params
     * @return
     */
    public PageResponse<String> updatePos(List<Camera> params) {
        if (null == params || params.isEmpty()) {
            return new PageResponse<>(RespCodeEnum.CODE_2000.getCode(),
                    "当前没有需要执行的信息!");
        }
        for (Camera param : params) {
            secCameraService.updatePos(param);
        }
        secCameraService.refreshCache(ContextUtil.getCompanyId());
        return new PageResponse<>(RespCodeEnum.CODE_0000, "执行成功!!");
    }
}
fzzy-igdss-web/src/main/java/com/fzzy/sys/manager/security/SecurityManager.java
ÎļþÒÑɾ³ý
fzzy-igdss-web/src/main/resources/static/img/web/security/ca-4.png
fzzy-igdss-web/src/main/resources/static/img/web/security/sp-arrow.png
fzzy-igdss-web/src/main/resources/static/img/web/security/tit-redBg.png
fzzy-igdss-web/src/main/resources/static/js/plugins/drag/drag-drop.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
Dragdrop=function(window){var doc=window.document;var E={on:function(el,type,fn){el.addEventListener?el.addEventListener(type,fn,false):el.attachEvent?el.attachEvent("on"+type,fn):el['on'+type]=fn},un:function(el,type,fn){el.removeEventListener?el.removeEventListener(type,fn,false):el.detachEvent?el.detachEvent("on"+type,fn):el['on'+type]=null},evt:function(e){return e||window.event}};return function(opt){var conf=null,defaultConf,diffX,diffY;function Config(opt){this.target=opt.target;this.bridge=opt.bridge;this.dragable=opt.dragable!=false;this.dragX=opt.dragX!=false;this.dragY=opt.dragY!=false;this.area=opt.area;this.callback=opt.callback};function Dragdrop(opt){if(!opt){return}conf=new Config(opt);defaultConf=new Config(opt);conf.bridge?E.on(conf.bridge,'mousedown',mousedown):E.on(conf.target,'mousedown',mousedown)};Dragdrop.prototype={dragX:function(){conf.dragX=true;conf.dragY=false},dragY:function(b){conf.dragY=true;conf.dragX=false},dragAll:function(){conf.dragX=true;conf.dragY=true},setArea:function(a){conf.area=a},setBridge:function(b){conf.bridge=b},setDragable:function(b){conf.dragable=b},reStore:function(){conf=new Config(defaultConf);conf.target.style.top='0px';conf.target.style.left='0px'},getDragX:function(){return conf.dragX},getDragY:function(){return conf.dragY}};function mousedown(e){e=E.evt(e);var el=conf.target;el.style.position='absolute';el.style.cursor='move';if(el.setCapture){E.on(el,"losecapture",mouseup);el.setCapture();e.cancelBubble=true}else if(window.captureEvents){e.stopPropagation();E.on(window,"blur",mouseup);e.preventDefault()}diffX=e.clientX-el.offsetLeft;diffY=e.clientY-el.offsetTop;E.on(doc,'mousemove',mousemove);E.on(doc,'mouseup',mouseup)};function mousemove(e){var el=conf.target,e=E.evt(e),moveX=e.clientX-diffX,moveY=e.clientY-diffY;var minX,maxX,minY,maxY;if(conf.area){minX=conf.area[0];maxX=conf.area[1];minY=conf.area[2];maxY=conf.area[3];moveX<minX&&(moveX=minX);moveX>maxX&&(moveX=maxX);moveY<minY&&(moveY=minY);moveY>maxY&&(moveY=maxY)}if(conf.dragable){conf.dragX&&(el.style.left=moveX+'px');conf.dragY&&(el.style.top=moveY+'px');if(conf.callback){var obj={moveX:moveX,moveY:moveY};conf.callback.call(conf,obj)}}};function mouseup(e){var el=conf.target;el.style.cursor='default';E.un(doc,'mousemove',mousemove);E.un(doc,'mouseup',mouseup);if(el.releaseCapture){E.un(el,"losecapture",mouseup);el.releaseCapture()}if(window.releaseEvents){E.un(window,"blur",mouseup)}};return new Dragdrop(opt)}}(this);
fzzy-igdss-web/src/main/resources/static/security/video-aerial.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
var layer;
var windowWidth = 1700;
var windowHeight = 810;
$(function () {
    layui.use(['layer'], function () {
        layer = layui.layer;
        addDevice(listCamera);
    });
});
window.onload = function () {
    $("#m-container").css("background-image", "url(" + backgroundImg + ")");
    windowWidth = document.body.offsetWidth;
    windowHeight = document.body.offsetHeight;
};
function showVideo(id) {
    layer.msg("调用视频查看……");
    //获取视频信息
    var curVideo = null;
    $.each(listCamera, function (index, item) {
        if (item.id == id) {
            curVideo = item;
            return true;
        }
    });
    if (!curVideo) {
        layer.alert("没有获取到当前视频信息……");
        return;
    }
    var url = "/security/video-play?cameraId=" + curVideo.id + "&playType=" + curVideo.playType;
    if(curVideo.playType == "MEDIA_HIK"){
        //海康插件直接window.open新页面播放
        var iHeight = 550;
        var iWidth = 1100;
        var iTop = (window.screen.height-30-iHeight)/2; //获得窗口的垂直位置;
        var iLeft = (window.screen.width-10-iWidth)/2; //获得窗口的水平位置;
        console.log(iWidth + "-" + iHeight);
        console.log(iTop + "-" + iLeft);
        var name = "视频预览";
        window.open(url,name,'height='+iHeight+',innerHeight='+iHeight+',width='+iWidth+',innerWidth='+iWidth+',top='+iTop+',left='+iLeft+',toolbar=0,menubar=0,scrollbars=auto,resizeable=0,location=0,status=no');
    }else {
        if (windowWidth > 1350) {
            layer.open({
                type: 2,
                title: false,//"当前预览:" + curVideo.name,
                area: ['1315px', '570px'],
                shade: 0,
                content: url,
                btn: 0,
                closeBtn: 2
            });
        } else {
            layer.open({
                type: 2,
                title: false,//"当前预览:" + curVideo.name,
                area: ['1315px', (windowHeight - 30) + 'px'],
                shade: 0,
                content: url,
                btn: 0,
                closeBtn: 2
            });
        }
    }
};
function showTips(name) {
    $("#camera_info").text("提示:当前设备名称- " + name);
};
// å¼€å§‹æ‹–拽
function drag() {
    var tips = $(".device");
    if (tips.length == 0) {
        return;
    }
    var maxX = windowWidth;
    var maxY = windowHeight;
    $.each(tips, function (index, item) {
        var dd = new Dragdrop({
            target: item,
            area: [0, maxX, 0, maxY],
            callback: function (obj) {
                console.log('x:' + (obj.moveX) + ' y:' + (obj.moveY));
            }
        });
        dd.dragAll();
    });
};
//添加设备信息
function addDevice(list) {
   //  console.log(list);
    if (!list || list.length == 0) return;
    var container = $("#m-container");
    var parentWidth = container.width();
    var parentHeight = container.height();
    var temp;
    var left = 50, top = 50;
    $.each(list, function (index, item) {
        left = (parentWidth * item.posX).toFixed(4);
        top = (parentHeight * item.posY).toFixed(4);
        if (left < 1) left = 50;
        if (top < 1) top = 50;
        temp = "";
        temp += "<div id='" + item.id + "' class='device' "
            + "' onclick=showTips('" + item.name + "') "
            + "' ondblclick=showVideo('" + item.id + "') style='left:"
            + left + "px;top:" + top + "px;'>";
        temp += "<img src='/img/web/security/ca-4.png' /></div>";
        container.append(temp);
    });
};
// ä¿å­˜è®¾å¤‡ä½ç½®ä¿¡æ¯
function updatePos() {
    var tips = $(".device");
    if (tips.length == 0) {
        return;
    }
    var container = $("#m-container");
    var parentWidth = container.width();
    var parentHeight = container.height();
    var parentTop = container.offset().top;
    var parentLeft = container.offset().left;
    // å°è£…数据进行保存
    var data = new Array();
    var id = null, posX = 0.0, posY = 0.0;
    var offset;
    $.each(tips, function (index, item) {
        id = item.id;
        offset = $('#' + id).offset();
        posX = (offset.left - parentLeft) / parentWidth;
        posY = (offset.top - parentTop) / parentHeight;
        data[index] = {
            id: id,
            posX: posX.toFixed(4),
            posY: posY.toFixed(4)
        };
    });
    $.ajax({
        type: 'POST',
        url: "/security/update-pos",
        dataType: 'JSON',
        contentType: "application/json;charset=UTF-8",
        data: JSON.stringify(data),
        success: function (result) {
            layer.msg("信息更新完成!!");
        },
        error: function (result) {
            layer.msg(result.msg);
        }
    });
}
fzzy-igdss-web/src/main/resources/static/security/video-list.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,613 @@
@charset "utf-8";
@font-face {
    font-family: DINCond-Bold;
    src: url('../fonts/DINCond-Bold.otf');
}
body {
    font-family: "微软雅黑", Arial, sans-serif;
    font-size: 14px;
    background: #282e35;
    position: relative;
}
i, em {
    font-style: normal;
}
a {
    text-decoration: none;
}
.fl {
    float: left;
}
.fr {
    float: right;
}
.i-container {
    width: 100%;
    /* min-width: 1290px; */
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
}
.jmkt-main {
    overflow: hidden;
    padding: 0 5px;
}
.sp-boxWrap,
.sp-box {
    height: 550px;
}
.sp-box {
    background: #2f3740;
    -webkit-border-radius: 8px;
    border-radius: 8px;
    overflow: hidden;
}
.pdgxq-H {
    height: 35px;
    padding: 0 20px;
    margin-top: 5px;
}
.pdgxq-H h3 {
    line-height: 35px;
    height: 35px;
    color: #fff;
    font-size: 18px;
    font-weight: bold;
    position: relative;
    float: left;
}
.pdgxq-H h3 i {
    display: inline-block;
    width: 4px;
    height: 24px;
    position: absolute;
    left: -20px;
    top: 50%;
    margin-top: -12px;
    z-index: 9;
    background: url(../img/web/security/tit-redBg.png) center no-repeat;
}
.sp-showBox {
    height: 100%;
}
.sp-showBox.show {
    display: block;
}
.sp-showItem {
    text-align: center;
    line-height: 316px;
    height: 316px;
    background: #262c33;
    margin: 2px;
    -webkit-border-radius: 8px;
    border-radius: 8px;
}
.sp-hideImg {
    width: 200px;
    height: 200px;
}
.sp-tab-hd {
    height: 40px;
    float: right;
}
.sp-tab-hd span {
    display: inline-block;
    float: right;
    width: 25px;
    height: 25px;
    padding: 4px;
    -webkit-border-radius: 4px;
    border-radius: 4px;
    overflow: hidden;
    margin: 3px 10px;
    opacity: 0.5;
    cursor: pointer;
}
.sp-tab-hd span img {
    width: 100%;
    height: 100%;
}
.sp-tab-hd span.active,
.sp-tab-hd span:hover {
    background: #262c33;
    opacity: 1;
}
.sp-showItem2 {
    text-align: center;
    height: 550px;
    background: #262c33;
    -webkit-border-radius: 8px;
    border-radius: 8px;
}
.sp-showItem2 .sp-hideImg {
    margin-top: 150px;
    width: 30%;
    height: auto;
}
.sp-cz-wrap {
    width: 270px;
    overflow: hidden;
    margin: 10px auto;
}
.sp-cz-box {
    overflow: hidden;
    width: 284px;
    height: 284px;
}
.sp-cz-box ul li {
    float: left;
    margin: 1.5px;
    background: #262c33;
    overflow: hidden;
    text-align: center;
    vertical-align: middle;
    display: table;
    opacity: 0.5;
}
.sp-cz-box ul li a {
    vertical-align: middle;
    display: table-cell;
    width: 100%;
    height: 100%;
}
.sp-cz-box ul li a img {
    width: 32px;
    height: 32px;
}
.sp-cz-box ul li.sp-cz-l5 a img {
    width: 66px;
    height: 66px;
}
.sp-cz-l1,
.sp-cz-l2,
.sp-cz-l3,
.sp-cz-l7,
.sp-cz-l8,
.sp-cz-l9 {
    height: 88px;
}
.sp-cz-l4,
.sp-cz-l5,
.sp-cz-l6 {
    height: 98px;
}
.sp-cz-l1 {
    width: 88px;
    border-top-left-radius: 8px;
}
.sp-cz-l2,
.sp-cz-l5,
.sp-cz-l8 {
    width: 98px;
}
.sp-cz-l3 {
    width: 88px;
    border-top-right-radius: 8px;
}
.sp-cz-l4,
.sp-cz-l6 {
    width: 88px;
}
.sp-cz-l7 {
    width: 88px;
    border-bottom-left-radius: 8px;
}
.sp-cz-l9 {
    width: 88px;
    border-bottom-right-radius: 8px;
}
.sp-cz-box ul li:hover,
.sp-cz-box ul li:active {
    background: #ef344a;
    opacity: 1;
}
.sp-cz-box ul li.sp-cz-l5,
.sp-cz-box ul li.sp-cz-l5:hover,
.sp-cz-box ul li.sp-cz-l5:active {
    background: #2a3138 !important;
    opacity: 0.5;
}
.sp-cz-l2 img {
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}
.sp-cz-l3 img {
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
}
.sp-cz-l4 img {
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
.sp-cz-l6 img {
    -webkit-transform: rotate(135deg);
    transform: rotate(135deg);
}
.sp-cz-l7 img {
    -webkit-transform: rotate(-90deg);
    transform: rotate(-90deg);
}
.sp-cz-l8 img {
    -webkit-transform: rotate(-135deg);
    transform: rotate(-135deg);
}
.sp-cz-l9 img {
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
}
/*.sp-bianbei {*/
/*    height: 50px;*/
/*    background: #262c33;*/
/*    width: 280px;*/
/*    -webkit-border-radius: 30px;*/
/*    border-radius: 30px;*/
/*    overflow: hidden;*/
/*    margin: 10px 2px 0 2px;*/
/*    text-align: center;*/
/*}*/
/*.sp-bianbei > span {*/
/*    line-height: 50px;*/
/*    color: #bbc3cd;*/
/*    font-size: 20px;*/
/*}*/
/*.sp-czBtn {*/
/*    width: 44px;*/
/*    height: 44px;*/
/*    background: #4c5764;*/
/*    text-align: center;*/
/*    vertical-align: top;*/
/*    color: #fff;*/
/*    font-weight: bold;*/
/*    border: 0;*/
/*    outline: none;*/
/*    -webkit-border-radius: 50%;*/
/*    border-radius: 50%;*/
/*    margin: 3px;*/
/*    font-size: 36px;*/
/*    cursor: pointer;*/
/*}*/
.fr{
    float: right;
}
.sp-bianbei{
    width: 47%;
    height: 40px;
    background: #4c5863;
    -webkit-border-radius: 30px;
    border-radius: 30px;
    overflow: hidden;
    margin: 10px 0;
    text-align: center;
}
.sp-bianbei>span{
    line-height: 40px;
    color: #bbc3cd;
    font-size:16px;
}
.sp-czBtn{
    background: #4c5764;
    text-align: center;
    vertical-align: top;
    color: #fff;
    font-weight: bold;
    border: 0;
    outline: none;
    -webkit-border-radius: 50%;
    border-radius: 50%;
    margin: 3px;
    font-size: 30px;
    cursor: pointer;
}
.sp-sxBtn{
    /*float: left;*/
}
.sp-fdBtn{
    float: right;
}
.sp-czBtn i{
    position: relative;
    top: -5px;
}
.sp-czBtn:active{
    background: #ef344a;
}
.sp-table-box {
    margin: 5px 10px 0 10px;
}
.sp-table-tit {
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid #8f3545;
}
.sp-table-tit h3 {
    float: left;
    color: #fff;
    font-size: 16px;
    font-weight: bold;
}
.sp-table-tit span {
    float: right;
    color: #9ea6af;
    font-size: 14px;
}
.sp-table {
    background: #2a3138;
    /*height: 190px;*/
    -webkit-border-bottom-left-radius: 8px;
    border-bottom-left-radius: 8px;
    -webkit--bottom-right-radius: 8px;
    border-bottom-right-radius: 8px;
    overflow-y: auto;
}
.sp-list {
    overflow: hidden;
    width: 100%;
}
.sp-list li {
    height: 35px;
    padding: 5px 10px;
    overflow: hidden;
}
.sp-list li:hover,
.sp-list li:active {
    background: #252b32;
}
.preset-input{
    width: 65px;
    appearance: none;
    -webkit-appearance:none;
    -moz-appearance:none;
    white-space: nowrap;
    text-overflow: ellipsis;
    height: 40px;
    line-height: 40px;
    border-radius: 3px;
    background: #4c5764;
    color: #bbc3cd;
    border-width: 0px;
    text-align: center;
}
.sp-list li p {
    line-height: 35px;
    height: 35px;
    overflow: hidden;
    color: #fff;
    font-size: 16px;
}
.sp-list li img {
    width: 35px;
    height: 35px;
    float: left;
    margin-right: 20px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
}
/** äº‘台控制**/
.ptz-block {
    position: absolute;
    z-index: 99999;
    width: 130px;
    height: 254px;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    font-size: 24px;
    background-color: rgba(0,0,0,.6);
    opacity: 0;
    border-radius: 10px 0 0 10px;
    overflow: hidden;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: center;
    align-items: center;
    transition: all 1s;
}
.ptz-block .ptzBlock {
    width: 139px;
    height: 150px;
    margin: 0 auto;
    text-align: center;
    position: relative;
    font-size: 24px;
}
.ptz-block .ptzBlock .ptz-block-box {
    width: 139px;
    height: 150px;
}
.ptz-up, .ptz-block {
    cursor: pointer;
}
.ptz-block .ptz-up {
    top: 0;
    left: 50%;
    transform: translateX(-50%);
}
.ptz-block .direction{
    width: 50px;
    height: 50px;
    line-height: 50px;
    position: absolute;
    cursor: pointer;
    color: #fff;
}
.ptz-block .direction:hover{
    color: #ef344a;
}
.ptz-block .ptz-left {
    top: 50%;
    left: 0;
    transform: translateY(-50%);
}
.ptz-block .ptz-center {
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    width: 42px;
    height: 42px;
    line-height: 42px;
    position: absolute;
    border-radius: 25px;
    background-color: #fff;
    font-size: 24px;
    color: #3d414a;
    cursor: pointer;
}
.ptz-block .ptz-right {
    top: 50%;
    right: 0;
    transform: translateY(-50%);
}
.ptz-block .ptz-down {
    top: 100px;
    left: 50%;
    transform: translateX(-50%);
}
.ptz-block .ptz-input{
    width: 60px;
    height: 25px;
    font-size: 15px;
    line-height: 42px;
    text-align: left;
    color: #0a1118;
}
.el-input {
    position: relative;
}
.el-input__inner {
    padding: 0;
    text-align: center;
}
.el-input--mini .el-input__inner {
    height: 28px;
    line-height: 28px;
}
.el-input__inner {
    -webkit-appearance: none;
    background-color: #fff;
    background-image: none;
    border-radius: 6px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: inherit;
    /*height: 40px;*/
    /*line-height: 40px;*/
    outline: none;
    /*padding: 0 0px;*/
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    width: 100%;
    margin-left: 40px
}
.ptz-block .ptz-plus {
    top: -30px;
    left: 30%;
    transform: translateX(-50%);
}
.ptz-block .ptz-btn {
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    font-size: 14px;
    position: absolute;
    background-color: #fff;
    border-radius: 12px;
    color: #3d414a;
    font-weight: 400;
}
.ptz-block .ptz-minus {
    top: -30px;
    left: 70%;
    transform: translateX(-50%);
}
.ptz-block .ptz-btn:hover{
    background-color: #ef344a;
    color: #ffffff;
}
/** äº‘台控制END **/
fzzy-igdss-web/src/main/resources/static/security/video-list.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,204 @@
var layer;
var timer;
var table;
var cameraData;
var playUrl= null;
$(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 cameraId
 */
play = function (data) {
    layer.msg("正在获取播放信息……");
    cameraData = null;
    playUrl = null;
    var data = {
        id: data.id,
        playType: data.playType
    };
    $.ajax({
        type: 'POST',
        url: "/security/get-media",
        dataType: 'JSON',
        contentType: "application/json;charset=UTF-8",
        data: JSON.stringify(data),
        success: function (result) {
            if (result.code != "SUCCESS") {
                layer.msg(result.msg);
            } else {
                cameraData = result;
                playUrl = result.playUrl;
                play2();
            }
        },
        error: function (result) {
            play2();
        }
    });
};
play2 = function () {
    if (!cameraData) {
        layer.alert("未获取到当前摄像头播放信息!!");
        return;
    }
    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);
    });
}
/**
 * æ’­æ”¾è¿˜æ˜¯æš‚停
 */
function playStop() {
    var videL = $('#easyPlayer');
    if (videL.paused) {
        videL.play();
    } else {
        videL.pause();
    }
}
/*============= 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);
}
/*============= webRtc视频播放 ----- å¼€å§‹ ===============*/
/*============= webRtc视频播放 ----- å¼€å§‹ ===============*/
/**
 * å¼€å§‹æ’­æ”¾
 * @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({
            iceServers: [{
                urls: ["stun:stun.l.google.com:19302"]
            }],
            sdpSemantics: "unified-plan"
        });
        webrtc.onsignalingstatechange = signalingstatechange;
        webrtc.ontrack = ontrack
        let offer = await webrtc.createOffer({
            offerToReceiveAudio: true,
            offerToReceiveVideo: true
        });
        await webrtc.setLocalDescription(offer);
    }
}
function ontrack(event) {
    mediaStream.addTrack(event.track);
}
async function signalingstatechange() {
    switch (webrtc.signalingState) {
        case 'have-local-offer':
            // let uuid = $('#uuid').val();
            let url = playUrl + "?uuid=" + cameraData.cameraId + "&channel=0";
            $.post(url, {
                data: btoa(webrtc.localDescription.sdp)
            }, function (data) {
                try {
                    console.log(data);
                    webrtc.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 ${webrtc.signalingState}`);
            break;
    }
}
/*============= è§†é¢‘播放 ----- ç»“束 ===============*/
fzzy-igdss-web/src/main/resources/static/security/video-webrtc.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,579 @@
@charset "utf-8";
@font-face {
    font-family: DINCond-Bold;
    src: url('../fonts/DINCond-Bold.otf');
}
body {
    font-family: "微软雅黑", Arial, sans-serif;
    font-size: 14px;
    background: #282e35;
    position: relative;
}
i, em {
    font-style: normal;
}
a {
    text-decoration: none;
}
.fl {
    float: left;
}
.fr {
    float: right;
}
.i-container {
    width: 100%;
    /* min-width: 1290px; */
    margin-left: auto;
    margin-right: auto;
    overflow: hidden;
}
.jmkt-main {
    overflow: hidden;
    padding: 0 5px;
}
.sp-boxWrap,
.sp-box {
    height: 550px;
}
.sp-box {
    background: #2f3740;
    -webkit-border-radius: 8px;
    border-radius: 8px;
    overflow: hidden;
}
.pdgxq-H {
    height: 35px;
    padding: 0 20px;
    margin-top: 5px;
}
.pdgxq-H h3 {
    line-height: 35px;
    height: 35px;
    color: #fff;
    font-size: 18px;
    font-weight: bold;
    position: relative;
    float: left;
}
.pdgxq-H h3 i {
    display: inline-block;
    width: 4px;
    height: 24px;
    position: absolute;
    left: -20px;
    top: 50%;
    margin-top: -12px;
    z-index: 9;
    background: url(../../img/web/security/tit-redBg.png) center no-repeat;
}
.sp-showBox {
    height: 100%;
}
.sp-showBox.show {
    display: block;
}
.sp-showItem {
    text-align: center;
    line-height: 316px;
    height: 316px;
    background: #262c33;
    margin: 2px;
    -webkit-border-radius: 8px;
    border-radius: 8px;
}
.sp-hideImg {
    width: 200px;
    height: 200px;
}
.sp-tab-hd {
    height: 40px;
    float: right;
}
.sp-tab-hd span {
    display: inline-block;
    float: right;
    width: 25px;
    height: 25px;
    padding: 4px;
    -webkit-border-radius: 4px;
    border-radius: 4px;
    overflow: hidden;
    margin: 3px 10px;
    opacity: 0.5;
    cursor: pointer;
}
.sp-tab-hd span img {
    width: 100%;
    height: 100%;
}
.sp-tab-hd span.active,
.sp-tab-hd span:hover {
    background: #262c33;
    opacity: 1;
}
.sp-showItem2 {
    text-align: center;
    height: 550px;
    background: #262c33;
    -webkit-border-radius: 8px;
    border-radius: 8px;
}
.sp-showItem2 .sp-hideImg {
    margin-top: 150px;
    width: 30%;
    height: auto;
}
.sp-cz-wrap {
    width: 270px;
    overflow: hidden;
    margin: 10px auto;
}
.sp-cz-box {
    overflow: hidden;
    width: 284px;
    height: 284px;
}
.sp-cz-box ul li {
    float: left;
    margin: 1.5px;
    background: #262c33;
    overflow: hidden;
    text-align: center;
    vertical-align: middle;
    display: table;
    opacity: 0.5;
}
.sp-cz-box ul li a {
    vertical-align: middle;
    display: table-cell;
    width: 100%;
    height: 100%;
}
.sp-cz-box ul li a img {
    width: 32px;
    height: 32px;
}
.sp-cz-box ul li.sp-cz-l5 a img {
    width: 66px;
    height: 66px;
}
.sp-cz-l1,
.sp-cz-l2,
.sp-cz-l3,
.sp-cz-l7,
.sp-cz-l8,
.sp-cz-l9 {
    height: 88px;
}
.sp-cz-l4,
.sp-cz-l5,
.sp-cz-l6 {
    height: 98px;
}
.sp-cz-l1 {
    width: 88px;
    border-top-left-radius: 8px;
}
.sp-cz-l2,
.sp-cz-l5,
.sp-cz-l8 {
    width: 98px;
}
.sp-cz-l3 {
    width: 88px;
    border-top-right-radius: 8px;
}
.sp-cz-l4,
.sp-cz-l6 {
    width: 88px;
}
.sp-cz-l7 {
    width: 88px;
    border-bottom-left-radius: 8px;
}
.sp-cz-l9 {
    width: 88px;
    border-bottom-right-radius: 8px;
}
.sp-cz-box ul li:hover,
.sp-cz-box ul li:active {
    background: #ef344a;
    opacity: 1;
}
.sp-cz-box ul li.sp-cz-l5,
.sp-cz-box ul li.sp-cz-l5:hover,
.sp-cz-box ul li.sp-cz-l5:active {
    background: #2a3138 !important;
    opacity: 0.5;
}
.sp-cz-l2 img {
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}
.sp-cz-l3 img {
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
}
.sp-cz-l4 img {
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
.sp-cz-l6 img {
    -webkit-transform: rotate(135deg);
    transform: rotate(135deg);
}
.sp-cz-l7 img {
    -webkit-transform: rotate(-90deg);
    transform: rotate(-90deg);
}
.sp-cz-l8 img {
    -webkit-transform: rotate(-135deg);
    transform: rotate(-135deg);
}
.sp-cz-l9 img {
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
}
.fr{
    float: right;
}
.sp-bianbei{
    width: 47%;
    height: 40px;
    background: #4c5863;
    -webkit-border-radius: 30px;
    border-radius: 30px;
    overflow: hidden;
    margin: 10px 0;
    text-align: center;
}
.sp-bianbei>span{
    line-height: 40px;
    color: #bbc3cd;
    font-size:16px;
}
.sp-czBtn{
    background: #4c5764;
    text-align: center;
    vertical-align: top;
    color: #fff;
    font-weight: bold;
    border: 0;
    outline: none;
    -webkit-border-radius: 50%;
    border-radius: 50%;
    margin: 3px;
    font-size: 30px;
    cursor: pointer;
}
.sp-sxBtn{
    /*float: left;*/
}
.sp-fdBtn{
    float: right;
}
.sp-czBtn i{
    position: relative;
    top: -5px;
}
.sp-czBtn:active{
    background: #ef344a;
}
.sp-table-box {
    margin: 5px 10px 0 10px;
}
.sp-table-tit {
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid #8f3545;
}
.sp-table-tit h3 {
    float: left;
    color: #fff;
    font-size: 16px;
    font-weight: bold;
}
.sp-table-tit span {
    float: right;
    color: #9ea6af;
    font-size: 14px;
}
.sp-table {
    background: #2a3138;
    /*height: 190px;*/
    -webkit-border-bottom-left-radius: 8px;
    border-bottom-left-radius: 8px;
    -webkit--bottom-right-radius: 8px;
    border-bottom-right-radius: 8px;
    overflow-y: auto;
}
.sp-list {
    overflow: hidden;
    width: 100%;
}
.sp-list li {
    height: 35px;
    padding: 5px 10px;
    overflow: hidden;
}
.sp-list li:hover,
.sp-list li:active {
    background: #252b32;
}
.preset-input{
    width: 65px;
    appearance: none;
    -webkit-appearance:none;
    -moz-appearance:none;
    white-space: nowrap;
    text-overflow: ellipsis;
    height: 40px;
    line-height: 40px;
    border-radius: 3px;
    background: #4c5764;
    color: #bbc3cd;
    border-width: 0px;
    text-align: center;
}
.sp-list li p {
    line-height: 35px;
    height: 35px;
    overflow: hidden;
    color: #fff;
    font-size: 16px;
}
.sp-list li img {
    width: 35px;
    height: 35px;
    float: left;
    margin-right: 20px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
}
/** äº‘台控制**/
.ptz-block {
    position: absolute;
    z-index: 99999;
    width: 130px;
    height: 254px;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    font-size: 24px;
    background-color: rgba(0,0,0,.6);
    opacity: 0;
    border-radius: 10px 0 0 10px;
    overflow: hidden;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: center;
    align-items: center;
    transition: all 1s;
}
.ptz-block .ptzBlock {
    width: 139px;
    height: 150px;
    margin: 0 auto;
    text-align: center;
    position: relative;
    font-size: 24px;
}
.ptz-block .ptzBlock .ptz-block-box {
    width: 139px;
    height: 150px;
}
.ptz-up, .ptz-block {
    cursor: pointer;
}
.ptz-block .ptz-up {
    top: 0;
    left: 50%;
    transform: translateX(-50%);
}
.ptz-block .direction{
    width: 50px;
    height: 50px;
    line-height: 50px;
    position: absolute;
    cursor: pointer;
    color: #fff;
}
.ptz-block .direction:hover{
    color: #ef344a;
}
.ptz-block .ptz-left {
    top: 50%;
    left: 0;
    transform: translateY(-50%);
}
.ptz-block .ptz-center {
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    width: 42px;
    height: 42px;
    line-height: 42px;
    position: absolute;
    border-radius: 25px;
    background-color: #fff;
    font-size: 24px;
    color: #3d414a;
    cursor: pointer;
}
.ptz-block .ptz-right {
    top: 50%;
    right: 0;
    transform: translateY(-50%);
}
.ptz-block .ptz-down {
    top: 100px;
    left: 50%;
    transform: translateX(-50%);
}
.ptz-block .ptz-input{
    width: 60px;
    height: 25px;
    font-size: 15px;
    line-height: 42px;
    text-align: left;
    color: #0a1118;
}
.el-input {
    position: relative;
}
.el-input__inner {
    padding: 0;
    text-align: center;
}
.el-input--mini .el-input__inner {
    height: 28px;
    line-height: 28px;
}
.el-input__inner {
    -webkit-appearance: none;
    background-color: #fff;
    background-image: none;
    border-radius: 6px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: inherit;
    /*height: 40px;*/
    /*line-height: 40px;*/
    outline: none;
    /*padding: 0 0px;*/
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    width: 100%;
    margin-left: 40px
}
.ptz-block .ptz-plus {
    top: -30px;
    left: 30%;
    transform: translateX(-50%);
}
.ptz-block .ptz-btn {
    width: 24px;
    height: 24px;
    line-height: 24px;
    text-align: center;
    font-size: 14px;
    position: absolute;
    background-color: #fff;
    border-radius: 12px;
    color: #3d414a;
    font-weight: 400;
}
.ptz-block .ptz-minus {
    top: -30px;
    left: 70%;
    transform: translateX(-50%);
}
.ptz-block .ptz-btn:hover{
    background-color: #ef344a;
    color: #ffffff;
}
/** äº‘台控制END **/
fzzy-igdss-web/src/main/resources/static/security/video-webrtc.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,242 @@
var layer;
var playUrl= null;
var loginTag = false;
$(function () {
    layui.use(['layer'], function () {
        layer = layui.layer;
    });
    getMedia();
});
/**
 * èŽ·å–æ’­æ”¾ä¿¡æ¯
 */
function getMedia() {
    var data = {
        id: cameraData.id,
        playType: cameraData.playType
    };
    $.ajax({
        type: 'POST',
        url: "/security/get-media",
        dataType: 'JSON',
        contentType: "application/json;charset=UTF-8",
        data: JSON.stringify(data),
        success: function (result) {
            if (result.code != "SUCCESS") {
                layer.msg(result.msg);
            } else {
                playUrl = result.playUrl;
                toPlay();
                onLogin();
            }
        },
        error: function (result) {
            layer.msg(result.msg);
        }
    });
}
/*============= webRtc视频播放 ----- å¼€å§‹ ===============*/
/**
 * å¼€å§‹æ’­æ”¾
 * @param winTag  æ’­æ”¾çª—口
 * @returns {Promise<void>}
 */
async function toPlay() {
    if(playUrl){
        mediaStream = new MediaStream();
        $("#video")[0].srcObject = mediaStream;
        webrtc = new RTCPeerConnection({
            iceServers: [{
                urls: ["stun:stun.l.google.com:19302"]
            }],
            sdpSemantics: "unified-plan"
        });
        webrtc.onsignalingstatechange = signalingstatechange;
        webrtc.ontrack = ontrack
        let offer = await webrtc.createOffer({
            offerToReceiveAudio: true,
            offerToReceiveVideo: true
        });
        await webrtc.setLocalDescription(offer);
    }
}
function ontrack(event) {
    mediaStream.addTrack(event.track);
}
async function signalingstatechange() {
    switch (webrtc.signalingState) {
        case 'have-local-offer':
            // let uuid = $('#uuid').val();
            let url = playUrl + "?uuid=" + cameraData.id + "&channel=0";
            $.post(url, {
                data: btoa(webrtc.localDescription.sdp)
            }, function (data) {
                try {
                    console.log(data);
                    webrtc.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 ${webrtc.signalingState}`);
            break;
    }
}
/*============= è§†é¢‘播放 ----- ç»“束 ===============*/
/**
 *
 * @param command äº‘台事件类型
 * @param flag æ˜¯å¦åœæ­¢ç›¸åº”事件
 */
function handPTZ(command, flag){
    if(!loginTag){
        layer.alert("设备云台登录失败,请重试!");
        return;
    }
    //大华云台控制
    dhPlayerPTZ(command, flag);
}
/**
 * äº‘台控制 -预置位置调用
 */
function handPreset() {
}
/*============= å¤§åŽJS云台控制 ----- å¼€å§‹ ===============*/
/**
 * @description è®¾å¤‡ç™»å½•
 */
function onLogin (){
    onLogout();
    let ip = cameraData.ip;
    let port= cameraData.webPort;
    let user= cameraData.loginId;
    let pwd=  cameraData.pwd;
    let target = ip + ':' + port;
    setIP(target);
    /**
     * RPC.login ç™»å½•
     * @param {string} $user.value ç”¨æˆ·å
     * @param {string} $password.value å¯†ç 
     * @param {boolean} false æ˜¯å¦httpOnly,默认false
     * @returns {Promise}
     */
    RPC.login(user, pwd, false).then((res) => {
        setCookie('DWebClientSessionID', '', -1);
        setCookie('DhWebClientSessionID', '', -1);
        /**
         * RPC.keepAlive ä¿æ´»
         */
        RPC.keepAlive(300, 60000, _getSession(), target, 0);
        const browser = BrowserType();
        if (browser.includes('ie')) {
            window.onunload = () => {
                ajax({
                    url: 'global.logout'
                });
            };
        } else if (browser.includes('chrome')) {
            const params = {
                method: 'global.logout',
                params: null,
                id: 10000,
                session: _getSession()
            };
            pubsub.subscribe('onbeforeunload',() => {
                navigator.sendBeacon('/RPC2', JSON.stringify(params));
            });
        } else {
            pubsub.subscribe('onbeforeunload',() => {
                ajax({
                    url: 'global.logout'
                });
            });
        }
        //登录成功,记录登录成功的硬盘录像机
        loginTag = true;
    }).catch((err) => {
        console.log(err);
    });
}
/**
 * @description è®¾å¤‡æ³¨é”€
 */
function onLogout (){
    /**
     * RPC.Global.logout æ³¨é”€æŽ¥å£
     * @returns {Promise}
     */
    RPC.Global.logout().then(function() {
        setLoginState(false);
        playerInstance.forEach(item => {
            if(item) {
                item.stop();
                item.close();
                item = null;
            }
            loginTag = false;
        });
    });
}
/**
 * @description è®¾å¤‡äº‘台事件
 * @param {string} type äº‘台事件类型
 * @param {boolean} isStop æ˜¯å¦åœæ­¢ç›¸åº”事件
 */
function dhPlayerPTZ (type, isStop) {
    //云台步长
    // let stepVal = $_('#h5_ptz_step').value - 0;
    let stepVal = 5;
    let arg2 = 0;
    let arg2Arr = ['LeftUp', 'RightUp', 'LeftDown', 'RightDown'];
    let presetArr = ['GotoPreset','SetPreset', 'ClearPreset'];
    //预置点
    // let presetNum = $_('#h5_preset').value - 0;
    let presetNum =  0;
    if(arg2Arr.indexOf(type) > -1) {
        arg2 = stepVal;
    }
    if(!isStop) {
        if(presetArr.indexOf(type) > -1) {
            /**
             * RPC.PTZManager äº‘台相关
             * @param {string} æ–¹æ³•
             * @param {number} channel é€šé“
             * @param {object} å‚数集合
             */
            RPC.PTZManager('start', 0, { 'code': type, 'arg1': presetNum, 'arg2': 0, 'arg3': 0 });
        } else {
            RPC.PTZManager('start', 0, { 'code': type, 'arg1': stepVal, 'arg2': arg2, 'arg3': 0 });
        }
    } else {
        RPC.PTZManager('stop', 0, { 'code': type, 'arg1': stepVal, 'arg2': arg2, 'arg3': 0 });
    }
}
/*============= å¤§åŽJS云台控制 ----- ç»“束 ===============*/
fzzy-igdss-web/src/main/resources/templates/common/preview-img.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <title>视频预览</title>
    <link rel="stylesheet" th:href="@{/ajax/libs/layui/css/layui.css}"/>
    <style type="text/css">
        .layui-card-header {
            font-weight: bold;
            background-color: #39aef5;
            color: #FFF;
        }
        .layui-card-body {
            text-align: center;
        }
        thead span {
            font-weight: bold
        }
        .video {
            width: 100%;;
            height: 100%;
        }
    </style>
</head>
<body>
<!-- å¯è¿½è¸ªä¿¡æ¯ -->
<div class="layui-tab-content">
    <div class="layui-fluid" id="recordFilesDiv">
        <div class="layui-col-md12 layui-col-sm12">
            <div class="layui-card">
                <div class="layui-card-body">
                    <img th:src="${imgPath}" style="height: 100%;width: 100%">
                </div>
            </div>
        </div>
    </div>
</div>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script>
</script>
</body>
</html>
fzzy-igdss-web/src/main/resources/templates/security/video-aerial.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="zh-cn" xmlns:th=http://www.thymeleaf.org>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>智慧粮库管理平台-监控鸟瞰图</title>
    <link rel="stylesheet" th:href="@{/ajax/libs/layui/css/layui.css}"/>
    <style>
        html, body, .full {
            width: 100%;
            height: 100%;
            overflow-y: hidden;
        }
        #m-container {
            background-repeat: no-repeat;
            background-size: 100% 100%;
            -moz-background-size: 100% 100%;
        }
        .device {
            position: absolute;
        }
        .device img {
            width: 40px;
            height: 40px;
        }
        #camera_info {
            font-size: 14px;
            font-weight: bold;
            color: red;
        }
    </style>
</head>
<body>
<div class="layui-card-body" style="height: 100%; padding: 1px;" id="main">
    <div class="full" id="m-container">
        <div style="float: right;">
            <span id="camera_info">提示:</span>
            <button type="button" class="layui-btn layui-btn-sm" onclick="drag()">移动</button>
            <button type="button" class="layui-btn layui-btn-sm layui-btn-danger" onclick="updatePos()">保存</button>
        </div>
    </div>
</div>
<script th:inline="javascript">
    //系统登陆人
    var loginUser = [[${loginUser}]];
    //业务类型
    var bizType = [[${bizType}]];
    //userId
    var userId = [[${loginUser.loginName}]];
    var companyId = [[${loginUser.companyId}]];
    //当前设备列表
    var listCamera = [[${listCamera}]];
    var backgroundImg = [[${backgroundImg}]];
</script>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/common/constant.js}"></script>
<script th:src="@{/common/igds-common.js}"></script>
<script th:src="@{/js/plugins/drag/drag-drop.js}"></script>
<script th:src="@{/security/video-aerial.js}"></script>
<!-- å¼¹å‡ºæ“ä½œæ¡† -->
<div class="layui-tab-content" id="aerialDialog" style="display: none;">
    <div class="layui-btn-container m10"></div>
</div>
</body>
</html>
fzzy-igdss-web/src/main/resources/templates/security/video-list.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,236 @@
<!DOCTYPE html>
<html lang="zh-cn" xmlns:th=http://www.thymeleaf.org>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <title>智慧粮库管理平台-监控列表</title>
    <link rel="stylesheet" th:href="@{/ajax/libs/layui/css/layui.css}"/>
    <link rel="stylesheet" th:href="@{/security/video-list.css}">
    <style>
        html, body, .full {
            width: 100%;
            height: 100%;
            overflow-y: hidden;
        }
        .layui-fluid {
            position: relative;
            margin: 0 auto;
            padding: unset;
        }
        .layui-col-space20 {
            margin: unset;
        }
        .layui-col-space20>* {
            padding: 10px 5px;
        }
        .sp-showItem2 {
            height: 690px;
        }
        .sp-box {
            height: 760px;
        }
        .sp-rl>span {
            line-height: 50px;
            color: #bbc3cd;
            font-size: 20px;
        }
        .sp-table {
            height: 732px;
            width: 425px;
        }
        .pdgxq-table1 {
            background-color: transparent;
            margin: 0;
        }
        .pdgxq-table1 thead tr th {
            color: #ef344a;
        }
        .pdgxq-table1 thead tr {
            background: #141C25 !important;
            border-bottom: 1px solid #ef344a;
        }
        .layui-table td, .layui-table th {
            padding: 9px 5px;
        }
        .pdgxq-table1 th, .pdgxq-table1 td {
            text-align: center;
            min-height: 32px;
            line-height: 32px;
            font-size: 14px;
        }
        .pdgxq-table1 tbody tr:nth-child(odd) {
            background-color: #262d33;
        }
        .pdgxq-table1 td em {
            color: #ef344a;
        }
        .layui-table td, .layui-table th {
            padding: 9px 5px;
        }
        .pdgxq-table1 td {
            color: #fff;
            cursor: pointer;
        }
        .video {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body class="pdgxq-body">
<div class="i-container">
    <div class="jmkt-main">
        <div class="layui-fluid">
            <div class="sp-boxWrap layui-row layui-col-space20">
                <div class="layui-col-lg9 layui-col-md9">
                    <div class="pdgxq-m1-left sp-box">
                        <div class="pdgxq-H">
                            <h3>
                                <i></i>视频实时预览
                            </h3>
                        </div>
                        <div class="sp-tab-bd" style="padding: 5px 10px 15px 10px;">
                            <div class="sp-showBox layui-row show">
                                <div class="layui-col-lg12 layui-col-md12">
                                    <div class="sp-showItem2" onmouseover="showPtz()"
                                         onmouseout="disPtz()">
                                        <!-- ä½¿ç”¨æœ¬åœ°VLC插件播放 -->
                                        <div id="vlcPlayer" style="display: none; width: 100%; height: 100%"></div>
<!--                                        &lt;!&ndash; ä½¿ç”¨æ’­æ”¾å™¨æ’­æ”¾ &ndash;&gt;-->
<!--                                        <easy-player id="easyPlayer" style="display: none;" live="true" show-custom-button="true" auto-play="true" muted="true"></easy-player>-->
<!--                                        &lt;!&ndash; ä½¿ç”¨IFrame播放 &ndash;&gt;-->
<!--                                        <iframe id="iframePlayer" src="" style="display: none;" width="100%" height="100%" allowfullscreen></iframe>-->
                                        <!-- ä½¿ç”¨WebRtc播放 -->
                                        <video class="video" id="video" autoplay="" muted="" playsinline="">
                                        <!-- äº‘台控制 -->
                                        <div class="ptz-block" id="ptz-block" style="opacity: 0;">
                                            <div class="ptzBlock">
                                                <div class="ptz-block-box">
                                                    <div title="上" onmousedown="mouseDownPTZControl(1);"
                                                         onmouseup="mouseUpPTZControl();"
                                                         class="ptz-cell direction ptz-up">
                                                        <i class="layui-icon layui-icon-up"></i>
                                                    </div>
                                                    <div title="å·¦" onmousedown="mouseDownPTZControl(3);"
                                                         onmouseup="mouseUpPTZControl();"
                                                         class="ptz-cell direction ptz-left">
                                                        <i class="layui-icon layui-icon-left"></i>
                                                    </div>
                                                    <div title="云台控制"
                                                         class="ptz-center layui-icon layui-icon-voice"></div>
                                                    <div title="右" onmousedown="mouseDownPTZControl(4);"
                                                         onmouseup="mouseUpPTZControl();"
                                                         class="ptz-cell direction ptz-right">
                                                        <i class="layui-icon layui-icon-right"></i>
                                                    </div>
                                                    <div title="下" onmousedown="mouseDownPTZControl(2);"
                                                         onmouseup="mouseUpPTZControl();"
                                                         class="ptz-cell direction ptz-down">
                                                        <i class="layui-icon layui-icon-down"></i>
                                                    </div>
                                                </div>
                                                <div title="云台速度">
                                                    <div class="ptz-input el-input el-input--mini">
                                                        <input type="number" autocomplete="off" value='120'
                                                               min="0" max="255" class="el-input__inner">
                                                    </div>
                                                </div>
                                                <div title="放大" onmousedown="PTZZoomIn()"
                                                     onmouseup="PTZZoomStop()"
                                                     class="ptz-cell ptz-btn ptz-plus">
                                                    <i class="layui-icon layui-icon-addition"></i>
                                                </div>
                                                <div title="缩小" onmousedown="PTZZoomout()"
                                                     onmouseup="PTZZoomStop()"
                                                     class="ptz-cell ptz-btn ptz-minus">
                                                    <i class="layui-icon layui-icon-subtraction"></i>
                                                </div>
                                            </div>
                                        </div>
                                        <!-- äº‘台控制 END -->
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <!--pdgxq-m1-left end-->
                <div class="layui-col-lg3 layui-col-md3">
                    <div class="pdgxq-m1-right sp-box" style="height: 760px;">
                        <div class="pdgxq-H">
                            <h3>
                                <i></i>设备列表
                            </h3>
                        </div>
                        <div class="sp-table-box">
                            <div class="sp-table">
                                <table class="layui-table pdgxq-table1" lay-skin="nob">
                                    <colgroup>
                                        <col width="70%">
                                        <col width="15%">
                                        <col width="15%">
                                    </colgroup>
                                    <thead>
                                    <tr>
                                        <th>名称</th>
                                        <th>类型</th>
                                        <th>状态</th>
                                    </tr>
                                    </thead>
                                    <tbody id="cameraList">
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
                <!--pdgxq-m1-left end-->
            </div>
            <!--sp-boxWrap end-->
        </div>
    </div>
    <!--jmkt-main end-->
</div>
<!--i-container end-->
<script th:inline="javascript">
    var listCamera = [[${listCamera}]];
</script>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/common/constant.js}"></script>
<script th:src="@{/security/video-list.js}"></script>
</body>
</html>
fzzy-igdss-web/src/main/resources/templates/security/video-webrtc.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,210 @@
<!DOCTYPE html>
<html lang="zh-cn" xmlns:th=http://www.thymeleaf.org>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <title>视频播放-Web-Rtc</title>
    <link rel="stylesheet" th:href="@{/ajax/libs/layui/css/layui.css}"/>
    <link rel="stylesheet" th:href="@{/security/video-webrtc.css}">
    <style>
        .layui-fluid {
            position: relative;
            margin: 0 auto;
            padding: unset;
        }
        .layui-col-space20 {
            margin: unset;
        }
        .layui-col-space20 > * {
            padding: 10px 5px;
        }
        /** éšè—åˆ—表下拉滚动条 **/
        .scroll::-webkit-scrollbar {
            display: none;
        }
        embed {
            width: 100%;
            height: 100%;
        }
        .layui-form-label {
            padding: 9px 10px;
            color: #FFFFFF;
            font-size: 16px;
            margin-left: 20px;
        }
        .layui-input {
            display: unset;
            width: 160px;
            background: #3f474e;
            border-style: solid;
            border-width: 0;
            color: #ffffff;
        }
        .layui-btn {
            padding: 0 15px;
            font-size: 16px;
            margin-left: 10px;
            margin-top: -3px;
        }
        .video {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body class="pdgxq-body">
<div class="i-container">
    <div class="jmkt-main">
        <div class="layui-fluid">
            <div class="sp-boxWrap layui-row layui-col-space20">
                <div class="layui-col-lg9 layui-col-md9">
                    <div class="pdgxq-m1-left sp-box">
                        <div class="sp-tab-bd">
                            <div class="sp-showBox layui-row show">
                                <div class="layui-col-lg12 layui-col-md12">
                                    <div class="sp-showItem2">
                                        <video class="video" id="video" autoplay="" muted="" playsinline="">
                                        </video>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <!--pdgxq-m1-left end-->
                <div class="layui-col-lg3 layui-col-md3">
                    <div class="pdgxq-m1-right sp-box">
                        <div class="pdgxq-H">
                            <h3>
                                <i></i>云台控制
                            </h3>
                        </div>
                        <div class="sp-cz-wrap">
                            <div class="sp-cz-box">
                                <ul>
                                    <li class="sp-cz-l1">
                                        <a href="javascript:;" onmousedown="handPTZ('LeftUp', false)"
                                           onmouseup="handPTZ('LeftUp', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l2">
                                        <a href="javascript:;" onmousedown="handPTZ('Up', false)"
                                           onmouseup="handPTZ('Up', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l3">
                                        <a href="javascript:;" onmousedown="handPTZ('RightUp', false)"
                                           onmouseup="handPTZ('RightUp', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l4">
                                        <a href="javascript:;" onmousedown="handPTZ('Left', false)"
                                           onmouseup="handPTZ('Left', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l5">
                                        <a href="javascript:;" onclick="playStop()">
                                        </a>
                                    </li>
                                    <li class="sp-cz-l6">
                                        <a href="javascript:;" onmousedown="handPTZ('Right', false)"
                                           onmouseup="handPTZ('Right', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l7">
                                        <a href="javascript:;" onmousedown="handPTZ('LeftDown', false)"
                                           onmouseup="handPTZ('LeftDown', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a>
                                    </li>
                                    <li class="sp-cz-l8">
                                        <a href="javascript:;" onmousedown="handPTZ('Down', false)"
                                           onmouseup="handPTZ('Down', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a></li>
                                    <li class="sp-cz-l9">
                                        <a href="javascript:;" onmousedown="handPTZ('RightDown', false)"
                                           onmouseup="handPTZ('RightDown', true)">
                                            <img th:src="@{/img/web/security/sp-arrow.png}"/>
                                        </a></li>
                                </ul>
                            </div>
                            <div class="sp-bianbei fl">
                                <button type="button" class="sp-sxBtn sp-czBtn" onmousedown="handPTZ('ZoomWide', false)" onmouseup="handPTZ('ZoomWide', true)">
                                    <i>-</i>
                                </button>
                                <span>变倍</span>
                                <button type="button" class="sp-fdBtn sp-czBtn" onmousedown="handPTZ('ZoomTele', false)" onmouseup="handPTZ('ZoomTele', true)">
                                    <i>+</i>
                                </button>
                            </div>
                            <div class="sp-bianbei fr">
                                <input type="text" value="预置点" class="preset-input">
                                <button type="button" class="sp-fdBtn sp-czBtn fr"
                                        onclick="handPreset()">
                                    <i>➸</i>
                                </button>
                            </div>
                        </div>
                        <!--sp-cz-wrap end-->
                        <div class="pdgxq-H">
                            <h3>
                                <i></i>设备信息
                            </h3>
                        </div>
                        <div class="sp-table-box">
                            <div class="sp-table">
                                <ul class="sp-list">
                                    <li><a href="javascript:void(0)">
                                        <p>
                                            è®¾å¤‡åç§°ï¼š<span th:text="${cameraData.name}"></span>
                                        </p>
                                    </a></li>
                                    <li><a href="javascript:void(0)">
                                        <p>
                                            è®¾å¤‡ç±»åž‹ï¼š<span th:text="${cameraData.type=='02'?'球机':'枪机'}"></span>
                                        </p>
                                    </a></li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
                <!--pdgxq-m1-left end-->
            </div>
            <!--sp-boxWrap end-->
        </div>
    </div>
    <!--jmkt-main end-->
</div>
<!--i-container end-->
<script th:inline="javascript">
    var cameraData = [[${cameraData}]];
</script>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/security/video-webrtc.js}"></script>
</body>
</html>
fzzy-igdss-web/src/main/resources/templates/security/video.html
ÎļþÒÑɾ³ý