‘liusuyi’
2023-05-24 0484a33f0550b344382f0d3caac5b26bbba23ca0
增加按坐标控制云台ptz接口
已添加2个文件
已修改13个文件
671 ■■■■■ 文件已修改
ard-work/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/constant/sdkPriority.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/camera/domain/CameraCmd.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/hikClientService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/hikClientServiceImpl.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/java/com/ruoyi/device/hiksdk/util/hikSdkUtil/GisUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/src/main/resources/templates/test.html 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/target/classes/com/ruoyi/device/camera/domain/CameraCmd.class 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/target/classes/com/ruoyi/device/hiksdk/controller/SdkController.class 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/target/classes/com/ruoyi/device/hiksdk/service/hikClientService.class 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/target/classes/com/ruoyi/device/hiksdk/service/impl/hikClientServiceImpl.class 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/target/classes/templates/test.html 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/SdkOperateAspect.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/target/classes/com/ruoyi/framework/aspectj/SdkOperateAspect.class 补丁 | 查看 | 原始文档 | blame | 历史
ard-work/pom.xml
@@ -93,6 +93,12 @@
            <version>2.0.9</version>
            <scope>compile</scope>
        </dependency>
        <!--张建提供引导依赖-->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
    </dependencies>
</project>
ard-work/src/main/java/com/ruoyi/constant/sdkPriority.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.constant;
/**
 * @Description: sdk控制优先级
 * @ClassName: sdkPriority
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´05月23日11:25
 * @Version: 1.0
 **/
public class sdkPriority {
    static Integer radar_fire = 999;
}
ard-work/src/main/java/com/ruoyi/device/camera/domain/CameraCmd.java
@@ -26,4 +26,8 @@
    Map<String,Double>ptzMap;
    /*过期间隔(分钟)*/
    Integer expired;
    /*相机经纬度*/
    String camPosition;
    /*目标经纬度*/
    String targetPosition;
}
ard-work/src/main/java/com/ruoyi/device/hiksdk/controller/SdkController.java
@@ -163,6 +163,16 @@
        return toAjax(sdk.setPtz(cmd));
    }
    @ApiOperation("指向目标")
    @PostMapping("/setTargetPosition")
    @Log(title = "指向目标", businessType = BusinessType.CONTROL)
    @ApiOperationSupport(includeParameters = {"cmd.cameraId", "cmd.channelNum", "cmd.targetPosition"})
    public @ResponseBody
    AjaxResult setTargetPosition(@RequestBody CameraCmd cmd) {
        return toAjax(sdk.setTargetPosition(cmd));
    }
    @ApiOperation("设置零方位角")
    @PostMapping("/setZeroPTZ")
    @Log(title = "设置零方位角", businessType = BusinessType.CONTROL)
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/hikClientService.java
@@ -15,7 +15,7 @@
 **/
