diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java index 8366a4a2..1fb8256c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java @@ -1,13 +1,20 @@ package com.genersoft.iot.vmp.media.zlm; +import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetting; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaSendRtpPortInfo; +import com.genersoft.iot.vmp.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + @Component public class SendRtpPortManager { @@ -29,27 +36,54 @@ public class SendRtpPortManager { } public int getNextPort(String mediaServerId) { - String key = KEY + userSetting.getServerId() + "_" + mediaServerId; - MediaSendRtpPortInfo mediaSendRtpPortInfo = (MediaSendRtpPortInfo)redisTemplate.opsForValue().get(key); + String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + + userSetting.getServerId() + "_*"; + List queryResult = RedisUtil.scan(redisTemplate, key); + Map sendRtpItemMap = new HashMap<>(); + + for (Object o : queryResult) { + SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(o); + if (sendRtpItem != null) { + sendRtpItemMap.put(sendRtpItem.getLocalPort(), sendRtpItem); + } + } + + String sendIndexKey = KEY + userSetting.getServerId() + "_" + mediaServerId; + MediaSendRtpPortInfo mediaSendRtpPortInfo = (MediaSendRtpPortInfo)redisTemplate.opsForValue().get(sendIndexKey); if (mediaSendRtpPortInfo == null) { logger.warn("[发送端口管理] 获取{}的发送端口时未找到端口信息", mediaSendRtpPortInfo); return 0; } + int port = getPort(mediaSendRtpPortInfo.getCurrent(), + mediaSendRtpPortInfo.getStart(), + mediaSendRtpPortInfo.getEnd(), checkPort -> sendRtpItemMap.get(checkPort) == null); + + mediaSendRtpPortInfo.setCurrent(port); + redisTemplate.opsForValue().set(sendIndexKey, mediaSendRtpPortInfo); + return port; + } + + interface CheckPortCallback{ + boolean check(int port); + } + + private int getPort(int current, int start, int end, CheckPortCallback checkPortCallback) { int port; - if (mediaSendRtpPortInfo.getCurrent() %2 != 0) { - port = mediaSendRtpPortInfo.getCurrent() + 1; + if (current %2 != 0) { + port = current + 1; }else { - port = mediaSendRtpPortInfo.getCurrent() + 2; + port = current + 2; } - if (port > mediaSendRtpPortInfo.getEnd()) { - if (mediaSendRtpPortInfo.getStart() %2 != 0) { - port = mediaSendRtpPortInfo.getStart() + 1; + if (port > end) { + if (start %2 != 0) { + port = start + 1; }else { - port = mediaSendRtpPortInfo.getStart(); + port = start; } } - mediaSendRtpPortInfo.setCurrent(port); - redisTemplate.opsForValue().set(key, mediaSendRtpPortInfo); + if (!checkPortCallback.check(port)) { + return getPort(port, start, end, checkPortCallback); + } return port; } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java index a9a66f5c..18215223 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java @@ -142,11 +142,12 @@ public class RtpController { // 预创建发流信息 int portForVideo = sendRtpPortManager.getNextPort(mediaServerItem.getId()); int portForAudio = sendRtpPortManager.getNextPort(mediaServerItem.getId()); - // 将信息写入redis中,以备后用 - redisTemplate.opsForValue().set(key, otherRtpSendInfo, 300, TimeUnit.SECONDS); + otherRtpSendInfo.setSendLocalIp(mediaServerItem.getSdpIp()); otherRtpSendInfo.setSendLocalPortForVideo(portForVideo); otherRtpSendInfo.setSendLocalPortForAudio(portForAudio); + // 将信息写入redis中,以备后用 + redisTemplate.opsForValue().set(key, otherRtpSendInfo, 300, TimeUnit.SECONDS); logger.info("[第三方服务对接->开启收流和获取发流信息] 结果,callId->{}, {}", callId, otherRtpSendInfo); } return otherRtpSendInfo;