diff --git a/README.md b/README.md index 7cac2b69..a29280b9 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,10 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git - [X] 支持Mysql,Postgresql,金仓等数据库 - [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取) +# 非开源的内容 +- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。在[知识星球](https://t.zsxq.com/10WAnH2MP)放了试用安装包以及使用教程,没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 + + # 授权协议 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 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/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 90b5291e..0c77fc18 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -63,7 +63,7 @@ public class SipLayer implements CommandLineRunner { private void addListeningPoint(String monitorIp, int port){ SipStackImpl sipStack; try { - sipStack = (SipStackImpl)SipFactory.getInstance().createSipStack(DefaultProperties.getProperties(monitorIp, userSetting.getSipLog())); + sipStack = (SipStackImpl)SipFactory.getInstance().createSipStack(DefaultProperties.getProperties("GB28181_SIP", userSetting.getSipLog())); sipStack.setMessageParserFactory(new GbStringMsgParserFactory()); } catch (PeerUnavailableException e) { logger.error("[SIP SERVER] SIP服务启动失败, 监听地址{}失败,请检查ip是否正确", monitorIp); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java b/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java index 7e355e54..e2c9ef58 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/conf/DefaultProperties.java @@ -12,10 +12,10 @@ import java.util.Properties; */ public class DefaultProperties { - public static Properties getProperties(String ip, boolean sipLog) { + public static Properties getProperties(String name, boolean sipLog) { Properties properties = new Properties(); - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP"); - properties.setProperty("javax.sip.IP_ADDRESS", ip); + properties.setProperty("javax.sip.STACK_NAME", name); +// properties.setProperty("javax.sip.IP_ADDRESS", ip); // 关闭自动会话 properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off"); /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java index a08231c8..8c96a8e8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java @@ -344,7 +344,7 @@ public class XmlUtil { if (!ObjectUtils.isEmpty(civilCode) && civilCode.length() <= 8 && NumberUtils.isParsable(civilCode) - && Integer.parseInt(civilCode)%2 == 0 + && civilCode.length()%2 == 0 ) { deviceChannel.setCivilCode(civilCode); } 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 e0ac71fc..81cae37c 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 @@ -171,7 +171,7 @@ public class ZLMServerFactory { // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { - localPort = sendRtpPortManager.getNextPort(serverItem.getId()); + localPort = sendRtpPortManager.getNextPort(serverItem); if (localPort == 0) { return null; } @@ -207,7 +207,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 74bea6cc..7a523632 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 @@ -121,34 +121,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 e248fd1e..3b9d6174 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 @@ -440,7 +440,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/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index fb844c9d..0e0bc184 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -155,25 +155,24 @@ public class StreamProxyServiceImpl implements IStreamProxyService { return; } - String talkKey = UUID.randomUUID().toString(); - dynamicTask.startCron(talkKey, ()->{ - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); - if (streamInfo != null) { - callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); - } - }, 1000); - String delayTalkKey = UUID.randomUUID().toString(); - dynamicTask.startDelay(delayTalkKey, ()->{ - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); - if (streamInfo != null) { - callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); - }else { - dynamicTask.stop(talkKey); - callback.run(ErrorCode.ERROR100.getCode(), "超时", null); - } - }, 5000); - if (param.isEnable()) { + String talkKey = UUID.randomUUID().toString(); + dynamicTask.startCron(talkKey, ()->{ + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); + if (streamInfo != null) { + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + } + }, 1000); + String delayTalkKey = UUID.randomUUID().toString(); + dynamicTask.startDelay(delayTalkKey, ()->{ + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false); + if (streamInfo != null) { + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + }else { + dynamicTask.stop(talkKey); + callback.run(ErrorCode.ERROR100.getCode(), "超时", null); + } + }, 5000); JSONObject jsonObject = addStreamProxyToZlm(param); if (jsonObject != null && jsonObject.getInteger("code") == 0) { dynamicTask.stop(talkKey); @@ -190,13 +189,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } if (jsonObject == null){ callback.run(ErrorCode.ERROR100.getCode(), "记录已保存,启用失败", null); - return; }else { callback.run(ErrorCode.ERROR100.getCode(), jsonObject.getString("msg"), null); - return; } } } + else{ + StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( + mediaInfo, param.getApp(), param.getStream(), null, null); + callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); + } } private String getSchemaFromFFmpegCmd(String ffmpegCmd) { 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 8d6e480d..f609a8dc 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; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index 18fdfa93..39f6388f 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -51,15 +51,15 @@ public class ApiStreamController { @Autowired private IRedisCatchStorage redisCatchStorage; - @Autowired - private IInviteStreamService inviteStreamService; - @Autowired private IDeviceService deviceService; @Autowired private IPlayService playService; + @Autowired + private IInviteStreamService inviteStreamService; + /** * 实时直播 - 开始直播 * @param serial 设备编号 @@ -92,7 +92,7 @@ public class ApiStreamController { result.put("error","device[ " + serial + " ]未找到"); resultDeferredResult.setResult(result); return resultDeferredResult; - }else if (!device.isOnLine()) { + }else if (device.isOnLine()) { JSONObject result = new JSONObject(); result.put("error","device[ " + code + " ]offline"); resultDeferredResult.setResult(result); @@ -133,11 +133,17 @@ public class ApiStreamController { result.put("ChannelName", deviceChannel.getName()); result.put("ChannelCustomName", ""); result.put("FLV", inviteInfo.getStreamInfo().getFlv().getUrl()); + result.put("HTTPS_FLV", inviteInfo.getStreamInfo().getHttps_flv().getUrl()); result.put("WS_FLV", inviteInfo.getStreamInfo().getWs_flv().getUrl()); + result.put("WSS_FLV", inviteInfo.getStreamInfo().getWss_flv().getUrl()); result.put("RTMP", inviteInfo.getStreamInfo().getRtmp().getUrl()); + result.put("RTMPS", inviteInfo.getStreamInfo().getRtmps().getUrl()); result.put("HLS", inviteInfo.getStreamInfo().getHls().getUrl()); + result.put("HTTPS_HLS", inviteInfo.getStreamInfo().getHttps_hls().getUrl()); result.put("RTSP", inviteInfo.getStreamInfo().getRtsp().getUrl()); + result.put("RTSPS", inviteInfo.getStreamInfo().getRtsps().getUrl()); result.put("WEBRTC", inviteInfo.getStreamInfo().getRtc().getUrl()); + result.put("HTTPS_WEBRTC", inviteInfo.getStreamInfo().getRtcs().getUrl()); result.put("CDN", ""); result.put("SnapURL", ""); result.put("Transport", device.getTransport()); diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index df148bbd..9b94f6f6 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -145,8 +145,8 @@ media: enable: true # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 port-range: 30000,30500 # 端口范围 - # [可选] 国标级联在此范围内选择端口发送媒体流 - send-port-range: 30000,30500 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流,请不要与收流端口范围重合 + send-port-range: 50502,50506 # 端口范围 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 record-assist-port: 0