public interface hikClientService {
    void loadHCNetSDKLib();
    boolean setTargetPosition(CameraCmd cmd);
    //登录
    ArdCameras login(ArdCameras cameras);
ard-work/src/main/java/com/ruoyi/device/hiksdk/service/impl/hikClientServiceImpl.java
@@ -9,16 +9,12 @@
import com.ruoyi.device.camera.mapper.ArdCamerasMapper;
import com.ruoyi.device.hiksdk.common.global.globalVariable;
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.device.cameracalibration.domain.ArdCamerasCalibration;
import com.ruoyi.device.hiksdk.domain.recordInfo;
import com.ruoyi.device.cameracalibration.service.IArdCamerasCalibrationService;
import com.ruoyi.device.hiksdk.util.hikSdkUtil.GisUtil;
import com.ruoyi.device.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ruoyi.device.hiksdk.service.hikClientService;
import com.ruoyi.device.hiksdk.util.imageUtil.waterMarkUtil;
import com.ruoyi.device.hiksdk.util.minioUtil.MinioUtil;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
@@ -29,11 +25,8 @@
import sun.misc.BASE64Encoder;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
@@ -240,7 +233,7 @@
     * @修改人和其它信息
     */
    @Override
    @SdkOperate
   // @SdkOperate
    public boolean PTZControlWithSpeed(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();
        boolean enable = cmd.isEnable();
@@ -289,7 +282,6 @@
        }
        return bool;
    }
    /**
     * è®¾ç½®èšç„¦å€¼
@@ -595,6 +587,39 @@
        }
    }
    @Override
    public boolean setTargetPosition(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();
        Integer channelNum = cmd.getChannelNum();
        if (!globalVariable.loginMap.containsKey(cameraId)) {
            return false;
        }
        Integer userId = globalVariable.loginMap.get(cameraId);
        HCNetSDK.NET_DVR_PTZPOS m_ptzPosCurrent = new HCNetSDK.NET_DVR_PTZPOS();
        m_ptzPosCurrent.wAction = 1;
        try {
            double[] cameraPositon = Arrays.stream(cmd.getCamPosition().split(",")).mapToDouble(Double::parseDouble).toArray();
            double[] targetPositions = Arrays.stream(cmd.getTargetPosition().split(",")).mapToDouble(Double::parseDouble).toArray();
            double[] cameraPTZ = GisUtil.getCameraPTZ(cameraPositon, targetPositions, 20, 150);
            String p = String.valueOf((int) ( cameraPTZ[0] * 10));
            String t = String.valueOf((int) ( cameraPTZ[1] * 10));
            String z = String.valueOf((int) (cameraPTZ[2]* 10));
            m_ptzPosCurrent.wPanPos = (short) (Integer.parseInt(p, 16));
            m_ptzPosCurrent.wTiltPos = (short) (Integer.parseInt(t, 16));
            m_ptzPosCurrent.wZoomPos = (short) (Integer.parseInt(z, 16));
            Pointer point = m_ptzPosCurrent.getPointer();
            m_ptzPosCurrent.write();
            boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_PTZPOS, channelNum, point, m_ptzPosCurrent.size());
            if (!bool) {
                int code = hCNetSDK.NET_DVR_GetLastError();
                log.info("设置ptz失败,请稍后重试" + code);
            }
            return bool;
        } catch (Exception ex) {
            log.error(ex.getMessage());
            return false;
        }
    }
    /**
     * @描述 æ“æŽ§é”å®š
     * @参数 [userId, channelNum]
ard-work/src/main/java/com/ruoyi/device/hiksdk/util/hikSdkUtil/GisUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.ruoyi.device.hiksdk.util.hikSdkUtil;
import org.gavaghan.geodesy.*;
import java.math.BigDecimal;
import java.util.Arrays;
public class GisUtil {
    public static GeodeticCalculator geodeticCalculator = new GeodeticCalculator();
    /**
     * æ ¹æ®ç»çº¬åº¦ï¼Œè®¡ç®—两点间的距离
     *
     * @param longitudeFrom ç¬¬ä¸€ä¸ªç‚¹çš„经度
     * @param latitudeFrom  ç¬¬ä¸€ä¸ªç‚¹çš„纬度
     * @param longitudeTo   ç¬¬äºŒä¸ªç‚¹çš„经度
     * @param latitudeTo    ç¬¬äºŒä¸ªç‚¹çš„纬度
     * @return è¿”回距离 å•位米
     */
    public static double getDistance(double longitudeFrom, double latitudeFrom, double longitudeTo, double latitudeTo) {
        GlobalCoordinates source = new GlobalCoordinates(latitudeFrom, longitudeFrom);
        GlobalCoordinates target = new GlobalCoordinates(latitudeTo, longitudeTo);
        return geodeticCalculator.calculateGeodeticCurve(Ellipsoid.WGS84, source, target).getEllipsoidalDistance();
    }
    /**
     * è®¡ç®—从from到to方向的直线与正北方向夹角
     *
     * @param longitudeFrom ç¬¬ä¸€ä¸ªç‚¹çš„经度
     * @param latitudeFrom  ç¬¬ä¸€ä¸ªç‚¹çš„纬度
     * @param longitudeTo   ç¬¬äºŒä¸ªç‚¹çš„经度
     * @param latitudeTo    ç¬¬äºŒä¸ªç‚¹çš„纬度
     * @return è¿”回角度
     */
    public static double getNorthAngle(double longitudeFrom, double latitudeFrom, double longitudeTo, double latitudeTo) {
        GlobalPosition source = new GlobalPosition(latitudeFrom, longitudeFrom, 0);
        GlobalPosition target = new GlobalPosition(latitudeTo, longitudeTo, 0);
        return geodeticCalculator.calculateGeodeticMeasurement(Ellipsoid.WGS84, source, target).getAzimuth();
    }
    /**
     * @param camera    ç»åº¦,纬度,高度 å¦‚:{125.097531, 46.60029, 120};
     * @param lookAt    ç»åº¦,纬度,高度 å¦‚:{125.124731, 46.584808, 0};
     * @param viewAngle ç›¸æœºå¯è§†è§’度 å¦‚:20
     * @param viewWidth è§†åŸŸå®½åº¦ å¦‚:150
     * @return ptz æ•°ç»„ å¦‚:[129.5355798969157, -2.5419097807416655, 23.3676043024458]
     */
    public static double[] getCameraPTZ(double[] camera, double[] lookAt, double viewAngle, double viewWidth) {
        double p = 0, t = 0, z = 0;
        double distance = GisUtil.getDistance(camera[0], camera[1], lookAt[0], lookAt[1]);
        double northAngle = GisUtil.getNorthAngle(camera[0], camera[1], lookAt[0], lookAt[1]);
        double height = camera[2] - lookAt[2];
        p = northAngle;
        t = Angle.toDegrees(Math.atan(height / distance)) * -1+360;
        z = distance * Math.tan(viewAngle / 2) * 2 / viewWidth;
      /*  p = new BigDecimal(p).setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
        t = new BigDecimal(t).setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();
        z = new BigDecimal(z).setScale(1,BigDecimal.ROUND_HALF_UP).doubleValue();*/
        return new double[]{p, t, z};
    }
    public static void main(String[] args) {
        // 125.097531,46.60029, 125.124731,46.584808
        //相机位置
        double[] camera = {125.146964331147,46.5580925811216,102};//经度,纬度,高度
        //看向的位置
        double[] lookAt = {125.155449,46.555108,0};//经度,纬度,高度
        double viewAngle = 20;//相机可视角度
        double viewWidth = 150;//相机视域宽度
        double[] ptz = GisUtil.getCameraPTZ(camera, lookAt, viewAngle, viewWidth);
        System.out.println("ptz:" + Arrays.toString(ptz));
    }
}
ard-work/src/main/resources/templates/test.html
@@ -9,115 +9,127 @@
    <link rel="stylesheet" th:href="@{/css/bootstrap.css}"/>
    <script th:src="@{/js/bootstrap.js}"></script>
    <style>
    .top-buffer { margin-top:10px; }
        .top-buffer {
            margin-top: 10px;
        }
    </style>
