ard-admin/src/main/resources/application-daqing.yml
@@ -55,12 +55,12 @@ #流媒体 mediamtx: apiHost: 192.168.10.103 playHost: 192.168.10.103 pushHost: 192.168.10.103 playHost: 112.98.104.134 https: true pushHost: 192.168.10.103 rtmpPort: 1935 rtspPort: 8554 webrtcPort: 8889 webrtcPort: 28889 # mqtt配置 @@ -88,4 +88,9 @@ # 机场单独用的oss配置,要http地址 dock: endpoint: http://192.168.10.103:9011 bucket: dockfile bucket: dockfile pointCloud: url : https://192.168.10.103:3001/tileset/ type : /tileset.json folder : /home/inspection/uploadPath/zip/ ard-admin/src/main/resources/application-dev.yml
@@ -2,10 +2,12 @@ server: # 服务器的HTTP端口,默认为8080 port: 8080 # token配置 token: # 是否允许账户多终端同时登录(true允许 false不允许) soloLogin: true # 日志配置 logging: level: @@ -23,14 +25,6 @@ enable: false username: admin password: ardkj12345 # MyBatis Plus配置 mybatis-plus: # 搜索指定包别名 typeAliasesPackage: com.ard.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 六合服务器配置 tianyu: @@ -60,13 +54,6 @@ #航线KMZ临时存放路径 waylineSavePath: /home/ard/myworkspace/uav_server/mainserver/waylines # MinIO minio: url: http://192.168.1.15:9001 accessKey: admin secretKey: xzx12345 bucketName: kmz #上云API cloud-api: app: @@ -75,11 +62,16 @@ license: khjd7FzUTzJgaArNv97XdA2nKQtYfESOvBHLqjC6MpvPqxCfuQ82nOlTgzoiLp7UoZujARopN2A1ctPFaJ8oHiHQrn3IRV4wqN3hdSM40xXj02YVvTWQBT54WS8Ks+E8Zatp3gk2T0+7cM5a5a3mWzxLMv7CNqw2z9pFBoOBdpY= host: 192.168.1.15 port: 123 #流媒体 mediamtx: apiHost: 192.168.1.15 playHost: 192.168.1.15 https: false https: true pushHost: 127.0.0.1 rtmpPort: 1935 rtspPort: 8554 webrtcPort: 8889 # mqtt配置 mqtt: @@ -89,4 +81,32 @@ username: admin password: public client-id: liusuyi inbound-topic: sys/product/+/status,thing/product/+/requests inbound-topic: sys/product/+/status,thing/product/+/requests # oss配置 https://192.168.1.3:9001 oss: enable: true provider: minio endpoint: https://127.0.0.1:9001 access-key: admin secret-key: ard12345 bucket: cloud-bucket expire: 3600 region: us-east-1 object-dir-prefix: wayline dock: enable: true provider: minio endpoint: http://127.0.0.1:9011 access-key: admin secret-key: ard12345 bucket: dockfile expire: 3600 region: us-east-1 object-dir-prefix: wayline pointCloud: url : https://127.0.10.1:3001/tileset/ type : /tileset.json folder : /home/inspection/uploadPath/zip/ ard-admin/src/main/resources/application-prod.yml
@@ -62,6 +62,12 @@ rtspPort: 8554 webrtcPort: 8889 #六合流媒体映射 mediamtx-sixhe: enable: true playHost: 112.98.104.134 webrtcPort: 38889 # mqtt配置 mqtt: protocol: tcp @@ -86,4 +92,9 @@ dock: endpoint: http://111.40.46.199:9011 bucket: dockfile bucket: dockfile pointCloud: url : https://192.168.1.3:3001/tileset/ type : /tileset.json folder : /home/inspection/uploadPath/zip/ ard-admin/src/main/resources/application.yml
@@ -118,9 +118,9 @@ servlet: multipart: # 单个文件大小 max-file-size: 3GB max-file-size: 6144MB # 设置总上传的文件大小 max-request-size: 3GB max-request-size: 6144MB # 服务模块 devtools: restart: ard-inspection/src/main/java/com/ard/inspection/service/impl/ArdPointCloudServiceImpl.java
@@ -8,6 +8,7 @@ import com.ard.inspection.domain.NotCould; import com.ard.inspection.utils.ZipFileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.ard.inspection.mapper.ArdPointCloudMapper; import com.ard.inspection.domain.ArdPointCloud; @@ -23,6 +24,9 @@ */ @Service public class ArdPointCloudServiceImpl implements IArdPointCloudService { @Value(value = "${pointCloud.folder}") private String cloudFolder; @Autowired private ArdPointCloudMapper ardPointCloudMapper; @@ -87,11 +91,10 @@ @Override public int deleteArdPointCloudByIds(String[] ids) { // 删除点云文件 String folderPath = "/home/inspection/uploadPath/zip/"; int count = 0; for (String id : ids) { ArdPointCloud ardPointCloud = ardPointCloudMapper.selectArdPointCloudById(id); if (zipFileUtils.deleteZipFile(folderPath + ardPointCloud.getFolderName())){ if (zipFileUtils.deleteZipFile(cloudFolder + ardPointCloud.getFolderName())){ ardPointCloudMapper.deleteArdPointCloudById(id); count++; } ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java
@@ -1,7 +1,6 @@ package com.ard.inspection.service.impl; import com.ard.common.core.domain.AjaxResult; import com.ard.common.utils.uuid.IdUtils; import com.ard.inspection.domain.ArdPointCloud; import com.ard.inspection.domain.UploadFileEntity; import com.ard.inspection.service.IArdPointCloudService; @@ -9,6 +8,7 @@ import com.ard.inspection.utils.ZipFileUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -28,7 +28,11 @@ @Slf4j public class BigFileUploadServiceImpl implements IBigFileUploadService { public static final String CLOUD_FILE_PATH = "https://192.168.1.3:3001/tileset/"; @Value(value = "${pointCloud.url}") private String cloudUrl; @Value(value = "${pointCloud.type}") private String cloudType; @Autowired private IArdPointCloudService ardPointCloudService; @@ -256,7 +260,7 @@ ardPointCloud.setFileSize(formatFileSize(file.getSize())); int dotIndex = originalFilename.lastIndexOf('.'); String folderName = (dotIndex > 0) ? originalFilename.substring(0, dotIndex) : originalFilename; String zipP = CLOUD_FILE_PATH + folderName + "/tileset.json"; String zipP = cloudUrl + folderName + cloudType; ardPointCloud.setFilePath(zipP); ardPointCloud.setFolderName(folderName); return AjaxResult.success("文件上传并解压成功", ardPointCloud); ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -169,6 +169,11 @@ if (ardRouteInfo.getGroupId() == null){ ardRouteInfo.setGroupId("0"); } if ("3".equals(ardRouteInfo.getType())){ ardRouteInfo.getUavRouteReq().setHeightMode("EGM96"); }else { ardRouteInfo.getUavRouteReq().setHeightMode("relativeToStartPoint"); } ardRouteInfo.getUavRouteReq().setDroneType(subStringDroneType(ardRouteInfo.getAircraft())); KmzResultVo kmzResult = routeService.buildKmz(ardRouteInfo.getUavRouteReq(),ardRouteInfo.getName()); zoomProcessing(ardRouteInfo); @@ -465,13 +470,6 @@ // 1.1通过航线数据,转换。 ArdRouteInfo route = ardRouteInfoMapper.selectArdRouteInfoById(id); try { // if ("3".equals(route.getType())) { // UavRouteReq uavRouteReq = new UavRouteReq(); // BeanUtils.copyProperties(deserialize(route.getRouteData()), uavRouteReq); // route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData())); // }else { // route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData())); // } route.setUavRouteReq((UavRouteReq) deserialize(route.getRouteData())); if (route.getCloudData() != null){ route.setArdPointCloudList(deserializeLs(route.getCloudData())); ard-route/src/main/java/com/ard/route/util/InitializationUtils.java
@@ -34,7 +34,8 @@ if (uavRouteReq.getTakeOffRefPoint() == null){ uavRouteReq.setTakeOffRefPoint( uavRouteReq.getRoutePointList().get(0).getLatitude() + "," + uavRouteReq.getRoutePointList().get(0).getLongitude() + "," + "0"); uavRouteReq.getRoutePointList().get(0).getLongitude() + "," + uavRouteReq.getRoutePointList().get(0).getHeight()); } //uavRouteReq.setDroneType(89); uavRouteReq.setSubDroneType(0); @@ -56,7 +57,6 @@ } uavRouteReq.setWaypointTurnReq(waypointTurnReq); uavRouteReq.setGimbalPitchMode("usePointSetting"); uavRouteReq.setHeightMode("EGM96"); if (M350_RTK.getValue().equals(uavRouteReq.getDroneType())) { // 变焦数值加工 buildZoom(uavRouteReq); @@ -91,9 +91,11 @@ * 根据起飞点高度减去当前航点高度 */ public void buildHeight(UavRouteReq uavRouteReq){ double takeOffHeight = getDoublePoint(uavRouteReq.getTakeOffRefPoint(),"alt"); for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) { routePointReq.setHeight(routePointReq.getHeight() - takeOffHeight); if (!"EGM96".equals(uavRouteReq.getHeightMode())){ double takeOffHeight = getDoublePoint(uavRouteReq.getTakeOffRefPoint(),"alt"); for (RoutePointReq routePointReq : uavRouteReq.getRoutePointList()) { routePointReq.setHeight(routePointReq.getHeight() - takeOffHeight); } } } ard-vtdu/src/main/java/com/ard/vtdu/config/MediamtxSixHeConfig.java
New file @@ -0,0 +1,23 @@ package com.ard.vtdu.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; /** * MediamtxConfig * * @author liusuyi * @date 2024年11月09日16:18 **/ @Configuration @Data @ConfigurationProperties(prefix = "mediamtx-sixhe") public class MediamtxSixHeConfig { //是否启动映射转换 private Boolean enable; //播放ip地址 private String playHost; //webrtc端口 private Integer webrtcPort; } ard-vtdu/src/main/java/com/ard/vtdu/service/impl/ArdArdMediaServiceImpl.java
@@ -58,21 +58,23 @@ String protocol = mediamtxConfig.isHttps() ? "https://" : "http://"; String webrtcUrl = protocol + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getWebrtcPort() + "/" + ardVtdu.getName(); String source = ardVtdu.getRtspSource(); Conf conf = new Conf(); conf.setSource(ardVtdu.getRtspSource()); if(!"publisher".equalsIgnoreCase(conf.getSource())) { conf.setSourceOnDemand(true); conf.setName(ardVtdu.getName()); conf.setSource(source); // 如果是拉流则配置按需 if (!"publisher".equalsIgnoreCase(source)) { conf.setSourceOnDemand(true); // 按需拉 conf.setRunOnDemandCloseAfter("5s"); // 无观众 5 秒断开 } conf.setRunOnDemandRestart(false); conf.setRunOnDemandCloseAfter("5s"); conf.setMaxReaders(100); conf.setSourceProtocol("tcp"); if (checkNameExist(ardVtdu.getName())) { mediaClient.removePath(ardVtdu.getName()); if (!checkNameExist(ardVtdu.getName())) { mediaClient.addPath(ardVtdu.getName(), conf); } else { mediaClient.editPath(ardVtdu.getName(), conf); } mediaClient.addPath(ardVtdu.getName(), conf); ardVtdu.setCameraId(ardVtdu.getName().split("_")[0]); ardVtdu.setRtspUrl(rtspUrl); ard-work/src/main/java/com/ard/work/component/websocket/handler/UavStreamManager.java
@@ -2,6 +2,7 @@ import com.alibaba.fastjson2.JSON; import com.ard.vtdu.config.MediamtxSixHeConfig; import com.ard.vtdu.domain.ArdVtdu; import com.ard.work.component.websocket.utils.WebSocketUtil; import com.ard.work.domain.message.BaseMessage; @@ -27,6 +28,8 @@ @Resource private ITyService tyService; @Resource private MediamtxSixHeConfig mediamtxSixHeConfig; // 盒子拉流地址缓存 key:boxSn value: webrtcUrl public static final ConcurrentMap<String, String> BOX_STREAM_PULL_MAP = new ConcurrentHashMap<>(); @@ -123,6 +126,24 @@ if (boxLiveUrl == null) { throw new RuntimeException("未获取到盒子直播地址:" + boxSn); } // 2. 获取原始 URL 字符串 String originalUrl = boxLiveUrl.getRtc(); if (mediamtxSixHeConfig.getEnable() && originalUrl != null && !originalUrl.isEmpty()) { // --- 开始替换逻辑 --- // 配置你的外网地址 String targetHost = mediamtxSixHeConfig.getPlayHost() + ":" + mediamtxSixHeConfig.getWebrtcPort(); // 正则解释: // (^https?://) -> 捕获组1:匹配 http:// 或 https:// // ([^/:]+) -> 捕获组2:匹配 IP 地址或域名 (非 / 和 : 的字符) // (:\d+)? -> 捕获组3:匹配 :端口号 (可选) // (/.*) -> 捕获组4:匹配后面的路径参数 String regex = "(^https?://)([^/:]+)(:\\d+)?(/.*)"; // 替换为:协议 + 外网IP:端口 + 路径 // $1 代表协议, $4 代表路径 String newUrl = originalUrl.replaceAll(regex, "$1" + targetHost + "$4"); // 将新 URL 设置回去 boxLiveUrl.setRtc(newUrl); } boxLiveUrl.setBoxSn(boxSn); return boxLiveUrl; } ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -1,6 +1,7 @@ package com.ard.work.service.impl; import com.ard.common.exception.ControlException; import com.ard.vtdu.config.MediamtxConfig; import com.ard.work.aspect.annotation.CheckControlRight; import com.ard.work.aspect.annotation.CheckDroneStatus; import com.ard.work.aspect.annotation.CheckNoFlyZone; @@ -87,7 +88,8 @@ private RouteStateMachineService stateMachineService; @Autowired private IArdFlightTaskPartService ardFlightTaskPartService; @Resource private MediamtxConfig mediamtxConfig; /** * 获取边缘服务器token信息 *