src/main/java/com/genersoft/iot/vmp/common/CommonGbChannel.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaSendRtpPortInfo.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/genersoft/iot/vmp/common/CommonGbChannel.java
New file @@ -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; } } src/main/java/com/genersoft/iot/vmp/media/zlm/SendRtpPortManager.java
@@ -3,12 +3,14 @@ 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 @@ @Autowired private RedisTemplate<Object, Object> 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<Object> queryResult = RedisUtil.scan(redisTemplate, key); @@ -54,14 +47,39 @@ 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 @@ } 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; } } src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java
@@ -167,7 +167,7 @@ // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { localPort = sendRtpPortManager.getNextPort(serverItem.getId()); localPort = sendRtpPortManager.getNextPort(serverItem); if (localPort == 0) { return null; } @@ -203,7 +203,7 @@ // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { localPort = sendRtpPortManager.getNextPort(serverItem.getId()); localPort = sendRtpPortManager.getNextPort(serverItem); if (localPort == 0) { return null; } src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaSendRtpPortInfo.java
File was deleted src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -119,34 +119,6 @@ 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); src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -269,7 +269,7 @@ 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) -> { src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
@@ -139,8 +139,8 @@ 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); src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
@@ -8,6 +8,7 @@ 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; @@ -71,6 +72,9 @@ @Autowired private IRedisCatchStorage redisCatchStorage; @Autowired private SendRtpPortManager sendRtpPortManager; @GetMapping(value = "/media_server/list") @@ -262,4 +266,12 @@ return result; } @PostMapping(value = "/test/getPort") @ResponseBody public int getPort() { int result = sendRtpPortManager.getNextPort(mediaServerService.getDefaultMediaServer()); System.out.println(result); return result; } }