Commit bfd1628d5b6e753091b0aa702a520b08cc64cc76

Authored by 648540858
1 parent 1ec6c450

修复重复调用open rtp server 的bug

增加对rtp server开启释放的统一管理
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
@@ -213,4 +213,11 @@ public interface ISIPCommander { @@ -213,4 +213,11 @@ public interface ISIPCommander {
213 * @param device 视频设备 213 * @param device 视频设备
214 */ 214 */
215 boolean mobilePostitionQuery(Device device); 215 boolean mobilePostitionQuery(Device device);
  216 +
  217 + /**
  218 + * 释放rtpserver
  219 + * @param device
  220 + * @param channelId
  221 + */
  222 + void closeRTPServer(Device device, String channelId);
216 } 223 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -8,7 +8,6 @@ import javax.sip.ClientTransaction; @@ -8,7 +8,6 @@ import javax.sip.ClientTransaction;
8 import javax.sip.Dialog; 8 import javax.sip.Dialog;
9 import javax.sip.InvalidArgumentException; 9 import javax.sip.InvalidArgumentException;
10 import javax.sip.SipException; 10 import javax.sip.SipException;
11 -import javax.sip.SipFactory;  
12 import javax.sip.SipProvider; 11 import javax.sip.SipProvider;
13 import javax.sip.TransactionDoesNotExistException; 12 import javax.sip.TransactionDoesNotExistException;
14 import javax.sip.address.SipURI; 13 import javax.sip.address.SipURI;
@@ -16,11 +15,10 @@ import javax.sip.header.ViaHeader; @@ -16,11 +15,10 @@ import javax.sip.header.ViaHeader;
16 import javax.sip.message.Request; 15 import javax.sip.message.Request;
17 16
18 import com.alibaba.fastjson.JSONObject; 17 import com.alibaba.fastjson.JSONObject;
19 -import com.genersoft.iot.vmp.common.StreamInfo;  
20 import com.genersoft.iot.vmp.conf.MediaServerConfig; 18 import com.genersoft.iot.vmp.conf.MediaServerConfig;
21 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; 19 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
22 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; 20 import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe;
23 -import com.genersoft.iot.vmp.media.zlm.ZLMUtils; 21 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
24 import com.genersoft.iot.vmp.storager.IVideoManagerStorager; 22 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
25 import org.springframework.beans.factory.annotation.Autowired; 23 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.beans.factory.annotation.Qualifier; 24 import org.springframework.beans.factory.annotation.Qualifier;
@@ -63,7 +61,7 @@ public class SIPCommander implements ISIPCommander { @@ -63,7 +61,7 @@ public class SIPCommander implements ISIPCommander {
63 private SipProvider udpSipProvider; 61 private SipProvider udpSipProvider;
64 62
65 @Autowired 63 @Autowired
66 - private ZLMUtils zlmUtils; 64 + private ZLMRTPServerFactory zlmrtpServerFactory;
67 65
68 @Value("${media.rtp.enable}") 66 @Value("${media.rtp.enable}")
69 private boolean rtpEnable; 67 private boolean rtpEnable;
@@ -288,7 +286,7 @@ public class SIPCommander implements ISIPCommander { @@ -288,7 +286,7 @@ public class SIPCommander implements ISIPCommander {
288 String mediaPort = null; 286 String mediaPort = null;
289 // 使用动态udp端口 287 // 使用动态udp端口
290 if (rtpEnable) { 288 if (rtpEnable) {
291 - mediaPort = zlmUtils.getNewRTPPort(streamId) + ""; 289 + mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + "";
292 }else { 290 }else {
293 mediaPort = mediaInfo.getRtpProxyPort(); 291 mediaPort = mediaInfo.getRtpProxyPort();
294 } 292 }
@@ -383,7 +381,7 @@ public class SIPCommander implements ISIPCommander { @@ -383,7 +381,7 @@ public class SIPCommander implements ISIPCommander {
383 String mediaPort = null; 381 String mediaPort = null;
384 // 使用动态udp端口 382 // 使用动态udp端口
385 if (rtpEnable) { 383 if (rtpEnable) {
386 - mediaPort = zlmUtils.getNewRTPPort(streamId) + ""; 384 + mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + "";
387 }else { 385 }else {
388 mediaPort = mediaInfo.getRtpProxyPort(); 386 mediaPort = mediaInfo.getRtpProxyPort();
389 } 387 }
@@ -459,6 +457,7 @@ public class SIPCommander implements ISIPCommander { @@ -459,6 +457,7 @@ public class SIPCommander implements ISIPCommander {
459 } 457 }
460 dialog.sendRequest(clientTransaction); 458 dialog.sendRequest(clientTransaction);
461 streamSession.remove(streamId); 459 streamSession.remove(streamId);
  460 + zlmrtpServerFactory.closeRTPServer(streamId);
462 } catch (TransactionDoesNotExistException e) { 461 } catch (TransactionDoesNotExistException e) {
463 e.printStackTrace(); 462 e.printStackTrace();
464 } catch (SipException e) { 463 } catch (SipException e) {
@@ -701,4 +700,11 @@ public class SIPCommander implements ISIPCommander { @@ -701,4 +700,11 @@ public class SIPCommander implements ISIPCommander {
701 } 700 }
702 701
703 702
  703 + @Override
  704 + public void closeRTPServer(Device device, String channelId) {
  705 + if (rtpEnable) {
  706 + String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
  707 + zlmrtpServerFactory.closeRTPServer(streamId);
  708 + }
  709 + }
704 } 710 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -116,4 +116,8 @@ public class ZLMRESTfulUtils { @@ -116,4 +116,8 @@ public class ZLMRESTfulUtils {
116 public JSONObject openRtpServer(Map<String, Object> param){ 116 public JSONObject openRtpServer(Map<String, Object> param){
117 return sendPost("openRtpServer",param); 117 return sendPost("openRtpServer",param);
118 } 118 }
  119 +
  120 + public JSONObject closeRtpServer(Map<String, Object> param) {
  121 + return sendPost("closeRtpServer",param);
  122 + }
119 } 123 }
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java deleted 100644 → 0
1 -package com.genersoft.iot.vmp.media.zlm;  
2 -  
3 -import com.alibaba.fastjson.JSONObject;  
4 -import org.springframework.beans.factory.annotation.Autowired;  
5 -import org.springframework.beans.factory.annotation.Value;  
6 -import org.springframework.stereotype.Component;  
7 -  
8 -import java.util.HashMap;  
9 -import java.util.Map;  
10 -  
11 -@Component  
12 -public class ZLMUtils {  
13 -  
14 - @Value("${media.rtp.udpPortRange}")  
15 - private String udpPortRange;  
16 -  
17 - @Autowired  
18 - private ZLMRESTfulUtils zlmresTfulUtils;  
19 -  
20 - private int[] udpPortRangeArray = new int[2];  
21 -  
22 - private int currentPort = 0;  
23 -  
24 - public int getNewRTPPort(String streamId) {  
25 -// String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();  
26 - Map<String, Object> param = new HashMap<>();  
27 - int newPort = getPortFromUdpPortRange();  
28 - param.put("port", newPort);  
29 - param.put("enable_tcp", 1);  
30 - param.put("stream_id", streamId);  
31 - JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param);  
32 - if (jsonObject != null && jsonObject.getInteger("code") == 0) {  
33 - return newPort;  
34 - } else {  
35 - return getNewRTPPort(streamId);  
36 - }  
37 - }  
38 -  
39 - private int getPortFromUdpPortRange() {  
40 - if (currentPort == 0) {  
41 - String[] udpPortRangeStrArray = udpPortRange.split(",");  
42 - udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]);  
43 - udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]);  
44 - }  
45 -  
46 - if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) {  
47 - currentPort = udpPortRangeArray[0];  
48 - return udpPortRangeArray[0];  
49 - } else {  
50 - if (currentPort % 2 == 1) {  
51 - currentPort++;  
52 - }  
53 - return currentPort++;  
54 - }  
55 - }  
56 -}  
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig; @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig;
7 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 7 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
8 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; 8 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
9 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; 9 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  10 +import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
10 import com.genersoft.iot.vmp.vmanager.service.IPlayService; 11 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
11 import org.slf4j.Logger; 12 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
@@ -62,14 +63,7 @@ public class PlayController { @@ -62,14 +63,7 @@ public class PlayController {
62 63
63 UUID uuid = UUID.randomUUID(); 64 UUID uuid = UUID.randomUUID();
64 DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(); 65 DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
65 - // 超时处理  
66 - result.onTimeout(()->{  
67 - logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));  
68 - RequestMessage msg = new RequestMessage();  
69 - msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);  
70 - msg.setData("Timeout");  
71 - resultHolder.invokeResult(msg);  
72 - }); 66 +
73 // 录像查询以channelId作为deviceId查询 67 // 录像查询以channelId作为deviceId查询
74 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result); 68 resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
75 69
@@ -89,13 +83,23 @@ public class PlayController { @@ -89,13 +83,23 @@ public class PlayController {
89 resultHolder.invokeResult(msg); 83 resultHolder.invokeResult(msg);
90 } else { 84 } else {
91 storager.stopPlay(streamInfo); 85 storager.stopPlay(streamInfo);
92 - // TODO playStreamCmd 超时处理  
93 cmder.playStreamCmd(device, channelId, (JSONObject response) -> { 86 cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
94 logger.info("收到订阅消息: " + response.toJSONString()); 87 logger.info("收到订阅消息: " + response.toJSONString());
95 playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString()); 88 playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
96 }); 89 });
97 } 90 }
98 } 91 }
  92 +
  93 + // 超时处理
  94 + result.onTimeout(()->{
  95 + logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
  96 + // 释放rtpserver
  97 + cmder.closeRTPServer(device, channelId);
  98 + RequestMessage msg = new RequestMessage();
  99 + msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
  100 + msg.setData("Timeout");
  101 + resultHolder.invokeResult(msg);
  102 + });
99 return result; 103 return result;
100 } 104 }
101 105
src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java
@@ -86,6 +86,8 @@ public class ApiStreamController { @@ -86,6 +86,8 @@ public class ApiStreamController {
86 JSONObject result = new JSONObject(); 86 JSONObject result = new JSONObject();
87 result.put("error","timeout"); 87 result.put("error","timeout");
88 resultDeferredResult.setResult(result); 88 resultDeferredResult.setResult(result);
  89 +
  90 + // 清理RTP server
89 }); 91 });
90 92
91 DeviceChannel deviceChannel = storager.queryChannel(serial, code); 93 DeviceChannel deviceChannel = storager.queryChannel(serial, code);