<body>
<div class="container">
        <div class="row ">
            <div class="dropdown">
                ç›¸æœºid:
                <select id="select">
                </select>
            </div>
    <div class="row ">
        <div class="dropdown">
            ç›¸æœºid:<select id="select">
        </select>
        </div>
        <div class="row top-buffer">
            <div class="col-md-1 col-md-offset-1">
                <button id="up" type="button" class="btn btn-primary">上</button>
            </div>
            <div class="col-md-4 col-md-offset-3">
                <div class="btn-group" role="group">
                    <button id="controlZoomIn" type="button" class="btn btn-primary">调焦-</button>
                    <button id="controlZoomOut" type="button" class="btn btn-primary">调焦+</button>
                </div>
            </div>
    </div>
    <div class="row top-buffer">
        <div class="col-md-1 col-md-offset-1">
            <button id="up" type="button" class="btn btn-primary">上</button>
        </div>
        <div class="row ">
            <div class="col-md-1">
                <button id="left" type="button" class="btn btn-primary">å·¦</button>
            </div>
            <div class="col-md-1 col-md-offset-1">
                <button id="right" type="button" class="btn btn-primary">右</button>
            </div>
            <div class="col-md-4 col-md-offset-2">
                <div class="btn-group" role="group">
                    <button id="controlFocusNear" type="button" class="btn btn-primary">聚焦-</button>
                    <button id="controlFocusFar" type="button" class="btn btn-primary">聚焦+</button>
                </div>
            </div>
        </div>
        <div class="row ">
            <div class="col-md-1 col-md-offset-1">
                <button id="down" type="button" class="btn btn-primary">下</button>
            </div>
            <div class="col-md-4 col-md-offset-3">
                <div class="btn-group" role="group">
                    <button id="controlIrisOpen" type="button" class="btn btn-primary">光圈-</button>
                    <button id="controlIrisClose" type="button" class="btn btn-primary">光圈+</button>
                </div>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="input-group">
                <span class="input-group-addon">P值:</span>
                <input id="p" class="form-control" placeholder="请输入P值"/>
            </div>
            <div class="input-group">
                <span class="input-group-addon">T值:</span>
                <input id="t" class="form-control" placeholder="请输入T值"/>
            </div>
            <div class="input-group">
                <span class="input-group-addon">Z值:</span>
                <input id="z" class="form-control" placeholder="请输入Z值"/>
            </div>
        </div>
        <div class="row top-buffer">
        <div class="col-md-4 col-md-offset-3">
            <div class="btn-group" role="group">
                <button id="getPTZ" type="button" class="btn btn-default">获取ptz</button>
                <button id="setPTZ" type="button" class="btn btn-default">设置ptz</button>
                <button id="setPreset" type="button" class="btn btn-default">设预置点</button>
                <button id="gotoPreset" type="button" class="btn btn-default">调预置点</button>
                <button id="getZeroPTZ" type="button" class="btn btn-default">调用零方位角</button>
                <button id="setZeroPTZ" type="button" class="btn btn-default">设置零方位角</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="FocusMode" type="button" class="btn btn-default">手动聚焦</button>
                <div id="focusDiv" class="input-group">
                    <span class="input-group-addon">聚焦值:</span>
                    <input id="focus" class="form-control" placeholder="聚焦值"/>
                </div>
                <button id="getFocusPos" type="button" class="btn btn-default">获取聚焦值</button>
                <button id="setFocusPos" type="button" class="btn btn-default">设置聚焦值</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="WiperPwron" type="button" class="btn btn-default">开启雨刷</button>
                <button id="Defogcfg" type="button" class="btn btn-default">开启透雾</button>
                <button id="Infrarecfg" type="button" class="btn btn-default">开启红外</button>
                <button id="HeateRpwron" type="button" class="btn btn-default">开启云台加热</button>
                <button id="CameraDeicing" type="button" class="btn btn-default">开启镜头加热</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="voice" type="button" class="btn btn-default">开始语音对讲</button>
                <button id="record" type="button" class="btn btn-default">开始录像</button>
                <button id="realCutPic" type="button" class="btn btn-default">实时抓图</button>
                <button id="saveCutPic" type="button" class="btn btn-default">存储抓图</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="col-md-6">
                <img class="thumbnail" id="imgContainer" style="width: 500px; height: 400px;padding: 5px 5px;"/>
            </div>
            <div class="col-md-6">
                <video id="video" muted autoplay loop controls  style="width: 800px; height: 100%; object-fit: fill" />
                <button id="controlZoomIn" type="button" class="btn btn-primary">调焦-</button>
                <button id="controlZoomOut" type="button" class="btn btn-primary">调焦+</button>
            </div>
        </div>
    </div>
