Sfoglia il codice sorgente

修复重复调用open rtp server 的bug
增加对rtp server开启释放的统一管理

648540858 5 anni fa
parent
commit
bfd1628d5b

+ 7 - 0
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java

@@ -213,4 +213,11 @@ public interface ISIPCommander {
 	 * @param device 视频设备
 	 */
 	boolean mobilePostitionQuery(Device device);
+
+	/**
+	 * 释放rtpserver
+	 * @param device
+	 * @param channelId
+	 */
+    void closeRTPServer(Device device, String channelId);
 }

+ 12 - 6
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java

@@ -8,7 +8,6 @@ import javax.sip.ClientTransaction;
 import javax.sip.Dialog;
 import javax.sip.InvalidArgumentException;
 import javax.sip.SipException;
-import javax.sip.SipFactory;
 import javax.sip.SipProvider;
 import javax.sip.TransactionDoesNotExistException;
 import javax.sip.address.SipURI;
@@ -16,11 +15,10 @@ import javax.sip.header.ViaHeader;
 import javax.sip.message.Request;
 
 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.ZLMHttpHookSubscribe;
-import com.genersoft.iot.vmp.media.zlm.ZLMUtils;
+import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -63,7 +61,7 @@ public class SIPCommander implements ISIPCommander {
 	private SipProvider udpSipProvider;
 
 	@Autowired
-	private ZLMUtils zlmUtils;
+	private ZLMRTPServerFactory zlmrtpServerFactory;
 
 	@Value("${media.rtp.enable}")
 	private boolean rtpEnable;
@@ -288,7 +286,7 @@ public class SIPCommander implements ISIPCommander {
 			String mediaPort = null;
 			// 使用动态udp端口
 			if (rtpEnable) {
-				mediaPort = zlmUtils.getNewRTPPort(streamId) + "";
+				mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + "";
 			}else {
 				mediaPort = mediaInfo.getRtpProxyPort();
 			}
@@ -383,7 +381,7 @@ public class SIPCommander implements ISIPCommander {
 			String mediaPort = null;
 			// 使用动态udp端口
 			if (rtpEnable) {
-				mediaPort = zlmUtils.getNewRTPPort(streamId) + "";
+				mediaPort = zlmrtpServerFactory.createRTPServer(streamId) + "";
 			}else {
 				mediaPort = mediaInfo.getRtpProxyPort();
 			}
@@ -459,6 +457,7 @@ public class SIPCommander implements ISIPCommander {
 			}
 			dialog.sendRequest(clientTransaction);
 			streamSession.remove(streamId);
+			zlmrtpServerFactory.closeRTPServer(streamId);
 		} catch (TransactionDoesNotExistException e) {
 			e.printStackTrace();
 		} catch (SipException e) {
@@ -701,4 +700,11 @@ public class SIPCommander implements ISIPCommander {
 	}
 
 
+	@Override
+	public void closeRTPServer(Device device, String channelId) {
+		if (rtpEnable) {
+			String streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId);
+			zlmrtpServerFactory.closeRTPServer(streamId);
+		}
+	}
 }

+ 4 - 0
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java

@@ -116,4 +116,8 @@ public class ZLMRESTfulUtils {
     public JSONObject openRtpServer(Map<String, Object> param){
         return sendPost("openRtpServer",param);
     }
+
+    public JSONObject closeRtpServer(Map<String, Object> param) {
+        return sendPost("closeRtpServer",param);
+    }
 }

+ 0 - 56
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java

@@ -1,56 +0,0 @@
-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 streamId) {
-//        String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
-        Map<String, Object> param = new HashMap<>();
-        int newPort = getPortFromUdpPortRange();
-        param.put("port", newPort);
-        param.put("enable_tcp", 1);
-        param.put("stream_id", streamId);
-        JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param);
-        if (jsonObject != null && jsonObject.getInteger("code") == 0) {
-            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 {
-            if (currentPort % 2 == 1) {
-                currentPort++;
-            }
-            return currentPort++;
-        }
-    }
-}

+ 13 - 9
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java

@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
+import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.vmanager.service.IPlayService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,14 +63,7 @@ public class PlayController {
 
 		UUID uuid = UUID.randomUUID();
 		DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
-		// 超时处理
-		result.onTimeout(()->{
-			logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
-			RequestMessage msg = new RequestMessage();
-			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
-			msg.setData("Timeout");
-			resultHolder.invokeResult(msg);
-		});
+
 		// 录像查询以channelId作为deviceId查询
 		resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
 
@@ -89,13 +83,23 @@ public class PlayController {
 				resultHolder.invokeResult(msg);
 			} else {
 				storager.stopPlay(streamInfo);
-				// TODO playStreamCmd 超时处理
 				cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
 					logger.info("收到订阅消息: " + response.toJSONString());
 					playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
 				});
 			}
 		}
+
+		// 超时处理
+		result.onTimeout(()->{
+			logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
+			// 释放rtpserver
+			cmder.closeRTPServer(device, channelId);
+			RequestMessage msg = new RequestMessage();
+			msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
+			msg.setData("Timeout");
+			resultHolder.invokeResult(msg);
+		});
 		return result;
 	}
 

+ 2 - 0
src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java

@@ -86,6 +86,8 @@ public class ApiStreamController {
             JSONObject result = new JSONObject();
             result.put("error","timeout");
             resultDeferredResult.setResult(result);
+
+             // 清理RTP server
         });
 
         DeviceChannel deviceChannel = storager.queryChannel(serial, code);