| | |
| | | @Slf4j |
| | | @Service |
| | | public class ArdChannelServiceImpl implements IArdChannelService { |
| | | // @Resource |
| | | //private IArdCameraService ardCameraService; |
| | | |
| | | @Resource |
| | | private ArdChannelMapper ardChannelMapper; |
| | | @Resource |
| | | private RedisCache redisCache; |
| | | @Resource |
| | | private IArdVtduService ardVtduService; |
| | | @Resource |
| | | private MediamtxConfig mediamtxConfig; |
| | | @Resource |
| | | private RedisCache redisCache; |
| | | |
| | | /** |
| | | * 查询通道管理 |
| | | * |
| | |
| | | } |
| | | |
| | | |
| | | @Scheduled(fixedDelay = 5000) |
| | | /** |
| | | * 同步通道流媒体 |
| | | */ |
| | | @Scheduled(cron = "0/10 * * * * ?") |
| | | public void syncVtdu() { |
| | | log.debug("定时同步Vtdu任务"); |
| | | List<ArdChannel> channels = this.selectArdChannelList(new ArdChannel()); |
| | | if (channels == null || channels.isEmpty()) { |
| | | // log.warn("没有获取到通道数据,退出同步"); |
| | | return; |
| | | } |
| | | List<ArdVtdu> ardVtduList = ardVtduService.selectArdVtduList(new ArdVtdu()); |
| | | try { |
| | | ArdChannel ardChannel = new ArdChannel(); |
| | | ardChannel.setUseDataScope(false); |
| | | List<ArdChannel> channels = this.selectArdChannelList(ardChannel); |
| | | if (channels == null || channels.isEmpty()) { |
| | | // log.warn("没有获取到通道数据,退出同步"); |
| | | return; |
| | | } |
| | | List<ArdVtdu> ardVtduList = ardVtduService.selectArdVtduList(new ArdVtdu()); |
| | | |
| | | Set<String> validNames = channels.stream() |
| | | .map(channel -> channel.getDeviceId() + "_" + channel.getChanNo()) |
| | | .collect(Collectors.toSet()); |
| | | // 2. 合并操作:增、删、改 |
| | | channels.forEach(channel -> { |
| | | String name = channel.getDeviceId() + "_" + channel.getChanNo(); // 生成媒体表的 name |
| | | String cameraId = channel.getDeviceId(); // cameraId 就是通道的 deviceId |
| | | String rtspSourceUrl = getRtspSource(channel); |
| | | String rtspUrl = |
| | | "rtsp://" + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getRtspPort() + "/" + name; // |
| | | // 拼接 webrtcUrl |
| | | String rtmpUrl = |
| | | "rtmp://" + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getRtmpPort() + "/" + name; // 拼接 |
| | | // webrtcUrl |
| | | String protocol = mediamtxConfig.isHttps() ? "https://" : "http://"; |
| | | String webrtcUrl = |
| | | protocol + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getWebrtcPort() + "/" + name; |
| | | // 拼接 webrtcUrl |
| | | Set<String> validNames = channels.stream() |
| | | .map(channel -> channel.getDeviceId() + "_" + channel.getChanNo()) |
| | | .collect(Collectors.toSet()); |
| | | // 2. 合并操作:增、删、改 |
| | | channels.forEach(channel -> { |
| | | String name = channel.getDeviceId() + "_" + channel.getChanNo(); // 生成媒体表的 name |
| | | String cameraId = channel.getDeviceId(); // cameraId 就是通道的 deviceId |
| | | String rtspSourceUrl = getRtspSource(channel); |
| | | String rtspUrl = |
| | | "rtsp://" + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getRtspPort() + "/" + name; // |
| | | // 拼接 webrtcUrl |
| | | String rtmpUrl = |
| | | "rtmp://" + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getRtmpPort() + "/" + name; // 拼接 |
| | | // webrtcUrl |
| | | String protocol = mediamtxConfig.isHttps() ? "https://" : "http://"; |
| | | String webrtcUrl = |
| | | protocol + mediamtxConfig.getPlayHost() + ":" + mediamtxConfig.getWebrtcPort() + "/" + name; |
| | | // 拼接 webrtcUrl |
| | | |
| | | // 先检查媒体表是否已有此记录 |
| | | Optional<ArdVtdu> existingMedia = ardVtduList.stream() |
| | | .filter(media -> media.getName().equals(name)) // 查找是否已有对应的媒体记录 |
| | | .findFirst(); |
| | | // 先检查媒体表是否已有此记录 |
| | | Optional<ArdVtdu> existingMedia = ardVtduList.stream() |
| | | .filter(media -> media.getName().equals(name)) // 查找是否已有对应的媒体记录 |
| | | .findFirst(); |
| | | |
| | | if (existingMedia.isPresent()) { |
| | | // 如果已有,更新现有记录 |
| | | ArdVtdu vtdu = existingMedia.get(); |
| | | // 更新前后内容相同则不进行更新 |
| | | if (!vtdu.getRtspSource().equals(rtspSourceUrl) || |
| | | !vtdu.getWebrtcUrl().equals(webrtcUrl) || |
| | | !vtdu.getRtspUrl().equals(rtspUrl) || |
| | | !vtdu.getRtmpUrl().equals(rtmpUrl)) { |
| | | if (existingMedia.isPresent()) { |
| | | // 如果已有,更新现有记录 |
| | | ArdVtdu vtdu = existingMedia.get(); |
| | | // 更新前后内容相同则不进行更新 |
| | | if (!vtdu.getRtspSource().equals(rtspSourceUrl) || |
| | | !vtdu.getWebrtcUrl().equals(webrtcUrl) || |
| | | !vtdu.getRtspUrl().equals(rtspUrl) || |
| | | !vtdu.getRtmpUrl().equals(rtmpUrl)) { |
| | | vtdu.setRtspUrl(rtspUrl); |
| | | vtdu.setRtmpUrl(rtmpUrl); |
| | | vtdu.setWebrtcUrl(webrtcUrl); |
| | | ardVtduService.updateArdVtdu(vtdu); |
| | | log.info("更新媒体记录:{}", vtdu.getName()); |
| | | } |
| | | } else { |
| | | // 如果没有,插入新的记录 |
| | | ArdVtdu vtdu = new ArdVtdu(); |
| | | vtdu.setName(name); |
| | | vtdu.setRtspSource(rtspSourceUrl); |
| | | vtdu.setCameraId(cameraId); |
| | | vtdu.setRtspUrl(rtspUrl); |
| | | vtdu.setRtmpUrl(rtmpUrl); |
| | | vtdu.setWebrtcUrl(webrtcUrl); |
| | | ardVtduService.updateArdVtdu(vtdu); |
| | | log.info("更新媒体记录:{}", vtdu.getName()); |
| | | ardVtduService.insertArdVtdu(vtdu); // 保存到媒体表 |
| | | log.info("插入新媒体记录:{}", vtdu.getName()); |
| | | } |
| | | } else { |
| | | // 如果没有,插入新的记录 |
| | | ArdVtdu vtdu = new ArdVtdu(); |
| | | vtdu.setName(name); |
| | | vtdu.setRtspSource(rtspSourceUrl); |
| | | vtdu.setCameraId(cameraId); |
| | | vtdu.setRtspUrl(rtspUrl); |
| | | vtdu.setRtmpUrl(rtmpUrl); |
| | | vtdu.setWebrtcUrl(webrtcUrl); |
| | | ardVtduService.insertArdVtdu(vtdu); // 保存到媒体表 |
| | | log.info("插入新媒体记录:{}", vtdu.getName()); |
| | | } |
| | | }); |
| | | // 3. 删除操作:删除媒体表中多余的记录 |
| | | List<String> invalidNames = ardVtduList.stream() |
| | | .filter(vtdu -> !validNames.contains(vtdu.getName())) |
| | | .filter(vtdu -> !"publisher".equalsIgnoreCase(vtdu.getRtspSource())) // 不是机场流 |
| | | .map(ArdVtdu::getName) |
| | | .collect(Collectors.toList()); |
| | | }); |
| | | // 3. 删除操作:删除媒体表中多余的记录 |
| | | List<String> invalidNames = ardVtduList.stream() |
| | | .filter(vtdu -> !validNames.contains(vtdu.getName())) |
| | | .filter(vtdu -> !"publisher".equalsIgnoreCase(vtdu.getRtspSource())) // 不是机场流 |
| | | .map(ArdVtdu::getName) |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (!invalidNames.isEmpty()) { |
| | | // 将 List<String> 转换为 String[] |
| | | String[] namesArray = invalidNames.toArray(new String[0]); |
| | | ardVtduService.deleteArdVtduByNames(namesArray); // 传递数组 |
| | | log.info("删除不再存在的媒体记录:{}", Arrays.toString(namesArray)); |
| | | if (!invalidNames.isEmpty()) { |
| | | // 将 List<String> 转换为 String[] |
| | | String[] namesArray = invalidNames.toArray(new String[0]); |
| | | ardVtduService.deleteArdVtduByNames(namesArray); // 传递数组 |
| | | log.info("删除不再存在的媒体记录:{}", Arrays.toString(namesArray)); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("定时同步Vtdu任务异常:{}", e.getMessage()); |
| | | } |
| | | |
| | | } |
| | |
| | | // 根据通道信息获取rtsp源地址 |
| | | private String getRtspSource(ArdChannel channel) { |
| | | String rtspSource = ""; |
| | | ArdCamera ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + channel.getDeviceId()); |
| | | ArdCamera ardCamera = redisCache.getCacheObject(CacheConstants.CAMERA_LIST_KEY + channel.getDeviceId()); |
| | | if (ardCamera != null) { |
| | | switch (ardCamera.getFactory()) { |
| | | case "1": |