</body>
    <div class="row ">
        <div class="col-md-1">
            <button id="left" type="button" class="btn btn-primary">å·¦</button>
        </div>
        <div class="col-md-1 col-md-offset-1">
            <button id="right" type="button" class="btn btn-primary">右</button>
        </div>
        <div class="col-md-4 col-md-offset-2">
            <div class="btn-group" role="group">
                <button id="controlFocusNear" type="button" class="btn btn-primary">聚焦-</button>
                <button id="controlFocusFar" type="button" class="btn btn-primary">聚焦+</button>
            </div>
        </div>
    </div>
    <div class="row ">
        <div class="col-md-1 col-md-offset-1">
            <button id="down" type="button" class="btn btn-primary">下</button>
        </div>
        <div class="col-md-4 col-md-offset-3">
            <div class="btn-group" role="group">
                <button id="controlIrisOpen" type="button" class="btn btn-primary">光圈-</button>
                <button id="controlIrisClose" type="button" class="btn btn-primary">光圈+</button>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="row top-buffer">
                <div class="input-group">
                    <span class="input-group-addon">目的坐标值:</span>
                    <input id="targetPostion" class="form-control" placeholder="目的坐标"/>
                    <button id="setTargetPostion" type="button" class="btn btn-default">指向坐标</button>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">P值:</span>
                    <input id="p" class="form-control" placeholder="请输入P值"/>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">T值:</span>
                    <input id="t" class="form-control" placeholder="请输入T值"/>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">Z值:</span>
                    <input id="z" class="form-control" placeholder="请输入Z值"/>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="getPTZ" type="button" class="btn btn-default">获取ptz</button>
                    <button id="setPTZ" type="button" class="btn btn-default">设置ptz</button>
                    <button id="setPreset" type="button" class="btn btn-default">设预置点</button>
                    <button id="gotoPreset" type="button" class="btn btn-default">调预置点</button>
                    <button id="getZeroPTZ" type="button" class="btn btn-default">调用零方位角</button>
                    <button id="setZeroPTZ" type="button" class="btn btn-default">设置零方位角</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="FocusMode" type="button" class="btn btn-default">手动聚焦</button>
                    <div id="focusDiv" class="input-group">
                        <span class="input-group-addon">聚焦值:</span>
                        <input id="focus" class="form-control" placeholder="聚焦值"/>
                    </div>
                    <button id="getFocusPos" type="button" class="btn btn-default">获取聚焦值</button>
                    <button id="setFocusPos" type="button" class="btn btn-default">设置聚焦值</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="WiperPwron" type="button" class="btn btn-default">开启雨刷</button>
                    <button id="Defogcfg" type="button" class="btn btn-default">开启透雾</button>
                    <button id="Infrarecfg" type="button" class="btn btn-default">开启红外</button>
                    <button id="HeateRpwron" type="button" class="btn btn-default">开启云台加热</button>
                    <button id="CameraDeicing" type="button" class="btn btn-default">开启镜头加热</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="voice" type="button" class="btn btn-default">开始语音对讲</button>
                    <button id="record" type="button" class="btn btn-default">开始录像</button>
                    <button id="realCutPic" type="button" class="btn btn-default">实时抓图</button>
                    <button id="saveCutPic" type="button" class="btn btn-default">存储抓图</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="col-md-6">
                    <img class="thumbnail" id="imgContainer" style="width: 500px; height: 300px;"/>
                </div>
            </div>
        </div>
        <div class="col-md-1"/>
        <div class="col-md-5">
            <div class="row top-buffer">
                <video id="video" muted autoplay loop controls style="width: 800px; height: 100%; object-fit: fill;"/>
            </div>
        </div>
    </div>
