diff --git a/src/main/java/com/genersoft/iot/vmp/aiot/service/impl/AiConfigServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/aiot/service/impl/AiConfigServiceImpl.java index 134f64bff..ce6f0177e 100644 --- a/src/main/java/com/genersoft/iot/vmp/aiot/service/impl/AiConfigServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/aiot/service/impl/AiConfigServiceImpl.java @@ -104,7 +104,7 @@ public class AiConfigServiceImpl implements IAiConfigService { } int backfilled = 0; for (StreamProxy proxy : nullCodeProxies) { - String cameraCode = "cam_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12); + String cameraCode = generateCameraCodeFromUrl(proxy.getSrcUrl()); streamProxyMapper.updateCameraCode(proxy.getId(), cameraCode); backfilled++; log.info("[AiConfig] 回填 camera_code: id={}, app={}, stream={} → {}", @@ -116,6 +116,34 @@ public class AiConfigServiceImpl implements IAiConfigService { } } + /** + * 从 RTSP URL 中提取 IP/Host,生成可读的 camera_code + * 格式:cam_{host简写}_{4位随机} + * 例:rtsp://admin:pwd@192.168.1.100:554/stream → cam_192_168_1_100_a3f1 + */ + private String generateCameraCodeFromUrl(String srcUrl) { + String hostPart = "unknown"; + if (srcUrl != null && !srcUrl.isEmpty()) { + try { + String urlBody = srcUrl; + int schemeEnd = urlBody.indexOf("://"); + if (schemeEnd >= 0) { + urlBody = urlBody.substring(schemeEnd + 3); + } + int atIndex = urlBody.indexOf('@'); + if (atIndex >= 0) { + urlBody = urlBody.substring(atIndex + 1); + } + String host = urlBody.split("[:/]")[0]; + hostPart = host.replace(".", "_"); + } catch (Exception e) { + hostPart = "unknown"; + } + } + String suffix = UUID.randomUUID().toString().replace("-", "").substring(0, 4); + return "cam_" + hostPart + "_" + suffix; + } + /** * 修复 ROI 表中仍使用 app/stream 格式的 camera_id,替换为对应的 camera_code * 例如: camera_id="live/camera01" → camera_id="cam_a1b2c3d4e5f6" diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java index e62ad0127..5d693d271 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java @@ -80,12 +80,38 @@ public class StreamProxyServiceImpl implements IStreamProxyService { private IAiRedisConfigService redisConfigService; /** - * 生成唯一的 camera_code - * 格式:cam_xxxxxxxxxxxx(12位随机字符) + * 从 RTSP URL 中提取 IP/Host 特征,生成可读的 camera_code + * 格式:cam_{host简写}_{4位随机} + * 例:rtsp://admin:pwd@192.168.1.100:554/stream → cam_192_168_1_100_a3f1 + * rtsp://10.0.0.5:554/live → cam_10_0_0_5_b2e4 + * @param srcUrl RTSP 拉流地址 * @return 唯一的 camera_code */ - private String generateCameraCode() { - return "cam_" + UUID.randomUUID().toString().replace("-", "").substring(0, 12); + private String generateCameraCode(String srcUrl) { + String hostPart = "unknown"; + if (srcUrl != null && !srcUrl.isEmpty()) { + try { + // 去掉 rtsp:// 前缀 + String urlBody = srcUrl; + int schemeEnd = urlBody.indexOf("://"); + if (schemeEnd >= 0) { + urlBody = urlBody.substring(schemeEnd + 3); + } + // 去掉 user:pass@ 部分 + int atIndex = urlBody.indexOf('@'); + if (atIndex >= 0) { + urlBody = urlBody.substring(atIndex + 1); + } + // 提取 host(去掉端口和路径) + String host = urlBody.split("[:/]")[0]; + // 将 . 替换为 _ 作为可读标识 + hostPart = host.replace(".", "_"); + } catch (Exception e) { + hostPart = "unknown"; + } + } + String suffix = UUID.randomUUID().toString().replace("-", "").substring(0, 4); + return "cam_" + hostPart + "_" + suffix; } /** @@ -162,7 +188,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { // 自动生成 camera_code(最多重试3次避免冲突) int retryCount = 0; while (retryCount < 3) { - String cameraCode = generateCameraCode(); + String cameraCode = generateCameraCode(streamProxy.getSrcUrl()); streamProxy.setCameraCode(cameraCode); streamProxy.setCreateTime(DateUtil.getNow());