优化:摄像头编码策略改为基于RTSP流IP生成可读ID
camera_code 从随机UUID改为 cam_{IP下划线分隔}_{4位随机} 格式,
如 cam_192_168_1_100_a3f1,提升可读性和可追溯性。
同步更新新增摄像头和启动回填两处生成逻辑。
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user