| | |
| | | package com.ard.device.channel.service.impl; |
| | | |
| | | import com.ard.common.constant.CacheConstants; |
| | | import com.ard.common.constant.UserConstants; |
| | | import com.ard.common.core.redis.RedisCache; |
| | | import com.ard.common.utils.uuid.IdUtils; |
| | | import com.ard.device.camera.domain.ArdCamera; |
| | | import com.ard.device.camera.service.IArdCameraService; |
| | |
| | | import com.ard.vtdu.domain.ArdVtdu; |
| | | import com.ard.vtdu.service.IArdVtduService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.scheduling.annotation.Scheduled; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | |
| | | @Slf4j |
| | | @Service |
| | | public class ArdChannelServiceImpl implements IArdChannelService { |
| | | @Resource |
| | | private IArdCameraService ardCameraService; |
| | | |
| | | @Resource |
| | | private ArdChannelMapper ardChannelMapper; |
| | | @Resource |
| | | private IArdVtduService ardVtduService; |
| | | @Resource |
| | | private MediamtxConfig mediamtxConfig; |
| | | |
| | | /** |
| | | * 查询通道管理 |
| | |
| | | return UserConstants.NOT_UNIQUE; |
| | | } |
| | | return UserConstants.UNIQUE; |
| | | } |
| | | |
| | | |
| | | @Scheduled(cron = "0/5 * * * * ?") |
| | | 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()); |
| | | |
| | | 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(); |
| | | |
| | | 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.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()); |
| | | |
| | | if (!invalidNames.isEmpty()) { |
| | | // 将 List<String> 转换为 String[] |
| | | String[] namesArray = invalidNames.toArray(new String[0]); |
| | | ardVtduService.deleteArdVtduByNames(namesArray); // 传递数组 |
| | | log.info("删除不再存在的媒体记录:{}", Arrays.toString(namesArray)); |
| | | } |
| | | |
| | | } |
| | | |
| | | // 根据通道信息获取rtsp源地址 |
| | | private String getRtspSource(ArdChannel channel) { |
| | | String rtspSource = ""; |
| | | ArdCamera ardCamera = ardCameraService.selectArdCameraById(channel.getDeviceId()); |
| | | if (ardCamera != null) { |
| | | switch (ardCamera.getFactory()) { |
| | | case "1": |
| | | rtspSource = |
| | | "rtsp://" + ardCamera.getUsername() + ":" + ardCamera.getPassword() + "@" + ardCamera.getIp() + ":" + ardCamera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream"; |
| | | break; |
| | | case "2": |
| | | rtspSource = |
| | | "rtsp://" + ardCamera.getUsername() + ":" + ardCamera.getPassword() + "@" + ardCamera.getIp() + ":" + ardCamera.getRtspPort() + "/cam/realmonitor?channel=" + channel.getChanNo() + "&subtype=0"; |
| | | break; |
| | | } |
| | | } |
| | | return rtspSource; |
| | | } |
| | | } |