diff --git a/src/main/java/com/genersoft/iot/vmp/common/CommonGbChannel.java b/src/main/java/com/genersoft/iot/vmp/common/CommonGbChannel.java new file mode 100644 index 00000000..b289a14a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/common/CommonGbChannel.java @@ -0,0 +1,191 @@ +package com.genersoft.iot.vmp.common; + +import io.swagger.v3.oas.annotations.media.Schema; + +public class CommonGbChannel { + + /** + * 国标字段:归属 + */ + @Schema(description = "归属") + private String owner; + + /** + * 国标字段:行政区划 + */ + @Schema(description = "行政区划") + private String civilCode; + + /** + * 国标字段:安装地址 + */ + @Schema(description = "安装地址") + private String address; + + /** + * 国标字段:经度 + */ + @Schema(description = "经度") + private Double longitude; + + /** + * 国标字段:纬度 + */ + @Schema(description = "纬度") + private Double latitude; + + /** + * 国标字段:摄像机类型: + * 1-球机; + * 2-半球; + * 3-固定枪机; + * 4-遥控枪机 + */ + @Schema(description = "摄像机类型") + private Integer ptzType; + + /** + * 国标字段:摄像机位置类型扩展。 + * 1-省际检查站、 + * 2-党政机关、 + * 3-车站码头、 + * 4-中心广场、 + * 5-体育场馆、 + * 6-商业中心、 + * 7-宗教场所、 + * 8-校园周边、 + * 9-治安复杂区域、 + * 10-交通干线 + */ + @Schema(description = "摄像机位置类型扩展") + private Integer positionType; + + /** + * 国标字段:安装位置室外、室内属性 + * 1-室外、 + * 2-室内 + */ + @Schema(description = "安装位置室外、室内属性") + private Integer roomType; + + /** + * 国标字段:用途 + * 1-治安、 + * 2-交通、 + * 3-重点、 + */ + @Schema(description = "用途") + private Integer useType; + + /** + * 国标字段:补光属性 + * 1-无补光、 + * 2-红外补光、 + * 3-白光补光 + */ + @Schema(description = "补光属性") + private Integer supplyLightType; + + /** + * 摄像机监视方位属性。 + * 1-东、 + * 2-西、 + * 3-南、 + * 4-北、 + * 5-东南、 + * 6-东北、 + * 7-西南、 + * 8-西北 + * + */ + @Schema(description = "方位") + private Integer directionType; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getCivilCode() { + return civilCode; + } + + public void setCivilCode(String civilCode) { + this.civilCode = civilCode; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public Double getLongitude() { + return longitude; + } + + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + public Double getLatitude() { + return latitude; + } + + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + + public Integer getPtzType() { + return ptzType; + } + + public void setPtzType(Integer ptzType) { + this.ptzType = ptzType; + } + + public Integer getPositionType() { + return positionType; + } + + public void setPositionType(Integer positionType) { + this.positionType = positionType; + } + + public Integer getRoomType() { + return roomType; + } + + public void setRoomType(Integer roomType) { + this.roomType = roomType; + } + + public Integer getUseType() { + return useType; + } + + public void setUseType(Integer useType) { + this.useType = useType; + } + + public Integer getSupplyLightType() { + return supplyLightType; + } + + public void setSupplyLightType(Integer supplyLightType) { + this.supplyLightType = supplyLightType; + } + + public Integer getDirectionType() { + return directionType; + } + + public void setDirectionType(Integer directionType) { + this.directionType = directionType; + } +} 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 893e52a0..f960c7dc 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 @@ -3,12 +3,14 @@ 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.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.utils.redis.RedisUtil; +import org.apache.commons.lang3.math.NumberUtils; 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.data.redis.support.atomic.RedisAtomicInteger; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -26,23 +28,14 @@ public class SendRtpPortManager { @Autowired private RedisTemplate redisTemplate; - private final String KEY = "VM_MEDIA_SEND_RTP_PORT_RANGE_"; + private final String KEY = "VM_MEDIA_SEND_RTP_PORT_"; - - public void initServerPort(String mediaServerId, int startPort, int endPort){ - String key = KEY + userSetting.getServerId() + "_" + mediaServerId; - MediaSendRtpPortInfo mediaSendRtpPortInfo = new MediaSendRtpPortInfo(startPort, endPort, mediaServerId); - redisTemplate.opsForValue().set(key, mediaSendRtpPortInfo); - } - - public int getNextPort(String mediaServerId) { - String sendIndexKey = KEY + userSetting.getServerId() + "_" + mediaServerId; - MediaSendRtpPortInfo mediaSendRtpPortInfo = (MediaSendRtpPortInfo)redisTemplate.opsForValue().get(sendIndexKey); - if (mediaSendRtpPortInfo == null) { - logger.warn("[发送端口管理] 获取{}的发送端口时未找到端口信息", mediaServerId); - return 0; + public int getNextPort(MediaServerItem mediaServer) { + if (mediaServer == null) { + logger.warn("[发送端口管理] 参数错误,mediaServer为NULL"); + return -1; } - + String sendIndexKey = KEY + userSetting.getServerId() + "_" + mediaServer.getId(); String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_*"; List queryResult = RedisUtil.scan(redisTemplate, key); @@ -54,14 +47,39 @@ public class SendRtpPortManager { sendRtpItemMap.put(sendRtpItem.getLocalPort(), sendRtpItem); } } + String sendRtpPortRange = mediaServer.getSendRtpPortRange(); + int startPort; + int endPort; + if (sendRtpPortRange == null) { + logger.warn("{}未设置发送端口默认值,自动使用40000-50000作为端口范围", mediaServer.getId()); + String[] portArray = sendRtpPortRange.split(","); + if (portArray.length != 2 || !NumberUtils.isParsable(portArray[0]) || !NumberUtils.isParsable(portArray[1])) { + logger.warn("{}发送端口配置格式错误,自动使用40000-50000作为端口范围", mediaServer.getId()); + startPort = 50000; + endPort = 60000; + }else { - int port = getPort(mediaSendRtpPortInfo.getCurrent(), - mediaSendRtpPortInfo.getStart(), - mediaSendRtpPortInfo.getEnd(), checkPort -> sendRtpItemMap.get(checkPort) == null); - - mediaSendRtpPortInfo.setCurrent(port); - redisTemplate.opsForValue().set(sendIndexKey, mediaSendRtpPortInfo); - return port; + if ( Integer.parseInt(portArray[1]) - Integer.parseInt(portArray[0]) < 1) { + logger.warn("{}发送端口配置错误,结束端口至少比开始端口大一,自动使用40000-50000作为端口范围", mediaServer.getId()); + startPort = 50000; + endPort = 60000; + }else { + startPort = Integer.parseInt(portArray[0]); + endPort = Integer.parseInt(portArray[1]); + } + } + }else { + startPort = 50000; + endPort = 60000; + } + if (redisTemplate == null || redisTemplate.getConnectionFactory() == null) { + logger.warn("{}获取redis连接信息失败", mediaServer.getId()); + return -1; + } + RedisAtomicInteger redisAtomicInteger = new RedisAtomicInteger(sendIndexKey , redisTemplate.getConnectionFactory()); + return redisAtomicInteger.getAndUpdate((current)->{ + return getPort(current, startPort, endPort, checkPort-> !sendRtpItemMap.containsKey(checkPort)); + }); } interface CheckPortCallback{ @@ -69,22 +87,25 @@ public class SendRtpPortManager { } private int getPort(int current, int start, int end, CheckPortCallback checkPortCallback) { - int port; - if (current %2 != 0) { - port = current + 1; - }else { - port = current + 2; - } - if (port > end) { - if (start %2 != 0) { - port = start + 1; + if (current <= 0) { + if (start%2 == 0) { + current = start; }else { - port = start; + current = start + 1; + } + }else { + current += 2; + if (current > end) { + if (start%2 == 0) { + current = start; + }else { + current = start + 1; + } } } - if (!checkPortCallback.check(port)) { - return getPort(port, start, end, checkPortCallback); + if (!checkPortCallback.check(current)) { + return getPort(current + 2, start, end, checkPortCallback); } - return port; + return current; } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java index 7fe92ae3..34acf152 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java @@ -167,7 +167,7 @@ public class ZLMServerFactory { // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { - localPort = sendRtpPortManager.getNextPort(serverItem.getId()); + localPort = sendRtpPortManager.getNextPort(serverItem); if (localPort == 0) { return null; } @@ -203,7 +203,7 @@ public class ZLMServerFactory { // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { - localPort = sendRtpPortManager.getNextPort(serverItem.getId()); + localPort = sendRtpPortManager.getNextPort(serverItem); if (localPort == 0) { return null; } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaSendRtpPortInfo.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaSendRtpPortInfo.java deleted file mode 100644 index 2e9f6317..00000000 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaSendRtpPortInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.genersoft.iot.vmp.media.zlm.dto; - -public class MediaSendRtpPortInfo { - - private int start; - private int end; - private String mediaServerId; - - private int current; - - - public MediaSendRtpPortInfo(int start, int end, String mediaServerId) { - this.start = start; - this.current = start; - this.end = end; - this.mediaServerId = mediaServerId; - } - - public int getStart() { - return start; - } - - public void setStart(int start) { - this.start = start; - } - - public int getEnd() { - return end; - } - - public void setEnd(int end) { - this.end = end; - } - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public int getCurrent() { - return current; - } - - public void setCurrent(int current) { - this.current = current; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index a79b4108..142b8100 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -119,34 +119,6 @@ public class MediaServerServiceImpl implements IMediaServerService { if (ssrcFactory.hasMediaServerSSRC(mediaServerItem.getId())) { ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null); } - if (userSetting.getGbSendStreamStrict()) { - int startPort = 50000; - int endPort = 60000; - String sendRtpPortRange = mediaServerItem.getSendRtpPortRange(); - if (sendRtpPortRange == null) { - logger.warn("[zlm] ] 未配置发流端口范围,默认使用50000到60000"); - }else { - String[] sendRtpPortRangeArray = sendRtpPortRange.trim().split(","); - if (sendRtpPortRangeArray.length != 2) { - logger.warn("[zlm] ] 发流端口范围错误,默认使用50000到60000"); - }else { - try { - startPort = Integer.parseInt(sendRtpPortRangeArray[0]); - endPort = Integer.parseInt(sendRtpPortRangeArray[1]); - if (endPort <= startPort) { - logger.warn("[zlm] ] 发流端口范围错误,结束端口应大于开始端口,使用默认端口"); - startPort = 50000; - endPort = 60000; - } - - }catch (NumberFormatException e) { - logger.warn("[zlm] ] 发流端口范围错误,默认使用50000到60000"); - } - } - } - logger.info("[[zlm] ] 配置发流端口范围,{}-{}", startPort, endPort); - sendRtpPortManager.initServerPort(mediaServerItem.getId(), startPort, endPort); - } // 查询redis是否存在此mediaServer String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId(); Boolean hasKey = redisTemplate.hasKey(key); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index e0494bcf..4f487ad9 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -269,7 +269,7 @@ public class PlayServiceImpl implements IPlayService { InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); - logger.info("[点播成功] deviceId: {}, channelId:{}, 码流类型:{}", device.getDeviceId(), + logger.info("[点播成功] deviceId: {}, channelId:{}, 码流类型:{}", device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "辅码流" : "主码流"); snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channelId, ssrcInfo.getStream()); }, (event) -> { 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 513e940f..638ed3ff 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 @@ -139,8 +139,8 @@ public class RtpController { redisTemplate.opsForValue().set(receiveKey, otherRtpSendInfo); if (isSend != null && isSend) { // 预创建发流信息 - int portForVideo = sendRtpPortManager.getNextPort(mediaServerItem.getId()); - int portForAudio = sendRtpPortManager.getNextPort(mediaServerItem.getId()); + int portForVideo = sendRtpPortManager.getNextPort(mediaServerItem); + int portForAudio = sendRtpPortManager.getNextPort(mediaServerItem); otherRtpSendInfo.setSendLocalIp(mediaServerItem.getSdpIp()); otherRtpSendInfo.setSendLocalPortForVideo(portForVideo); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index bef7ffb9..f4bcb1a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.VersionInfo; import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; @@ -72,6 +73,9 @@ public class ServerController { @Autowired private IRedisCatchStorage redisCatchStorage; + @Autowired + private SendRtpPortManager sendRtpPortManager; + @GetMapping(value = "/media_server/list") @ResponseBody @@ -262,4 +266,12 @@ public class ServerController { return result; } + + @PostMapping(value = "/test/getPort") + @ResponseBody + public int getPort() { + int result = sendRtpPortManager.getNextPort(mediaServerService.getDefaultMediaServer()); + System.out.println(result); + return result; + } }