From 3fe47021b9aefb11b1e659383ac2f3d0edd2aa42 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期四, 04 五月 2023 14:21:58 +0800
Subject: [PATCH] 优化国标规范,参考国标文档中-点播外域设备媒体流SSRC处理方式,上级点播时自定义ssrc,不适用上级携带的ssrc,也避免上级兼容性差,不携带ssrc的问题,可通过配置关闭此特性

---
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java |   44 ++++++++++++----------
 src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java                                     |    5 ++
 src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java                           |    5 ++
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                              |    5 ++
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                        |    7 +++
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java    |    5 ++
 src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java                                           |    9 ++++
 src/main/resources/all-application.yml                                                              |    2 +
 8 files changed, 61 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
index 539198f..5ae9236 100644
--- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
+++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -53,6 +53,7 @@
     private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
 
     private Boolean deviceStatusNotify = Boolean.FALSE;
+    private Boolean useCustomSsrcForParentInvite = Boolean.TRUE;
 
     private String serverId = "000000";
 
@@ -277,4 +278,12 @@
     public void setDeviceStatusNotify(Boolean deviceStatusNotify) {
         this.deviceStatusNotify = deviceStatusNotify;
     }
+
+    public Boolean getUseCustomSsrcForParentInvite() {
+        return useCustomSsrcForParentInvite;
+    }
+
+    public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) {
+        this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite;
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
index 3352838..17c23a0 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
@@ -5,6 +5,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -36,6 +37,9 @@
 
     @Autowired
     private IRedisCatchStorage redisCatchStorage;
+
+    @Autowired
+    private SSRCFactory ssrcFactory;
 
     @Autowired
     private UserSetting userSetting;
@@ -96,6 +100,7 @@
                 MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId());
                 redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStreamId());
                 if (mediaServerItem != null) {
+                    ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
                     Map<String, Object> param = new HashMap<>();
                     param.put("vhost","__defaultVhost__");
                     param.put("app",sendRtpItem.getApp());
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
index addd633..cc3051f 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -6,6 +6,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
 import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
@@ -61,6 +62,9 @@
 	private ZLMRTPServerFactory zlmrtpServerFactory;
 
 	@Autowired
+	private SSRCFactory ssrcFactory;
+
+	@Autowired
 	private IMediaServerService mediaServerService;
 
 	@Autowired
@@ -102,6 +106,7 @@
 				logger.info("[鏀跺埌bye] 鍋滄鍚戜笂绾ф帹娴侊細{}", streamId);
 				MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
 				redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
+				ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
 				zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
 				int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
 				if (totalReaderCount <= 0) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
index a4367b4..c235320 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -245,18 +245,15 @@
                 String contentString = new String(request.getRawContent());
 
                 // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎浠ヨВ鏋愩��
-                int ssrcIndex = contentString.indexOf("y=");
                 // 妫�鏌ユ槸鍚︽湁y瀛楁
-                String ssrcDefault = "0000000000";
-                String ssrc;
+                int ssrcIndex = contentString.indexOf("y=");
+
                 SessionDescription sdp;
                 if (ssrcIndex >= 0) {
                     //ssrc瑙勫畾闀垮害涓�10涓瓧鑺傦紝涓嶅彇浣欎笅闀垮害浠ラ伩鍏嶅悗缁繕鏈夆�渇=鈥濆瓧娈�
-                    ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
-                    String substring = contentString.substring(0, contentString.indexOf("y="));
+                    String substring = contentString.substring(0, ssrcIndex);
                     sdp = SdpFactory.getInstance().createSessionDescription(substring);
                 } else {
-                    ssrc = ssrcDefault;
                     sdp = SdpFactory.getInstance().createSessionDescription(contentString);
                 }
                 String sessionName = sdp.getSessionName().getValue();
@@ -320,7 +317,7 @@
                 String username = sdp.getOrigin().getUsername();
                 String addressStr = sdp.getConnection().getAddress();
 
-                logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}, 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, channelId, addressStr, port, ssrc);
+
                 Device device = null;
                 // 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍�
                 if (channel != null) {
@@ -344,6 +341,15 @@
                         }
                         return;
                     }
