diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java index 63f28cd7..73fb474d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java @@ -93,7 +93,7 @@ public class SIPProcessorFactory { public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) { Request request = evt.getRequest(); String method = request.getMethod(); - logger.info("接收到消息:"+request.getMethod()); +// logger.info("接收到消息:"+request.getMethod()); if (Request.INVITE.equals(method)) { InviteRequestProcessor processor = new InviteRequestProcessor(); processor.setRequestEvent(evt); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 3cc1376d..f901e5ed 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -19,6 +19,7 @@ import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; +import com.genersoft.iot.vmp.media.zlm.ZLMUtils; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -60,6 +61,13 @@ public class SIPCommander implements ISIPCommander { @Qualifier(value="udpSipProvider") private SipProvider udpSipProvider; + @Autowired + private ZLMUtils zlmUtils; + + @Value("${media.rtp.enable}") + private boolean rtpEnable; + + /** * 云台方向放控制,使用配置文件中的默认镜头移动速度 @@ -202,10 +210,17 @@ public class SIPCommander implements ISIPCommander { @Override public StreamInfo playStreamCmd(Device device, String channelId) { try { - + String ssrc = streamSession.createPlaySsrc(); String transport = device.getTransport(); MediaServerConfig mediaInfo = storager.getMediaInfo(); + String mediaPort = null; + // 使用动态udp端口 + if (rtpEnable) { + mediaPort = zlmUtils.getNewRTPPort(ssrc) + ""; + }else { + mediaPort = mediaInfo.getRtpProxyPort(); + } // StringBuffer content = new StringBuffer(200); content.append("v=0\r\n"); @@ -214,10 +229,10 @@ public class SIPCommander implements ISIPCommander { content.append("c=IN IP4 "+mediaInfo.getLocalIP()+"\r\n"); content.append("t=0 0\r\n"); if("TCP".equals(transport)) { - content.append("m=video "+mediaInfo.getRtpProxyPort()+" TCP/RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ mediaPort +" TCP/RTP/AVP 96 98 97\r\n"); } if("UDP".equals(transport)) { - content.append("m=video "+mediaInfo.getRtpProxyPort()+" RTP/AVP 96 98 97\r\n"); + content.append("m=video "+ mediaPort +" RTP/AVP 96 98 97\r\n"); } content.append("a=recvonly\r\n"); content.append("a=rtpmap:96 PS/90000\r\n"); @@ -575,4 +590,5 @@ public class SIPCommander implements ISIPCommander { return clientTransaction; } + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 01aa341a..3cb6506e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -83,4 +83,8 @@ public class ZLMRESTfulUtils { public JSONObject setServerConfig(Map param){ return sendPost("setServerConfig",param); } + + public JSONObject openRtpServer(Map param){ + return sendPost("openRtpServer",param); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java new file mode 100644 index 00000000..dda16930 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java @@ -0,0 +1,58 @@ +package com.genersoft.iot.vmp.media.zlm; + +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class ZLMUtils { + + @Value("${media.rtp.udpPortRange}") + private String udpPortRange; + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + private int[] udpPortRangeArray = new int[2]; + + private int currentPort = 0; + + public int getNewRTPPort(String ssrc) { + String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); + Map param = new HashMap<>(); + int newPort = getPortFromUdpPortRange(); + param.put("port", newPort); + param.put("enable_tcp", 0); + param.put("stream_id", streamId); + JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param); + if (jsonObject.getInteger("code") == 0) { + System.out.println(11111111); + System.out.println(streamId); + System.out.println(ssrc); + System.out.println(newPort); + System.out.println(jsonObject.toJSONString()); + return newPort; + }else { + return getNewRTPPort(streamId); + } + } + + private int getPortFromUdpPortRange() { + if (currentPort == 0) { + String[] udpPortRangeStrArray = udpPortRange.split(","); + udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]); + udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]); + } + + if (currentPort == 0 || currentPort ++ > udpPortRangeArray[1]) { + currentPort = udpPortRangeArray[0]; + return udpPortRangeArray[0]; + }else { + return currentPort ++; + } + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java index d5647fc6..19429a23 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; @@ -69,8 +70,8 @@ public class PlayController { return new ResponseEntity("timeout",HttpStatus.OK); }else { JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); - Boolean exist = rtpInfo.getBoolean("exist"); - if (rtpInfo == null || !rtpInfo.getBoolean("exist") || streamInfo.getFlv() != null){ + if (rtpInfo == null || !rtpInfo.getBoolean("exist") || storager.queryPlayByDevice(deviceId, channelId).getFlv() == null){ + Thread.sleep(2000); continue; }else { lockFlag = false; @@ -91,7 +92,6 @@ public class PlayController { } }; } - Thread.sleep(200); streamInfo = storager.queryPlayByDevice(deviceId, channelId); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ad375486..a06c19e6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -43,5 +43,9 @@ media: #zlm服务器的ip与http端口, 重点: 这是http端口 ip: 192.168.1.20 port: 9080 secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc - streamNoneReaderDelayMS: 1800000 # 无人观看多久关闭流 + streamNoneReaderDelayMS: 1800000 # 无人观看多久自动关闭流 + rtp: # 启用udp多端口模式 + enable: false + udpPortRange: 30000,300500 # 端口范围 +