</div>
<script th:inline="javascript">
    var cameraId, opt, token;
    window.onload = function () {
@@ -134,7 +146,10 @@
                        ipaddr: arr[i].ip,
                        username: arr[i].username,
                        password: arr[i].password,
                        port: arr[i].rtspPort
                        port: arr[i].rtspPort,
                        longitude: arr[i].longitude,
                        latitude: arr[i].latitude,
                        altitude: arr[i].altitude
                    };
                    cameraMap.set(arr[i].id, camera);
                    //先创建好select里面的option元素
@@ -371,6 +386,34 @@
                'Authorization': token
            },
            url: "../hik/setPTZ",
            type: "post",
            dataType: "json",
            data: JSON.stringify(myEntity),
            success: function (data) {
                console.log(data);
            }
        })
    })
    $("#setTargetPostion").click(function () {
        cameraId = $('#select option:selected').val();
        var camera = cameraMap.get(cameraId);
        var camP = camera.longitude + ',' + camera.latitude + ',' + camera.altitude;
        var targetP = $('#targetPostion').val();
        //定义一个带有Map字段的实体对象
        var myEntity = {
            channelNum: 1,
            cameraId: cameraId,
            targetPosition: targetP,
            camPosition: camP,
        };
        console.log(myEntity)
        $.ajax({
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': token
            },
            url: "../hik/setTargetPosition",
            type: "post",
            dataType: "json",
            data: JSON.stringify(myEntity),
@@ -636,7 +679,7 @@
            data: JSON.stringify(opt),
            success: function (data) {
                console.log(data.data);
                $("#imgContainer").attr("src","data:image/png;base64,"+data.data);
                $("#imgContainer").attr("src", "data:image/png;base64," + data.data);
            }
        })
    })
@@ -722,6 +765,7 @@
            }
        })
    }
    let webRtcServer = null;
    let videoMap = new Map();
    $('video').click(function (e) {
@@ -738,7 +782,7 @@
            } else if (camera.type == "dh") {
                realViewDh("127.0.0.1", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else {
                realViewHik("192.168.1.15", ID, camera.username, camera.password, camera.ipaddr,  camera.port);
                realViewHik("192.168.1.15", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            }
        }
    });
@@ -784,4 +828,5 @@
        webRtcServer.disconnect();
    }
