Commit 694076dc8c447754b02dff24a891249f54427ffb

Authored by 648540858
1 parent 2466a248

优化国标级联发流并发能力

Showing 26 changed files with 275 additions and 164 deletions
sql/mysql.sql
... ... @@ -281,7 +281,6 @@ CREATE TABLE `media_server` (
281 281 `secret` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
282 282 `rtpEnable` int NOT NULL,
283 283 `rtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
284   - `sendRtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
285 284 `recordAssistPort` int NOT NULL,
286 285 `defaultServer` int NOT NULL,
287 286 `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
... ...
sql/update.sql
1 1 alter table media_server
2 2 drop column streamNoneReaderDelayMS;
3 3  
  4 +alter table media_server
  5 + drop column sendRtpPortRange;
  6 +
4 7 alter table stream_proxy
5 8 add enable_disable_none_reader bit(1) default null;
6 9  
... ...
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
... ... @@ -37,6 +37,8 @@ public class UserSetting {
37 37  
38 38 private Boolean pushAuthority = Boolean.TRUE;
39 39  
  40 + private Boolean gbSendStreamStrict = Boolean.FALSE;
  41 +
40 42 private String serverId = "000000";
41 43  
42 44 private String thirdPartyGBIdReg = "[\\s\\S]*";
... ... @@ -166,4 +168,12 @@ public class UserSetting {
166 168 public void setPushAuthority(Boolean pushAuthority) {
167 169 this.pushAuthority = pushAuthority;
168 170 }
  171 +
  172 + public Boolean getGbSendStreamStrict() {
  173 + return gbSendStreamStrict;
  174 + }
  175 +
  176 + public void setGbSendStreamStrict(Boolean gbSendStreamStrict) {
  177 + this.gbSendStreamStrict = gbSendStreamStrict;
  178 + }
169 179 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/SipSubscribe.java
... ... @@ -7,10 +7,12 @@ import org.slf4j.LoggerFactory;
7 7 import org.springframework.scheduling.annotation.Scheduled;
8 8 import org.springframework.stereotype.Component;
9 9  
10   -import javax.sip.*;
  10 +import javax.sip.DialogTerminatedEvent;
  11 +import javax.sip.ResponseEvent;
  12 +import javax.sip.TimeoutEvent;
  13 +import javax.sip.TransactionTerminatedEvent;
11 14 import javax.sip.header.CallIdHeader;
12 15 import javax.sip.message.Response;
13   -import java.text.ParseException;
14 16 import java.time.Instant;
15 17 import java.util.Map;
16 18 import java.util.concurrent.ConcurrentHashMap;
... ... @@ -29,6 +31,7 @@ public class SipSubscribe {
29 31 private Map<String, SipSubscribe.Event> okSubscribes = new ConcurrentHashMap<>();
30 32  
31 33 private Map<String, Instant> okTimeSubscribes = new ConcurrentHashMap<>();
  34 +
32 35 private Map<String, Instant> errorTimeSubscribes = new ConcurrentHashMap<>();
33 36  
34 37 // @Scheduled(cron="*/5 * * * * ?") //每五秒执行一次
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java
1 1 package com.genersoft.iot.vmp.gb28181.event.record;
2 2  
3 3 import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
4   -import com.genersoft.iot.vmp.gb28181.bean.RecordItem;
5 4 import org.slf4j.Logger;
6 5 import org.slf4j.LoggerFactory;
7 6 import org.springframework.context.ApplicationListener;
8 7 import org.springframework.stereotype.Component;
9 8 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
10 9  
11   -import java.io.IOException;
12   -import java.util.*;
  10 +import java.util.HashMap;
  11 +import java.util.Hashtable;
  12 +import java.util.Map;
13 13  
14 14 /**
15   - * @description: 录像查询结束时间
  15 + * @description: 录像查询结束事件
16 16 * @author: pan
17 17 * @data: 2022-02-23
18 18 */
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
4 4 import com.genersoft.iot.vmp.common.StreamInfo;
5   -import com.genersoft.iot.vmp.conf.DynamicTask;
6 5 import com.genersoft.iot.vmp.conf.SipConfig;
7 6 import com.genersoft.iot.vmp.conf.UserSetting;
8 7 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
... ... @@ -12,45 +11,31 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
12 11 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
13 12 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
14 13 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
  14 +import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
15 15 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
  16 +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
16 17 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
17 18 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
18   -import com.genersoft.iot.vmp.utils.DateUtil;
19   -import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
20   -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
21 19 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
22 20 import com.genersoft.iot.vmp.service.IMediaServerService;
23 21 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
24   -import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
25   -import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
26   -import com.genersoft.iot.vmp.utils.GitUtil;
27   -import gov.nist.javax.sip.SIPConstants;
28   -import gov.nist.javax.sip.SipProviderImpl;
29   -import gov.nist.javax.sip.SipStackImpl;
  22 +import com.genersoft.iot.vmp.utils.DateUtil;
30 23 import gov.nist.javax.sip.message.SIPRequest;
31 24 import gov.nist.javax.sip.message.SIPResponse;
32   -import gov.nist.javax.sip.stack.SIPClientTransaction;
33   -import gov.nist.javax.sip.stack.SIPClientTransactionImpl;
34   -import gov.nist.javax.sip.stack.SIPDialog;
35 25 import org.slf4j.Logger;
36 26 import org.slf4j.LoggerFactory;
37 27 import org.springframework.beans.factory.annotation.Autowired;
38   -import org.springframework.beans.factory.annotation.Qualifier;
39 28 import org.springframework.context.annotation.DependsOn;
40   -import org.springframework.context.annotation.Lazy;
41 29 import org.springframework.stereotype.Component;
42 30 import org.springframework.util.ObjectUtils;
43 31  
44   -import javax.sip.*;
45   -import javax.sip.address.Address;
46   -import javax.sip.address.SipURI;
47   -import javax.sip.header.*;
48   -import javax.sip.message.Message;
  32 +import javax.sip.InvalidArgumentException;
  33 +import javax.sip.ResponseEvent;
  34 +import javax.sip.SipException;
  35 +import javax.sip.SipFactory;
  36 +import javax.sip.header.CallIdHeader;
49 37 import javax.sip.message.Request;
50   -import javax.sip.message.Response;
51   -import java.lang.reflect.Field;
52 38 import java.text.ParseException;
53   -import java.util.HashSet;
54 39  
55 40 /**
56 41 * @description:设备能力接口,用于定义设备的控制、查询能力
... ... @@ -183,7 +168,7 @@ public class SIPCommander implements ISIPCommander {
183 168 public void ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
184 169 int zoomSpeed) throws InvalidArgumentException, SipException, ParseException {
185 170 String cmdStr = SipUtils.cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed);
186   - StringBuffer ptzXml = new StringBuffer(200);
  171 + StringBuilder ptzXml = new StringBuilder(200);
187 172 String charset = device.getCharset();
188 173 ptzXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
189 174 ptzXml.append("<Control>\r\n");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2  
3 3 import com.alibaba.fastjson2.JSON;
4   -import com.alibaba.fastjson2.JSONObject;
5 4 import com.genersoft.iot.vmp.gb28181.bean.*;
6 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
7 6 import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
... ... @@ -15,15 +14,12 @@ import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
15 14 import com.genersoft.iot.vmp.service.IMediaServerService;
16 15 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
17 16 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
18   -import gov.nist.javax.sip.SipProviderImpl;
19 17 import gov.nist.javax.sip.message.MessageFactoryImpl;
20 18 import gov.nist.javax.sip.message.SIPRequest;
21 19 import org.slf4j.Logger;
22 20 import org.slf4j.LoggerFactory;
23 21 import org.springframework.beans.factory.annotation.Autowired;
24   -import org.springframework.beans.factory.annotation.Qualifier;
25 22 import org.springframework.context.annotation.DependsOn;
26   -import org.springframework.context.annotation.Lazy;
27 23 import org.springframework.lang.Nullable;
28 24 import org.springframework.stereotype.Component;
29 25 import org.springframework.util.ObjectUtils;
... ... @@ -638,7 +634,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
638 634 MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
639 635 if (mediaServerItem != null) {
640 636 mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
641   - zlmrtpServerFactory.closeRTPServer(mediaServerItem, sendRtpItem.getStreamId());
  637 + zlmrtpServerFactory.closeRtpServer(mediaServerItem, sendRtpItem.getStreamId());
642 638 }
643 639 SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem);
644 640 if (byeRequest == null) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java
... ... @@ -10,8 +10,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
10 10 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
11 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
12 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
13   -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
14 13 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
  14 +import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
15 15 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
16 16 import com.genersoft.iot.vmp.service.IMediaServerService;
17 17 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg;
... ... @@ -33,7 +33,8 @@ import javax.sip.header.FromHeader;
33 33 import javax.sip.header.HeaderAddress;
34 34 import javax.sip.header.ToHeader;
35 35 import java.text.ParseException;
36   -import java.util.*;
  36 +import java.util.HashMap;
  37 +import java.util.Map;
37 38  
38 39 /**
39 40 * SIP命令类型: ACK请求
... ... @@ -63,6 +64,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
63 64 private ZLMRTPServerFactory zlmrtpServerFactory;
64 65  
65 66 @Autowired
  67 + private ZlmHttpHookSubscribe hookSubscribe;
  68 +
  69 + @Autowired
66 70 private IMediaServerService mediaServerService;
67 71  
68 72 @Autowired
... ... @@ -130,8 +134,18 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
130 134 startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, jsonObject, param, callIdHeader);
131 135 });
132 136 }else {
133   - JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
134   - startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, jsonObject, param, callIdHeader);
  137 + // 如果是非严格模式,需要关闭端口占用
  138 + JSONObject startSendRtpStreamResult = null;
  139 + if (sendRtpItem.getLocalPort() != 0) {
  140 + if (zlmrtpServerFactory.releasePort(mediaInfo, sendRtpItem.getSsrc())) {
  141 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  142 + }
  143 + }else {
  144 + startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
  145 + }
  146 + if (startSendRtpStreamResult != null) {
  147 + startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader);
  148 + }
135 149 }
136 150 }
137 151 private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform,
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -45,6 +45,7 @@ import javax.sip.header.CallIdHeader;
45 45 import javax.sip.message.Response;
46 46 import java.text.ParseException;
47 47 import java.time.Instant;
  48 +import java.util.Random;
48 49 import java.util.Vector;
49 50  
50 51 /**
... ... @@ -157,11 +158,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
157 158 StreamProxyItem proxyByAppAndStream =null;
158 159 // 不是通道可能是直播流
159 160 if (channel != null && gbStream == null) {
160   -// if (channel.getStatus() == 0) {
161   -// logger.info("通道离线,返回400");
162   -// responseAck(request, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
163   -// return;
164   -// }
165 161 // 通道存在,发100,TRYING
166 162 try {
167 163 responseAck(request, Response.TRYING);
... ... @@ -385,7 +381,12 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
385 381 } else {
386 382 content.append("t=0 0\r\n");
387 383 }
388   - content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n");
  384 + int localPort = sendRtpItem.getLocalPort();
  385 + if (localPort == 0) {
  386 + // 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口
  387 + localPort = new Random().nextInt(65535) + 1;
  388 + }
  389 + content.append("m=video " + localPort + " RTP/AVP 96\r\n");
389 390 content.append("a=sendonly\r\n");
390 391 content.append("a=rtpmap:96 PS/90000\r\n");
391 392 content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
... ... @@ -476,9 +477,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
476 477  
477 478 // 写入redis, 超时时回复
478 479 redisCatchStorage.updateSendRTPSever(sendRtpItem);
  480 + MediaServerItem finalMediaServerItem = mediaServerItem;
479 481 playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
480 482 logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId);
481 483 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
  484 + zlmrtpServerFactory.releasePort(finalMediaServerItem, sendRtpItem.getSsrc());
482 485 }, null);
483 486 } else {
484 487 sendRtpItem.setStreamId(playTransaction.getStream());
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -626,6 +626,32 @@ public class ZLMHttpHookListener {
626 626 return ret;
627 627 }
628 628  
  629 + /**
  630 + * rtpServer收流超时
  631 + */
  632 + @ResponseBody
  633 + @PostMapping(value = "/on_rtp_server_timeout", produces = "application/json;charset=UTF-8")
  634 + public JSONObject onRtpServerTimeout(HttpServletRequest request, @RequestBody OnRtpServerTimeoutHookParam param){
  635 + System.out.println(param);
  636 + logger.info("[ZLM HOOK] rtpServer收流超时:{}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc());
  637 +
  638 + JSONObject ret = new JSONObject();
  639 + ret.put("code", 0);
  640 + ret.put("msg", "success");
  641 +
  642 + taskExecutor.execute(()->{
  643 + JSONObject json = (JSONObject) JSON.toJSON(param);
  644 + List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout);
  645 + if (subscribes != null && subscribes.size() > 0) {
  646 + for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
  647 + subscribe.response(null, json);
  648 + }
  649 + }
  650 + });
  651 +
  652 + return ret;
  653 + }
  654 +
629 655 private Map<String, String> urlParamToMap(String params) {
630 656 HashMap<String, String> map = new HashMap<>();
631 657 if (ObjectUtils.isEmpty(params)) {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
1 1 package com.genersoft.iot.vmp.media.zlm;
2 2  
  3 +import com.alibaba.fastjson2.JSON;
3 4 import com.alibaba.fastjson2.JSONArray;
4 5 import com.alibaba.fastjson2.JSONObject;
5 6 import com.genersoft.iot.vmp.conf.UserSetting;
6 7 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
7   -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  8 +import com.genersoft.iot.vmp.media.zlm.dto.*;
8 9 import org.slf4j.Logger;
9 10 import org.slf4j.LoggerFactory;
10 11 import org.springframework.beans.factory.annotation.Autowired;
11 12 import org.springframework.stereotype.Component;
12   -import org.springframework.util.ObjectUtils;
13 13  
14 14 import java.util.*;
15 15  
... ... @@ -24,6 +24,9 @@ public class ZLMRTPServerFactory {
24 24 @Autowired
25 25 private UserSetting userSetting;
26 26  
  27 + @Autowired
  28 + private ZlmHttpHookSubscribe hookSubscribe;
  29 +
27 30 private int[] portRangeArray = new int[2];
28 31  
29 32 public int getFreePort(MediaServerItem mediaServerItem, int startPort, int endPort, List<Integer> usedFreelist) {
... ... @@ -141,7 +144,7 @@ public class ZLMRTPServerFactory {
141 144 return result;
142 145 }
143 146  
144   - public boolean closeRTPServer(MediaServerItem serverItem, String streamId) {
  147 + public boolean closeRtpServer(MediaServerItem serverItem, String streamId) {
145 148 boolean result = false;
146 149 if (serverItem !=null){
147 150 Map<String, Object> param = new HashMap<>();
... ... @@ -161,32 +164,6 @@ public class ZLMRTPServerFactory {
161 164 return result;
162 165 }
163 166  
164   -// private int getPortFromportRange(MediaServerItem mediaServerItem) {
165   -// int currentPort = mediaServerItem.getCurrentPort();
166   -// if (currentPort == 0) {
167   -// String[] portRangeStrArray = mediaServerItem.getSendRtpPortRange().split(",");
168   -// if (portRangeStrArray.length != 2) {
169   -// portRangeArray[0] = 30000;
170   -// portRangeArray[1] = 30500;
171   -// }else {
172   -// portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
173   -// portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
174   -// }
175   -// }
176   -//
177   -// if (currentPort == 0 || currentPort++ > portRangeArray[1]) {
178   -// currentPort = portRangeArray[0];
179   -// mediaServerItem.setCurrentPort(currentPort);
180   -// return portRangeArray[0];
181   -// } else {
182   -// if (currentPort % 2 == 1) {
183   -// currentPort++;
184   -// }
185   -// currentPort++;
186   -// mediaServerItem.setCurrentPort(currentPort);
187   -// return currentPort;
188   -// }
189   -// }
190 167  
191 168 /**
192 169 * 创建一个国标推流
... ... @@ -200,21 +177,15 @@ public class ZLMRTPServerFactory {
200 177 */
201 178 public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
202 179  
203   - // 使用RTPServer 功能找一个可用的端口
204   - String sendRtpPortRange = serverItem.getSendRtpPortRange();
205   - if (ObjectUtils.isEmpty(sendRtpPortRange)) {
206   - return null;
207   - }
208   - String[] portRangeStrArray = serverItem.getSendRtpPortRange().split(",");
209   - int localPort = -1;
210   - if (portRangeStrArray.length != 2) {
211   - localPort = getFreePort(serverItem, 30000, 30500, null);
212   - }else {
213   - localPort = getFreePort(serverItem, Integer.parseInt(portRangeStrArray[0]), Integer.parseInt(portRangeStrArray[1]), null);
214   - }
215   - if (localPort == -1) {
216   - logger.error("没有可用的端口");
217   - return null;
  180 + // 默认为随机端口
  181 + int localPort = 0;
  182 + if (userSetting.getGbSendStreamStrict()) {
  183 + if (userSetting.getGbSendStreamStrict()) {
  184 + localPort = keepPort(serverItem, ssrc);
  185 + if (localPort == 0) {
  186 + return null;
  187 + }
  188 + }
218 189 }
219 190 SendRtpItem sendRtpItem = new SendRtpItem();
220 191 sendRtpItem.setIp(ip);
... ... @@ -242,21 +213,13 @@ public class ZLMRTPServerFactory {
242 213 * @return SendRtpItem
243 214 */
244 215 public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){
245   - // 使用RTPServer 功能找一个可用的端口
246   - String sendRtpPortRange = serverItem.getSendRtpPortRange();
247   - if (ObjectUtils.isEmpty(sendRtpPortRange)) {
248   - return null;
249   - }
250   - String[] portRangeStrArray = serverItem.getSendRtpPortRange().split(",");
251   - int localPort = -1;
252   - if (portRangeStrArray.length != 2) {
253   - localPort = getFreePort(serverItem, 30000, 30500, null);
254   - }else {
255   - localPort = getFreePort(serverItem, Integer.parseInt(portRangeStrArray[0]), Integer.parseInt(portRangeStrArray[1]), null);
256   - }
257   - if (localPort == -1) {
258   - logger.error("没有可用的端口");
259   - return null;
  216 + // 默认为随机端口
  217 + int localPort = 0;
  218 + if (userSetting.getGbSendStreamStrict()) {
  219 + localPort = keepPort(serverItem, ssrc);
  220 + if (localPort == 0) {
  221 + return null;
  222 + }
260 223 }
261 224 SendRtpItem sendRtpItem = new SendRtpItem();
262 225 sendRtpItem.setIp(ip);
... ... @@ -274,6 +237,42 @@ public class ZLMRTPServerFactory {
274 237 }
275 238  
276 239 /**
  240 + * 保持端口,直到需要需要发流时再释放
  241 + */
  242 + public int keepPort(MediaServerItem serverItem, String ssrc) {
  243 + int localPort = 0;
  244 + Map<String, Object> param = new HashMap<>(3);
  245 + param.put("port", 0);
  246 + param.put("enable_tcp", 1);
  247 + param.put("stream_id", ssrc);
  248 + JSONObject jsonObject = zlmresTfulUtils.openRtpServer(serverItem, param);
  249 + if (jsonObject.getInteger("code") == 0) {
  250 + localPort = jsonObject.getInteger("port");
  251 + HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId());
  252 + // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
  253 + hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
  254 + (MediaServerItem mediaServerItem, JSONObject response)->{
  255 + logger.info("[上级点播] {}->监听端口到期继续保持监听", ssrc);
  256 + keepPort(serverItem, ssrc);
  257 + });
  258 + }
  259 + logger.info("[上级点播] {}->监听端口: {}", ssrc, localPort);
  260 + return localPort;
  261 + }
  262 +
  263 + /**
  264 + * 释放保持的端口
  265 + */
  266 + public boolean releasePort(MediaServerItem serverItem, String ssrc) {
  267 + logger.info("[上级点播] {}->释放监听端口,等待推流", ssrc);
  268 + boolean closeRTPServerResult = closeRtpServer(serverItem, ssrc);
  269 + HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId());
  270 + // 订阅 zlm启动事件, 新的zlm也会从这里进入系统
  271 + hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout);
  272 + return closeRTPServerResult;
  273 + }
  274 +
  275 + /**
277 276 * 调用zlm RESTFUL API —— startSendRtp
278 277 */
279 278 public JSONObject startSendRtpStream(MediaServerItem mediaServerItem, Map<String, Object>param) {
... ... @@ -333,7 +332,7 @@ public class ZLMRTPServerFactory {
333 332 result= true;
334 333 logger.info("[停止RTP推流] 成功");
335 334 } else {
336   - logger.error("[停止RTP推流] 失败: {}, 参数:{}->\r\n{}",jsonObject.getString("msg"),jsonObject.toJSONString(param));
  335 + logger.error("[停止RTP推流] 失败: {}, 参数:{}->\r\n{}",jsonObject.getString("msg"), JSON.toJSON(param), jsonObject);
337 336 }
338 337 return result;
339 338 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
... ... @@ -18,7 +18,11 @@ import org.springframework.core.annotation.Order;
18 18 import org.springframework.scheduling.annotation.Async;
19 19 import org.springframework.stereotype.Component;
20 20  
21   -import java.util.*;
  21 +import java.util.HashMap;
  22 +import java.util.List;
  23 +import java.util.Map;
  24 +import java.util.Set;
  25 +import java.util.concurrent.ConcurrentHashMap;
22 26  
23 27 @Component
24 28 @Order(value=1)
... ... @@ -73,8 +77,6 @@ public class ZLMRunner implements CommandLineRunner {
73 77 }
74 78 });
75 79  
76   -
77   -
78 80 // 获取zlm信息
79 81 logger.info("[zlm] 等待默认zlm中...");
80 82  
... ... @@ -87,7 +89,7 @@ public class ZLMRunner implements CommandLineRunner {
87 89 }
88 90 for (MediaServerItem mediaServerItem : all) {
89 91 if (startGetMedia == null) {
90   - startGetMedia = new HashMap<>();
  92 + startGetMedia = new ConcurrentHashMap<>();
91 93 }
92 94 startGetMedia.put(mediaServerItem.getId(), true);
93 95 connectZlmServer(mediaServerItem);
... ... @@ -95,7 +97,7 @@ public class ZLMRunner implements CommandLineRunner {
95 97 }
96 98 String taskKey = "zlm-connect-timeout";
97 99 dynamicTask.startDelay(taskKey, ()->{
98   - if (startGetMedia != null) {
  100 + if (startGetMedia != null && startGetMedia.size() > 0) {
99 101 Set<String> allZlmId = startGetMedia.keySet();
100 102 for (String id : allZlmId) {
101 103 logger.error("[ {} ]]主动连接失败,不再尝试连接", id);
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeFactory.java
... ... @@ -24,6 +24,17 @@ public class HookSubscribeFactory {
24 24 return hookSubscribe;
25 25 }
26 26  
  27 + public static HookSubscribeForRtpServerTimeout on_rtp_server_timeout(String stream, String ssrc, String mediaServerId) {
  28 + HookSubscribeForRtpServerTimeout hookSubscribe = new HookSubscribeForRtpServerTimeout();
  29 + JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject();
  30 + subscribeKey.put("stream_id", stream);
  31 + subscribeKey.put("ssrc", ssrc);
  32 + subscribeKey.put("mediaServerId", mediaServerId);
  33 + hookSubscribe.setContent(subscribeKey);
  34 +
  35 + return hookSubscribe;
  36 + }
  37 +
27 38 public static HookSubscribeForServerStarted on_server_started() {
28 39 HookSubscribeForServerStarted hookSubscribe = new HookSubscribeForServerStarted();
29 40 hookSubscribe.setContent(new JSONObject());
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForRtpServerTimeout.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto;
  2 +
  3 +import com.alibaba.fastjson2.JSONObject;
  4 +import com.alibaba.fastjson2.annotation.JSONField;
  5 +
  6 +import java.time.Instant;
  7 +
  8 +/**
  9 + * hook订阅-收流超时
  10 + * @author lin
  11 + */
  12 +public class HookSubscribeForRtpServerTimeout implements IHookSubscribe{
  13 +
  14 + private HookType hookType = HookType.on_rtp_server_timeout;
  15 +
  16 + private JSONObject content;
  17 +
  18 + @JSONField(format="yyyy-MM-dd HH:mm:ss")
  19 + private Instant expires;
  20 +
  21 + @Override
  22 + public HookType getHookType() {
  23 + return hookType;
  24 + }
  25 +
  26 + @Override
  27 + public JSONObject getContent() {
  28 + return content;
  29 + }
  30 +
  31 + public void setContent(JSONObject content) {
  32 + this.content = content;
  33 + }
  34 +
  35 + @Override
  36 + public Instant getExpires() {
  37 + return expires;
  38 + }
  39 +
  40 + @Override
  41 + public void setExpires(Instant expires) {
  42 + this.expires = expires;
  43 + }
  44 +}
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookSubscribeForStreamChange.java
... ... @@ -15,6 +15,7 @@ public class HookSubscribeForStreamChange implements IHookSubscribe{
15 15  
16 16 private JSONObject content;
17 17  
  18 + @JSONField(format="yyyy-MM-dd HH:mm:ss")
18 19 private Instant expires;
19 20  
20 21 @Override
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookType.java
... ... @@ -19,5 +19,7 @@ public enum HookType {
19 19 on_stream_none_reader,
20 20 on_stream_not_found,
21 21 on_server_started,
  22 +
  23 + on_rtp_server_timeout,
22 24 on_server_keepalive
23 25 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaServerItem.java
... ... @@ -65,9 +65,6 @@ public class MediaServerItem{
65 65 @Schema(description = "多端口RTP收流端口范围")
66 66 private String rtpPortRange;
67 67  
68   - @Schema(description = "RTP发流端口范围")
69   - private String sendRtpPortRange;
70   -
71 68 @Schema(description = "assist服务端口")
72 69 private int recordAssistPort;
73 70  
... ... @@ -118,7 +115,6 @@ public class MediaServerItem{
118 115 hookAliveInterval = zlmServerConfig.getHookAliveInterval();
119 116 rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口
120 117 rtpPortRange = zlmServerConfig.getPortRange().replace("_",","); // 默认使用30000,30500作为级联时发送流的端口号
121   - sendRtpPortRange = "30000,30500"; // 默认使用30000,30500作为级联时发送流的端口号
122 118 recordAssistPort = 0; // 默认关闭
123 119  
124 120 }
... ... @@ -323,14 +319,6 @@ public class MediaServerItem{
323 319 this.lastKeepaliveTime = lastKeepaliveTime;
324 320 }
325 321  
326   - public String getSendRtpPortRange() {
327   - return sendRtpPortRange;
328   - }
329   -
330   - public void setSendRtpPortRange(String sendRtpPortRange) {
331   - this.sendRtpPortRange = sendRtpPortRange;
332   - }
333   -
334 322 public Float getHookAliveInterval() {
335 323 return hookAliveInterval;
336 324 }
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRtpServerTimeoutHookParam.java 0 → 100644
  1 +package com.genersoft.iot.vmp.media.zlm.dto.hook;
  2 +
  3 +/**
  4 + * zlm hook事件中的on_rtp_server_timeout事件的参数
  5 + * @author lin
  6 + */
  7 +public class OnRtpServerTimeoutHookParam extends HookParam{
  8 + private int local_port;
  9 + private String stream_id;
  10 + private int tcpMode;
  11 + private boolean re_use_port;
  12 + private String ssrc;
  13 +
  14 + public int getLocal_port() {
  15 + return local_port;
  16 + }
  17 +
  18 + public void setLocal_port(int local_port) {
  19 + this.local_port = local_port;
  20 + }
  21 +
  22 + public String getStream_id() {
  23 + return stream_id;
  24 + }
  25 +
  26 + public void setStream_id(String stream_id) {
  27 + this.stream_id = stream_id;
  28 + }
  29 +
  30 + public int getTcpMode() {
  31 + return tcpMode;
  32 + }
  33 +
  34 + public void setTcpMode(int tcpMode) {
  35 + this.tcpMode = tcpMode;
  36 + }
  37 +
  38 + public boolean isRe_use_port() {
  39 + return re_use_port;
  40 + }
  41 +
  42 + public void setRe_use_port(boolean re_use_port) {
  43 + this.re_use_port = re_use_port;
  44 + }
  45 +
  46 + public String getSsrc() {
  47 + return ssrc;
  48 + }
  49 +
  50 + public void setSsrc(String ssrc) {
  51 + this.ssrc = ssrc;
  52 + }
  53 +}
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
... ... @@ -4,13 +4,12 @@ import com.genersoft.iot.vmp.conf.DynamicTask;
4 4 import com.genersoft.iot.vmp.gb28181.bean.*;
5 5 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
6 6 import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
  7 +import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
  8 +import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
7 9 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
8 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
9   -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform;
10 11 import com.genersoft.iot.vmp.service.IDeviceChannelService;
11 12 import com.genersoft.iot.vmp.service.IDeviceService;
12   -import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
13   -import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
14 13 import com.genersoft.iot.vmp.service.IMediaServerService;
15 14 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
16 15 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
... ... @@ -24,12 +23,10 @@ import org.slf4j.Logger;
24 23 import org.slf4j.LoggerFactory;
25 24 import org.springframework.beans.factory.annotation.Autowired;
26 25 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
27   -import org.springframework.jdbc.support.incrementer.AbstractIdentityColumnMaxValueIncrementer;
28 26 import org.springframework.stereotype.Service;
29 27 import org.springframework.transaction.TransactionDefinition;
30 28 import org.springframework.transaction.TransactionStatus;
31 29 import org.springframework.util.ObjectUtils;
32   -import org.springframework.util.StringUtils;
33 30  
34 31 import javax.sip.InvalidArgumentException;
35 32 import javax.sip.SipException;
... ... @@ -171,7 +168,7 @@ public class DeviceServiceImpl implements IDeviceService {
171 168 redisCatchStorage.updateDevice(device);
172 169 deviceMapper.update(device);
173 170 //进行通道离线
174   - deviceChannelMapper.offlineByDeviceId(deviceId);
  171 +// deviceChannelMapper.offlineByDeviceId(deviceId);
175 172 // 离线释放所有ssrc
176 173 List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(deviceId, null, null, null);
177 174 if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -168,7 +168,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
168 168 if (mediaServerItem == null) {
169 169 return;
170 170 }
171   - zlmrtpServerFactory.closeRTPServer(mediaServerItem, streamId);
  171 + zlmrtpServerFactory.closeRtpServer(mediaServerItem, streamId);
172 172 releaseSsrc(mediaServerItem.getId(), streamId);
173 173 }
174 174  
... ... @@ -535,6 +535,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
535 535 param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
536 536 param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex));
537 537 param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrex));
  538 + param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrex));
538 539 if (mediaServerItem.getRecordAssistPort() > 0) {
539 540 param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort()));
540 541 }else {
... ... @@ -545,8 +546,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
545 546 // 置0关闭此特性(推流断开会导致立即断开播放器)
546 547 // 此参数不应大于播放器超时时间
547 548 // 优化此消息以更快的收到流注销事件
548   - param.put("general.continue_push_ms", "3000" );
549   - param.put("general.publishToHls", "0" );
  549 + param.put("protocol.continue_push_ms", "3000" );
550 550 // 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流,
551 551 // 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项
552 552 // param.put("general.wait_track_ready_ms", "3000" );
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -283,7 +283,7 @@ public class PlayServiceImpl implements IPlayService {
283 283 try {
284 284 cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
285 285 logger.info("收到订阅消息: " + response.toJSONString());
286   - System.out.println("停止超时任务: " + timeOutTaskKey);
  286 + dynamicTask.stop(timeOutTaskKey);
287 287  
288 288 // hook响应
289 289 onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId, uuid);
... ...
src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java
... ... @@ -28,7 +28,6 @@ public interface MediaServerMapper {
28 28 "secret, " +
29 29 "rtpEnable, " +
30 30 "rtpPortRange, " +
31   - "sendRtpPortRange, " +
32 31 "recordAssistPort, " +
33 32 "defaultServer, " +
34 33 "createTime, " +
... ... @@ -52,7 +51,6 @@ public interface MediaServerMapper {
52 51 "'${secret}', " +
53 52 "${rtpEnable}, " +
54 53 "'${rtpPortRange}', " +
55   - "'${sendRtpPortRange}', " +
56 54 "${recordAssistPort}, " +
57 55 "${defaultServer}, " +
58 56 "'${createTime}', " +
... ... @@ -77,7 +75,6 @@ public interface MediaServerMapper {
77 75 "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +
78 76 "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
79 77 "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
80   - "<if test=\"sendRtpPortRange != null\">, sendRtpPortRange='${sendRtpPortRange}'</if>" +
81 78 "<if test=\"secret != null\">, secret='${secret}'</if>" +
82 79 "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
83 80 "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +
... ... @@ -101,7 +98,6 @@ public interface MediaServerMapper {
101 98 "<if test=\"autoConfig != null\">, autoConfig=${autoConfig}</if>" +
102 99 "<if test=\"rtpEnable != null\">, rtpEnable=${rtpEnable}</if>" +
103 100 "<if test=\"rtpPortRange != null\">, rtpPortRange='${rtpPortRange}'</if>" +
104   - "<if test=\"sendRtpPortRange != null\">, sendRtpPortRange='${sendRtpPortRange}'</if>" +
105 101 "<if test=\"secret != null\">, secret='${secret}'</if>" +
106 102 "<if test=\"recordAssistPort != null\">, recordAssistPort=${recordAssistPort}</if>" +
107 103 "<if test=\"hookAliveInterval != null\">, hookAliveInterval=${hookAliveInterval}</if>" +
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
... ... @@ -62,7 +62,9 @@ public class MediaController {
62 62 if (callId != null) {
63 63 // 权限校验
64 64 StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
65   - if (streamAuthorityInfo.getCallId().equals(callId)) {
  65 + if (streamAuthorityInfo != null
  66 + && streamAuthorityInfo.getCallId() != null
  67 + && streamAuthorityInfo.getCallId().equals(callId)) {
66 68 authority = true;
67 69 }else {
68 70 throw new ControllerException(ErrorCode.ERROR400);
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
... ... @@ -135,14 +135,8 @@ public class ServerController {
135 135 MediaServerItem mediaServerItemInDatabase = mediaServerService.getOne(mediaServerItem.getId());
136 136  
137 137 if (mediaServerItemInDatabase != null) {
138   - if (ObjectUtils.isEmpty(mediaServerItemInDatabase.getSendRtpPortRange()) && ObjectUtils.isEmpty(mediaServerItem.getSendRtpPortRange())) {
139   - mediaServerItem.setSendRtpPortRange("30000,30500");
140   - }
141 138 mediaServerService.update(mediaServerItem);
142 139 } else {
143   - if (ObjectUtils.isEmpty(mediaServerItem.getSendRtpPortRange())) {
144   - mediaServerItem.setSendRtpPortRange("30000,30500");
145   - }
146 140 mediaServerService.add(mediaServerItem);
147 141 }
148 142 }
... ...
src/main/resources/all-application.yml
... ... @@ -192,6 +192,9 @@ user-settings:
192 192 stream-on-demand: true
193 193 # 推流鉴权, 默认开启
194 194 push-authority: true
  195 + # 国标级联发流严格模式,严格模式会使用与sdp信息中一致的端口发流,端口共享media.rtp.port-range,这会损失一些性能,
  196 + # 非严格模式使用随机端口发流,性能更好, 默认关闭
  197 + gb-send-stream-strict: false
195 198  
196 199 # 关闭在线文档(生产环境建议关闭)
197 200 springdoc:
... ...
web_src/src/components/dialog/MediaServerEdit.vue
... ... @@ -89,11 +89,6 @@
89 89 -
90 90 <el-input v-model="rtpPortRange2" placeholder="终止" @change="portRangeChange" clearable style="width: 100px" prop="rtpPortRange2" :disabled="mediaServerForm.defaultServer"></el-input>
91 91 </el-form-item>
92   - <el-form-item label="推流端口" prop="sendRtpPortRange1">
93   - <el-input v-model="sendRtpPortRange1" placeholder="起始" @change="portRangeChange" clearable style="width: 100px" prop="sendRtpPortRange1" :disabled="mediaServerForm.defaultServer"></el-input>
94   - -
95   - <el-input v-model="sendRtpPortRange2" placeholder="终止" @change="portRangeChange" clearable style="width: 100px" prop="sendRtpPortRange2" :disabled="mediaServerForm.defaultServer"></el-input>
96   - </el-form-item>
97 92 <el-form-item label="录像管理服务端口" prop="recordAssistPort">
98 93 <el-input v-model.number="mediaServerForm.recordAssistPort" :disabled="mediaServerForm.defaultServer">
99 94 <!-- <el-button v-if="mediaServerForm.recordAssistPort > 0" slot="append" type="primary" @click="checkRecordServer">测试</el-button>-->
... ... @@ -177,15 +172,12 @@ export default {
177 172 rtmpSSlPort: "",
178 173 rtpEnable: false,
179 174 rtpPortRange: "",
180   - sendRtpPortRange: "",
181 175 rtpProxyPort: "",
182 176 rtspPort: "",
183 177 rtspSSLPort: "",
184 178 },
185 179 rtpPortRange1:30000,
186 180 rtpPortRange2:30500,
187   - sendRtpPortRange1:30000,
188   - sendRtpPortRange2:30500,
189 181  
190 182 rules: {
191 183 ip: [{ required: true, validator: isValidIp, message: '请输入有效的IP地址', trigger: 'blur' }],
... ... @@ -196,8 +188,6 @@ export default {
196 188 rtmpSSlPort: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
197 189 rtpPortRange1: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
198 190 rtpPortRange2: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
199   - sendRtpPortRange1: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
200   - sendRtpPortRange2: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
201 191 rtpProxyPort: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
202 192 rtspPort: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
203 193 rtspSSLPort: [{ required: true, validator: isValidPort, message: '请输入有效的端口号', trigger: 'blur' }],
... ... @@ -229,9 +219,6 @@ export default {
229 219 this.rtpPortRange2 = rtpPortRange[1]
230 220 }
231 221 }
232   - let sendRtpPortRange = this.mediaServerForm.sendRtpPortRange.split(",");
233   - this.sendRtpPortRange1 = sendRtpPortRange[0]
234   - this.sendRtpPortRange2 = sendRtpPortRange[1]
235 222 }
236 223 },
237 224 checkServer: function() {
... ... @@ -251,8 +238,6 @@ export default {
251 238 that.mediaServerForm = data.data;
252 239 that.mediaServerForm.httpPort = httpPort;
253 240 that.mediaServerForm.autoConfig = true;
254   - that.sendRtpPortRange1 = 30000
255   - that.sendRtpPortRange2 = 30500
256 241 that.rtpPortRange1 = 30000
257 242 that.rtpPortRange2 = 30500
258 243 that.serverCheck = 1;
... ... @@ -336,13 +321,10 @@ export default {
336 321 rtmpSSlPort: "",
337 322 rtpEnable: false,
338 323 rtpPortRange: "",
339   - sendRtpPortRange: "",
340 324 rtpProxyPort: "",
341 325 rtspPort: "",
342 326 rtspSSLPort: "",
343 327 };
344   - this.sendRtpPortRange1 = 30000;
345   - this.sendRtpPortRange2 = 30500;
346 328 this.rtpPortRange1 = 30500;
347 329 this.rtpPortRange2 = 30500;
348 330 this.listChangeCallback = null
... ... @@ -367,9 +349,7 @@ export default {
367 349 }
368 350 },
369 351 portRangeChange: function() {
370   - this.mediaServerForm.sendRtpPortRange = this.sendRtpPortRange1 + "," + this.sendRtpPortRange2
371 352 this.mediaServerForm.rtpPortRange = this.rtpPortRange1 + "," + this.rtpPortRange2
372   - console.log(this.mediaServerForm.sendRtpPortRange)
373 353 console.log(this.mediaServerForm.rtpPortRange)
374 354 }
375 355 },
... ...