+
+                    String ssrc;
+                    if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) {
+                        // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+                        ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+                    }else {
+                        ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
+                    }
+                    logger.info("[涓婄骇鐐规挱] 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}, 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, channelId, addressStr, port, ssrc);
                     SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                             device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
 
@@ -465,29 +471,23 @@
                             }
                         }
                         if (playTransaction == null) {
+                            // 琚偣鎾殑閫氶亾鐩墠鏈鐐规挱锛屽垯寮�濮嬬偣鎾�
                             String streamId = null;
                             if (mediaServerItem.isRtpEnable()) {
                                 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
                             }
-                            SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
+                            SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
                             logger.info(JSONObject.toJSONString(ssrcInfo));
                             sendRtpItem.setStreamId(ssrcInfo.getStream());
-                            sendRtpItem.setSsrc(ssrc.equals(ssrcDefault) ? ssrcInfo.getSsrc() : ssrc);
+//                            sendRtpItem.setSsrc(ssrcInfo.getSsrc());
 
                             // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                             redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                            MediaServerItem finalMediaServerItem = mediaServerItem;
                             playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
                                 logger.info("[涓婄骇鐐规挱]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
                                 redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
                             });
                         } else {
-                            // 褰撳墠绯荤粺浣滀负涓嬬骇骞冲彴浣跨敤锛屽綋涓婄骇骞冲彴鐐规挱鏃朵笉鎼哄甫ssrc鏃讹紝骞朵笖璁惧鍦ㄥ綋鍓嶇郴缁熶腑宸茬粡鐐规挱浜嗐�傝繖涓椂鍊欓渶瑕侀噸鏂扮粰鐢熸垚涓�涓猻src锛屼笉浣跨敤榛樿鐨�"0000000000"銆�
-                            if (ssrc.equals(ssrcDefault)) {
-                                ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
-                                ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
-                                sendRtpItem.setSsrc(ssrc);
-                            }
 
                             sendRtpItem.setStreamId(playTransaction.getStream());
                             // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
@@ -499,11 +499,15 @@
                         }
                     }
                 } else if (gbStream != null) {
-                    if(ssrc.equals(ssrcDefault))
-                    {
-                        ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
-                        ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
+
+                    String ssrc;
+                    if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) {
+                        // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+                        ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+                    }else {
+                        ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
                     }
+
                     if("push".equals(gbStream.getStreamType())) {
                         if (streamPushItem != null && streamPushItem.isPushIng()) {
                             // 鎺ㄦ祦鐘舵��
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 405fdd0..4e9b57d 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -8,6 +8,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
@@ -104,6 +105,9 @@
 
     @Autowired
     private AssistRESTfulUtils assistRESTfulUtils;
+
+    @Autowired
+    private SSRCFactory ssrcFactory;
 
     @Qualifier("taskExecutor")
     @Autowired
@@ -666,6 +670,7 @@
             if (sendRtpItems.size() > 0) {
                 for (SendRtpItem sendRtpItem : sendRtpItems) {
                     ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
+                    ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
                     try {
                         commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
                     } catch (SipException | InvalidArgumentException | ParseException e) {
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
index 9233ca9..63999b7 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -4,6 +4,7 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
@@ -52,6 +53,9 @@
 
     @Autowired
     private IRedisCatchStorage redisCatchStorage;
+
+    @Autowired
+    private SSRCFactory ssrcFactory;
 
     @Autowired
     private IMediaServerService mediaServerService;
@@ -328,6 +332,7 @@
         List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(platformId);
         if (sendRtpItems != null && sendRtpItems.size() > 0) {
             for (SendRtpItem sendRtpItem : sendRtpItems) {
+                ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());
                 redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null);
                 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
                 Map<String, Object> param = new HashMap<>(3);
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
index d4abcb4..aed9811 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -915,7 +915,12 @@
     @Override
     public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) {
         String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS;
-        logger.info("[redis閫氱煡] 鎺ㄩ�佽澶�/閫氶亾鐘舵�侊紝 {}/{}-{}", deviceId, channelId, online);
+        if (channelId == null) {
+            logger.info("[redis閫氱煡] 鎺ㄩ�佽澶囩姸鎬侊紝 {}-{}", deviceId, online);
+        }else {
+            logger.info("[redis閫氱煡] 鎺ㄩ�侀�氶亾鐘舵�侊紝 {}/{}-{}", deviceId, channelId, online);
+        }
+
         StringBuilder msg = new StringBuilder();
         msg.append(deviceId);
         if (channelId != null) {
diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml
index cc2145a..54d348d 100644
--- a/src/main/resources/all-application.yml
+++ b/src/main/resources/all-application.yml
@@ -194,6 +194,8 @@
     max-notify-count-queue: 10000
     # 璁惧/閫氶亾鐘舵�佸彉鍖栨椂鍙戦�佹秷鎭�
     device-status-notify: false
+    # 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+    use-custom-ssrc-for-parent-invite: true
     # 璺ㄥ煙閰嶇疆锛岄厤缃綘璁块棶鍓嶇椤甸潰鐨勫湴鍧�鍗冲彲锛� 鍙互閰嶇疆澶氫釜
     allowed-origins:
         - http://localhost:8008

--
Gitblit v1.8.0