</script>
</body>
</html>
ard-work/target/classes/com/ruoyi/device/camera/domain/CameraCmd.class
Binary files differ
ard-work/target/classes/com/ruoyi/device/hiksdk/controller/SdkController.class
Binary files differ
ard-work/target/classes/com/ruoyi/device/hiksdk/service/hikClientService.class
Binary files differ
ard-work/target/classes/com/ruoyi/device/hiksdk/service/impl/hikClientServiceImpl.class
Binary files differ
ard-work/target/classes/templates/test.html
@@ -9,115 +9,127 @@
    <link rel="stylesheet" th:href="@{/css/bootstrap.css}"/>
    <script th:src="@{/js/bootstrap.js}"></script>
    <style>
    .top-buffer { margin-top:10px; }
        .top-buffer {
            margin-top: 10px;
        }
    </style>
<body>
<div class="container">
        <div class="row ">
            <div class="dropdown">
                ç›¸æœºid:
                <select id="select">
                </select>
            </div>
    <div class="row ">
        <div class="dropdown">
            ç›¸æœºid:<select id="select">
        </select>
        </div>
        <div class="row top-buffer">
            <div class="col-md-1 col-md-offset-1">
                <button id="up" type="button" class="btn btn-primary">上</button>
            </div>
            <div class="col-md-4 col-md-offset-3">
                <div class="btn-group" role="group">
                    <button id="controlZoomIn" type="button" class="btn btn-primary">调焦-</button>
                    <button id="controlZoomOut" type="button" class="btn btn-primary">调焦+</button>
                </div>
            </div>
    </div>
    <div class="row top-buffer">
        <div class="col-md-1 col-md-offset-1">
            <button id="up" type="button" class="btn btn-primary">上</button>
        </div>
        <div class="row ">
            <div class="col-md-1">
                <button id="left" type="button" class="btn btn-primary">å·¦</button>
            </div>
            <div class="col-md-1 col-md-offset-1">
                <button id="right" type="button" class="btn btn-primary">右</button>
            </div>
            <div class="col-md-4 col-md-offset-2">
                <div class="btn-group" role="group">
                    <button id="controlFocusNear" type="button" class="btn btn-primary">聚焦-</button>
                    <button id="controlFocusFar" type="button" class="btn btn-primary">聚焦+</button>
                </div>
            </div>
        </div>
        <div class="row ">
            <div class="col-md-1 col-md-offset-1">
                <button id="down" type="button" class="btn btn-primary">下</button>
            </div>
            <div class="col-md-4 col-md-offset-3">
                <div class="btn-group" role="group">
                    <button id="controlIrisOpen" type="button" class="btn btn-primary">光圈-</button>
                    <button id="controlIrisClose" type="button" class="btn btn-primary">光圈+</button>
                </div>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="input-group">
                <span class="input-group-addon">P值:</span>
                <input id="p" class="form-control" placeholder="请输入P值"/>
            </div>
            <div class="input-group">
                <span class="input-group-addon">T值:</span>
                <input id="t" class="form-control" placeholder="请输入T值"/>
            </div>
            <div class="input-group">
                <span class="input-group-addon">Z值:</span>
                <input id="z" class="form-control" placeholder="请输入Z值"/>
            </div>
        </div>
        <div class="row top-buffer">
        <div class="col-md-4 col-md-offset-3">
            <div class="btn-group" role="group">
                <button id="getPTZ" type="button" class="btn btn-default">获取ptz</button>
                <button id="setPTZ" type="button" class="btn btn-default">设置ptz</button>
                <button id="setPreset" type="button" class="btn btn-default">设预置点</button>
                <button id="gotoPreset" type="button" class="btn btn-default">调预置点</button>
                <button id="getZeroPTZ" type="button" class="btn btn-default">调用零方位角</button>
                <button id="setZeroPTZ" type="button" class="btn btn-default">设置零方位角</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="FocusMode" type="button" class="btn btn-default">手动聚焦</button>
                <div id="focusDiv" class="input-group">
                    <span class="input-group-addon">聚焦值:</span>
                    <input id="focus" class="form-control" placeholder="聚焦值"/>
                </div>
                <button id="getFocusPos" type="button" class="btn btn-default">获取聚焦值</button>
                <button id="setFocusPos" type="button" class="btn btn-default">设置聚焦值</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="WiperPwron" type="button" class="btn btn-default">开启雨刷</button>
                <button id="Defogcfg" type="button" class="btn btn-default">开启透雾</button>
                <button id="Infrarecfg" type="button" class="btn btn-default">开启红外</button>
                <button id="HeateRpwron" type="button" class="btn btn-default">开启云台加热</button>
                <button id="CameraDeicing" type="button" class="btn btn-default">开启镜头加热</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="btn-group" role="group">
                <button id="voice" type="button" class="btn btn-default">开始语音对讲</button>
                <button id="record" type="button" class="btn btn-default">开始录像</button>
                <button id="realCutPic" type="button" class="btn btn-default">实时抓图</button>
                <button id="saveCutPic" type="button" class="btn btn-default">存储抓图</button>
            </div>
        </div>
        <div class="row top-buffer">
            <div class="col-md-6">
                <img class="thumbnail" id="imgContainer" style="width: 500px; height: 400px;padding: 5px 5px;"/>
            </div>
            <div class="col-md-6">
                <video id="video" muted autoplay loop controls  style="width: 800px; height: 100%; object-fit: fill" />
                <button id="controlZoomIn" type="button" class="btn btn-primary">调焦-</button>
                <button id="controlZoomOut" type="button" class="btn btn-primary">调焦+</button>
            </div>
        </div>
    </div>
</body>
    <div class="row ">
        <div class="col-md-1">
            <button id="left" type="button" class="btn btn-primary">å·¦</button>
        </div>
        <div class="col-md-1 col-md-offset-1">
            <button id="right" type="button" class="btn btn-primary">右</button>
        </div>
        <div class="col-md-4 col-md-offset-2">
            <div class="btn-group" role="group">
                <button id="controlFocusNear" type="button" class="btn btn-primary">聚焦-</button>
                <button id="controlFocusFar" type="button" class="btn btn-primary">聚焦+</button>
            </div>
        </div>
    </div>
    <div class="row ">
        <div class="col-md-1 col-md-offset-1">
            <button id="down" type="button" class="btn btn-primary">下</button>
        </div>
        <div class="col-md-4 col-md-offset-3">
            <div class="btn-group" role="group">
                <button id="controlIrisOpen" type="button" class="btn btn-primary">光圈-</button>
                <button id="controlIrisClose" type="button" class="btn btn-primary">光圈+</button>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="row top-buffer">
                <div class="input-group">
                    <span class="input-group-addon">目的坐标值:</span>
                    <input id="targetPostion" class="form-control" placeholder="目的坐标"/>
                    <button id="setTargetPostion" type="button" class="btn btn-default">指向坐标</button>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">P值:</span>
                    <input id="p" class="form-control" placeholder="请输入P值"/>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">T值:</span>
                    <input id="t" class="form-control" placeholder="请输入T值"/>
                </div>
                <div class="input-group">
                    <span class="input-group-addon">Z值:</span>
                    <input id="z" class="form-control" placeholder="请输入Z值"/>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="getPTZ" type="button" class="btn btn-default">获取ptz</button>
                    <button id="setPTZ" type="button" class="btn btn-default">设置ptz</button>
                    <button id="setPreset" type="button" class="btn btn-default">设预置点</button>
                    <button id="gotoPreset" type="button" class="btn btn-default">调预置点</button>
                    <button id="getZeroPTZ" type="button" class="btn btn-default">调用零方位角</button>
                    <button id="setZeroPTZ" type="button" class="btn btn-default">设置零方位角</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="FocusMode" type="button" class="btn btn-default">手动聚焦</button>
                    <div id="focusDiv" class="input-group">
                        <span class="input-group-addon">聚焦值:</span>
                        <input id="focus" class="form-control" placeholder="聚焦值"/>
                    </div>
                    <button id="getFocusPos" type="button" class="btn btn-default">获取聚焦值</button>
                    <button id="setFocusPos" type="button" class="btn btn-default">设置聚焦值</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="WiperPwron" type="button" class="btn btn-default">开启雨刷</button>
                    <button id="Defogcfg" type="button" class="btn btn-default">开启透雾</button>
                    <button id="Infrarecfg" type="button" class="btn btn-default">开启红外</button>
                    <button id="HeateRpwron" type="button" class="btn btn-default">开启云台加热</button>
                    <button id="CameraDeicing" type="button" class="btn btn-default">开启镜头加热</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="btn-group" role="group">
                    <button id="voice" type="button" class="btn btn-default">开始语音对讲</button>
                    <button id="record" type="button" class="btn btn-default">开始录像</button>
                    <button id="realCutPic" type="button" class="btn btn-default">实时抓图</button>
                    <button id="saveCutPic" type="button" class="btn btn-default">存储抓图</button>
                </div>
            </div>
            <div class="row top-buffer">
                <div class="col-md-6">
                    <img class="thumbnail" id="imgContainer" style="width: 500px; height: 300px;"/>
                </div>
            </div>
        </div>
        <div class="col-md-1"/>
        <div class="col-md-5">
            <div class="row top-buffer">
                <video id="video" muted autoplay loop controls style="width: 800px; height: 100%; object-fit: fill;"/>
            </div>
        </div>
    </div>
</div>
<script th:inline="javascript">
    var cameraId, opt, token;
    window.onload = function () {
@@ -134,7 +146,10 @@
                        ipaddr: arr[i].ip,
                        username: arr[i].username,
                        password: arr[i].password,
                        port: arr[i].rtspPort
                        port: arr[i].rtspPort,
                        longitude: arr[i].longitude,
                        latitude: arr[i].latitude,
                        altitude: arr[i].altitude
                    };
                    cameraMap.set(arr[i].id, camera);
                    //先创建好select里面的option元素
@@ -371,6 +386,34 @@
                'Authorization': token
            },
            url: "../hik/setPTZ",
            type: "post",
            dataType: "json",
            data: JSON.stringify(myEntity),
            success: function (data) {
                console.log(data);
            }
        })
    })
    $("#setTargetPostion").click(function () {
        cameraId = $('#select option:selected').val();
        var camera = cameraMap.get(cameraId);
        var camP = camera.longitude + ',' + camera.latitude + ',' + camera.altitude;
        var targetP = $('#targetPostion').val();
        //定义一个带有Map字段的实体对象
        var myEntity = {
            channelNum: 1,
            cameraId: cameraId,
            targetPosition: targetP,
            camPosition: camP,
        };
        console.log(myEntity)
        $.ajax({
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': token
            },
            url: "../hik/setTargetPosition",
            type: "post",
            dataType: "json",
            data: JSON.stringify(myEntity),
@@ -636,7 +679,7 @@
            data: JSON.stringify(opt),
            success: function (data) {
                console.log(data.data);
                $("#imgContainer").attr("src","data:image/png;base64,"+data.data);
                $("#imgContainer").attr("src", "data:image/png;base64," + data.data);
            }
        })
    })
@@ -722,6 +765,7 @@
            }
        })
    }
    let webRtcServer = null;
    let videoMap = new Map();
    $('video').click(function (e) {
@@ -738,7 +782,7 @@
            } else if (camera.type == "dh") {
                realViewDh("127.0.0.1", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else {
                realViewHik("192.168.1.15", ID, camera.username, camera.password, camera.ipaddr,  camera.port);
                realViewHik("192.168.1.15", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            }
        }
    });
@@ -784,4 +828,5 @@
        webRtcServer.disconnect();
    }
</script>
</body>
</html>
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/SdkOperateAspect.java
@@ -1,7 +1,5 @@
package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.SdkOperate;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
@@ -9,19 +7,13 @@
import com.ruoyi.device.camera.domain.ArdCameras;
import com.ruoyi.device.camera.domain.CameraCmd;
import com.ruoyi.device.camera.service.IArdCamerasService;
import com.ruoyi.system.service.ISysUserService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * SDK控制处理
@@ -42,7 +34,6 @@
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Boolean resultMap = dataScopeFilter(point);
        if (resultMap) {
            return point.proceed();
@@ -57,16 +48,18 @@
     * @param joinPoint åˆ‡ç‚¹
     */
    public Boolean dataScopeFilter(ProceedingJoinPoint joinPoint) {
        //获取请求控制相机的信息
        CameraCmd cmd = (CameraCmd) joinPoint.getArgs()[0];
        ArdCameras ardCameras = ardCamerasService.selectArdCamerasById(cmd.getCameraId());
        if (StringUtils.isNull(ardCameras)) {
            return false;
        }
        //优先级比对
        Date operatorExpired = ardCameras.getOperatorExpired();
        Date now = new Date();
        if (now.before(operatorExpired)) {
            //未过期
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (StringUtils.isNull(loginUser)) {
                return false;//当前登录用户为空不可以控制
ruoyi-framework/target/classes/com/ruoyi/framework/aspectj/SdkOperateAspect.class
Binary files differ