From 764d04b497356ba6bcbb75fd42b51eca750f7223 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 29 五月 2024 15:02:51 +0800
Subject: [PATCH] 调整上级观看消息的发送

---
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java |  863 ++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 510 insertions(+), 353 deletions(-)

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 f9a0b7e..de1a929 100755
--- 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
@@ -2,40 +2,56 @@
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
+import com.genersoft.iot.vmp.common.InviteSessionType;
 import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.common.VideoManagerConstants;
 import com.genersoft.iot.vmp.conf.DynamicTask;
+import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
 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.SIPSender;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
-import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
-import com.genersoft.iot.vmp.media.zlm.dto.*;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
-import com.genersoft.iot.vmp.service.*;
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.bean.MediaServer;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
+import com.genersoft.iot.vmp.media.service.IMediaServerService;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.service.IPlayService;
+import com.genersoft.iot.vmp.service.IStreamProxyService;
+import com.genersoft.iot.vmp.service.IStreamPushService;
+import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
+import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
 import com.genersoft.iot.vmp.service.bean.ErrorCallback;
 import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
-import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
 import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import gov.nist.javax.sdp.TimeDescriptionImpl;
 import gov.nist.javax.sdp.fields.TimeField;
+import gov.nist.javax.sdp.fields.URIField;
 import gov.nist.javax.sip.message.SIPRequest;
 import gov.nist.javax.sip.message.SIPResponse;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import javax.sdp.*;
@@ -46,10 +62,10 @@
 import javax.sip.message.Response;
 import java.text.ParseException;
 import java.time.Instant;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
 import java.util.Vector;
+import java.util.*;
 
 /**
  * SIP鍛戒护绫诲瀷锛� INVITE璇锋眰
@@ -63,13 +79,14 @@
     private final String method = "INVITE";
 
     @Autowired
-    private SIPCommanderFroPlatform cmderFroPlatform;
+    private ISIPCommanderForPlatform cmderFroPlatform;
 
     @Autowired
     private IVideoManagerStorage storager;
 
     @Autowired
     private IStreamPushService streamPushService;
+
     @Autowired
     private IStreamProxyService streamProxyService;
 
@@ -77,7 +94,10 @@
     private IRedisCatchStorage redisCatchStorage;
 
     @Autowired
-    private IInviteStreamService inviteStreamService;
+    private IRedisRpcService redisRpcService;
+
+    @Autowired
+    private RedisTemplate<Object, Object> redisTemplate;
 
     @Autowired
     private SSRCFactory ssrcFactory;
@@ -86,22 +106,19 @@
     private DynamicTask dynamicTask;
 
     @Autowired
-    private RedisPushStreamResponseListener redisPushStreamResponseListener;
-
-    @Autowired
     private IPlayService playService;
 
     @Autowired
     private SIPSender sipSender;
 
     @Autowired
-    private ZLMServerFactory zlmServerFactory;
+    private AudioBroadcastManager audioBroadcastManager;
 
     @Autowired
     private IMediaServerService mediaServerService;
 
     @Autowired
-    private ZlmHttpHookSubscribe zlmHttpHookSubscribe;
+    private HookSubscribe hookSubscribe;
 
     @Autowired
     private SIPProcessorObserver sipProcessorObserver;
@@ -110,11 +127,16 @@
     private UserSetting userSetting;
 
     @Autowired
-    private ZLMMediaListManager mediaListManager;
-
+    private SipConfig config;
 
     @Autowired
-    private RedisGbPlayMsgListener redisGbPlayMsgListener;
+    private VideoStreamSessionManager streamSession;
+
+    @Autowired
+    private SendRtpPortManager sendRtpPortManager;
+
+    @Autowired
+    private RedisPushStreamResponseListener redisPushStreamResponseListener;
 
 
     @Override
@@ -133,7 +155,20 @@
         //  Invite Request娑堟伅瀹炵幇锛屾娑堟伅涓�鑸负绾ц仈娑堟伅锛屼笂绾х粰涓嬬骇鍙戦�佽姹傝棰戞寚浠�
         try {
             SIPRequest request = (SIPRequest)evt.getRequest();
-            String channelId = SipUtils.getChannelIdFromRequest(request);
+            String channelIdFromSub = SipUtils.getChannelIdFromRequest(request);
+
+            // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
+            String contentString = new String(request.getRawContent());
+            Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
+            SessionDescription sdp = gb28181Sdp.getBaseSdb();
+            String sessionName = sdp.getSessionName().getValue();
+            String channelIdFromSdp = null;
+            if(StringUtils.equalsIgnoreCase("Playback", sessionName)){
+                URIField uriField = (URIField)sdp.getURI();
+                channelIdFromSdp = uriField.getURI().split(":")[0];
+            }
+            final String channelId = StringUtils.isNotBlank(channelIdFromSdp) ? channelIdFromSdp : channelIdFromSub;
+
             String requesterId = SipUtils.getUserIdFromFromHeader(request);
             CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
             if (requesterId == null || channelId == null) {
@@ -147,11 +182,13 @@
                 return;
             }
 
+            logger.info("[INVITE] requesterId: {}, callId: {}, 鏉ヨ嚜锛歿}锛歿}",
+                    requesterId, callIdHeader.getCallId(), request.getRemoteAddress(), request.getRemotePort());
 
             // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
             ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
             if (platform == null) {
-                inviteFromDeviceHandle(request, requesterId);
+                inviteFromDeviceHandle(request, requesterId, channelId);
 
             } else {
                 // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
@@ -159,9 +196,9 @@
                 GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
                 PlatformCatalog catalog = storager.getCatalog(requesterId, channelId);
 
-                MediaServerItem mediaServerItem = null;
+                MediaServer mediaServerItem = null;
                 StreamPushItem streamPushItem = null;
-                StreamProxyItem proxyByAppAndStream =null;
+                StreamProxyItem proxyByAppAndStream = null;
                 // 涓嶆槸閫氶亾鍙兘鏄洿鎾祦
                 if (channel != null && gbStream == null) {
                     // 閫氶亾瀛樺湪锛屽彂100锛孴RYING
@@ -204,7 +241,7 @@
                                 }
                                 return;
                             }
-                        }else if("proxy".equals(gbStream.getStreamType())){
+                        } else if ("proxy".equals(gbStream.getStreamType())) {
                             proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream());
                             if (proxyByAppAndStream == null) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
@@ -240,12 +277,6 @@
                     }
                     return;
                 }
-                // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
-                String contentString = new String(request.getRawContent());
-
-                Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
-                SessionDescription sdp = gb28181Sdp.getBaseSdb();
-                String sessionName = sdp.getSessionName().getValue();
 
                 Long startTime = null;
                 Long stopTime = null;
@@ -304,8 +335,12 @@
                     return;
                 }
                 String username = sdp.getOrigin().getUsername();
-                String addressStr = sdp.getConnection().getAddress();
-
+                String addressStr;
+                if(StringUtils.isEmpty(platform.getSendStreamIp())){
+                    addressStr = sdp.getConnection().getAddress();
+                }else {
+                    addressStr = platform.getSendStreamIp();
+                }
 
                 Device device = null;
                 // 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍�
@@ -342,14 +377,15 @@
                     if (mediaTransmissionTCP) {
                         if (tcpActive) {
                             streamTypeStr = "TCP-ACTIVE";
-                        }else {
+                        } else {
                             streamTypeStr = "TCP-PASSIVE";
                         }
-                    }else {
+                    } else {
                         streamTypeStr = "UDP";
                     }
-                    logger.info("[涓婄骇Invite] {}, 骞冲彴锛歿}锛� 閫氶亾锛歿}, 鏀舵祦鍦板潃锛歿}:{}锛屾敹娴佹柟寮忥細{}, ssrc锛歿}", sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc);
-                    SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+                    logger.info("[涓婄骇Invite] {}, 骞冲彴锛歿}锛� 閫氶亾锛歿}, 鏀舵祦鍦板潃锛歿}:{}锛屾敹娴佹柟寮忥細{}, ssrc锛歿}",
+                            sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc);
+                    SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                             device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
 
                     if (tcpActive != null) {
@@ -371,19 +407,22 @@
                     Long finalStopTime = stopTime;
                     ErrorCallback<Object> hookEvent = (code, msg, data) -> {
                         StreamInfo streamInfo = (StreamInfo)data;
-                        MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId());
+                        MediaServer mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId());
                         logger.info("[涓婄骇Invite]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", streamInfo.getApp(), streamInfo.getStream());
                         //     * 0 绛夊緟璁惧鎺ㄦ祦涓婃潵
                         //     * 1 涓嬬骇宸茬粡鎺ㄦ祦锛岀瓑寰呬笂绾у钩鍙板洖澶峚ck
                         //     * 2 鎺ㄦ祦涓�
                         sendRtpItem.setStatus(1);
                         redisCatchStorage.updateSendRTPSever(sendRtpItem);
-
+                        String sdpIp = mediaServerItemInUSe.getSdpIp();
+                        if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) {
+                            sdpIp = platform.getSendStreamIp();
+                        }
                         StringBuffer content = new StringBuffer(200);
                         content.append("v=0\r\n");
-                        content.append("o=" + channelId + " 0 0 IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n");
+                        content.append("o=" + channelId + " 0 0 IN IP4 " + sdpIp + "\r\n");
                         content.append("s=" + sessionName + "\r\n");
-                        content.append("c=IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n");
+                        content.append("c=IN IP4 " + sdpIp + "\r\n");
                         if ("Playback".equalsIgnoreCase(sessionName)) {
                             content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n");
                         } else {
@@ -394,7 +433,16 @@
                             // 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
                             localPort = new Random().nextInt(65535) + 1;
                         }
-                        content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+                        if (sendRtpItem.isTcp()) {
+                            content.append("m=video " + localPort + " TCP/RTP/AVP 96\r\n");
+                            if (!sendRtpItem.isTcpActive()) {
+                                content.append("a=setup:active\r\n");
+                            } else {
+                                content.append("a=setup:passive\r\n");
+                            }
+                        }else {
+                            content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+                        }
                         content.append("a=sendonly\r\n");
                         content.append("a=rtpmap:96 PS/90000\r\n");
                         content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
@@ -416,43 +464,23 @@
                             responseSdpAck(request, content.toString(), platform);
                             // tcp涓诲姩妯″紡锛屽洖澶峴dp鍚庡紑鍚洃鍚�
                             if (sendRtpItem.isTcpActive()) {
-                                MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
-                                Map<String, Object> param = new HashMap<>(12);
-                                param.put("vhost","__defaultVhost__");
-                                param.put("app",sendRtpItem.getApp());
-                                param.put("stream",sendRtpItem.getStreamId());
-                                param.put("ssrc", sendRtpItem.getSsrc());
-                                if (!sendRtpItem.isTcpActive()) {
-                                    param.put("dst_url",sendRtpItem.getIp());
-                                    param.put("dst_port", sendRtpItem.getPort());
-                                }
-                                String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
-                                param.put("is_udp", is_Udp);
-                                param.put("src_port", localPort);
-                                param.put("pt", sendRtpItem.getPt());
-                                param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
-                                param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
-                                if (!sendRtpItem.isTcp()) {
-                                    // 寮�鍚痳tcp淇濇椿
-                                    param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");
-                                }
-                                JSONObject startSendRtpStreamResult = zlmServerFactory.startSendRtpStreamForPassive(mediaInfo, param);
-                                if (startSendRtpStreamResult != null) {
-                                    startSendRtpStreamHand(evt, sendRtpItem, null, startSendRtpStreamResult, param, callIdHeader);
-                                }
+                                MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+                                try {
+                                    mediaServerService.startSendRtpPassive(mediaServer, sendRtpItem, 5);
+                                    redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, platform);
+                                }catch (ControllerException e) {}
                             }
                         } catch (SipException | InvalidArgumentException | ParseException e) {
                             logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍥炲SdpAck", e);
                         }
                     };
                     ErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
+                        logger.info("[涓婄骇Invite] {}, 澶辫触, 骞冲彴锛歿}锛� 閫氶亾锛歿}, code锛� {}锛� msg锛泏}", sessionName, username, channelId, statusCode, msg);
                         // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒
                         try {
-                            if (statusCode > 0) {
-                                Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
-                                sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
-                            }
-                        } catch (ParseException | SipException  e) {
+                            Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
+                            sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
+                        } catch (ParseException | SipException e) {
                             logger.error("鏈鐞嗙殑寮傚父 ", e);
                         }
                     });
@@ -462,20 +490,20 @@
                         String startTimeStr = DateUtil.urlFormatter.format(start);
                         String endTimeStr = DateUtil.urlFormatter.format(end);
                         String stream = device.getDeviceId() + "_" + channelId + "_" + startTimeStr + "_" + endTimeStr;
-                        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
-                        sendRtpItem.setStreamId(ssrcInfo.getStream());
+                        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0,false,!channel.getHasAudio(), false, device.getStreamModeForParam());
+                        sendRtpItem.setStream(stream);
                         // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                         redisCatchStorage.updateSendRTPSever(sendRtpItem);
                         playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
                                 DateUtil.formatter.format(end),
                                 (code, msg, data) -> {
-                                    if (code == InviteErrorCode.SUCCESS.getCode()){
+                                    if (code == InviteErrorCode.SUCCESS.getCode()) {
                                         hookEvent.run(code, msg, data);
-                                    }else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
+                                    } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
                                         logger.info("[褰曞儚鍥炴斁]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
                                         redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
                                         errorEvent.run(code, msg, data);
-                                    }else {
+                                    } else {
                                         errorEvent.run(code, msg, data);
                                     }
                                 });
@@ -492,8 +520,8 @@
                         }
 
                         sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD);
-                        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
-                        sendRtpItem.setStreamId(ssrcInfo.getStream());
+                        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.getHasAudio(), false, device.getStreamModeForParam());
+                        sendRtpItem.setStream(ssrcInfo.getStream());
                         // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                         redisCatchStorage.updateSendRTPSever(sendRtpItem);
                         playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
@@ -510,7 +538,10 @@
                                     }
                                 });
                     } else {
-
+                        sendRtpItem.setPlayType(InviteStreamType.PLAY);
+                        String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
+                        sendRtpItem.setStream(streamId);
+                        redisCatchStorage.updateSendRTPSever(sendRtpItem);
                         SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> {
                             if (code == InviteErrorCode.SUCCESS.getCode()) {
                                 hookEvent.run(code, msg, data);
@@ -522,46 +553,83 @@
                                 errorEvent.run(code, msg, data);
                             }
                         }));
-                        sendRtpItem.setPlayType(InviteStreamType.PLAY);
-                        String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
-                        sendRtpItem.setStreamId(streamId);
                         sendRtpItem.setSsrc(ssrcInfo.getSsrc());
                         redisCatchStorage.updateSendRTPSever(sendRtpItem);
 
                     }
                 } else if (gbStream != null) {
-
-                    String ssrc;
-                    if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
-                        // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
-                        ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
-                    }else {
-                        ssrc = gb28181Sdp.getSsrc();
+                    SendRtpItem sendRtpItem = new SendRtpItem();
+                    if (!userSetting.getUseCustomSsrcForParentInvite() && gb28181Sdp.getSsrc() != null) {
+                        sendRtpItem.setSsrc(gb28181Sdp.getSsrc());
                     }
 
-                    if("push".equals(gbStream.getStreamType())) {
-                        if (streamPushItem != null && streamPushItem.isPushIng()) {
-                            // 鎺ㄦ祦鐘舵��
-                            pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-                        } else {
-                            // 鏈帹娴� 鎷夎捣
-                            notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                    if (tcpActive != null) {
+                        sendRtpItem.setTcpActive(tcpActive);
+                    }
+                    sendRtpItem.setTcp(mediaTransmissionTCP);
+                    sendRtpItem.setRtcp(platform.isRtcp());
+                    sendRtpItem.setPlatformName(platform.getName());
+                    sendRtpItem.setPlatformId(platform.getServerGBId());
+                    sendRtpItem.setMediaServerId(mediaServerItem.getId());
+                    sendRtpItem.setChannelId(channelId);
+                    sendRtpItem.setIp(addressStr);
+                    sendRtpItem.setPort(port);
+                    sendRtpItem.setUsePs(true);
+                    sendRtpItem.setApp(gbStream.getApp());
+                    sendRtpItem.setStream(gbStream.getStream());
+                    sendRtpItem.setCallId(callIdHeader.getCallId());
+                    sendRtpItem.setFromTag(request.getFromTag());
+                    sendRtpItem.setOnlyAudio(false);
+                    sendRtpItem.setStatus(0);
+                    sendRtpItem.setSessionName(sessionName);
+                    // 娓呯悊鍙兘瀛樺湪鐨勭紦瀛橀伩鍏嶇敤鍒版棫鐨勬暟鎹�
+                    List<SendRtpItem> sendRtpItemList = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, gbStream.getStream());
+                    if (!sendRtpItemList.isEmpty()) {
+                        for (SendRtpItem rtpItem : sendRtpItemList) {
+                            redisCatchStorage.deleteSendRTPServer(rtpItem);
                         }
-                    }else if ("proxy".equals(gbStream.getStreamType())){
-                        if (null != proxyByAppAndStream) {
-                            if(proxyByAppAndStream.isStatus()){
-                                pushProxyStream(evt, request, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-                            }else{
-                                //寮�鍚唬鐞嗘媺娴�
-                                notifyStreamOnline(evt, request,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                    }
+                    if ("push".equals(gbStream.getStreamType())) {
+                        sendRtpItem.setPlayType(InviteStreamType.PUSH);
+                        if (streamPushItem != null) {
+                            // 浠巖edis鏌ヨ鏄惁姝e湪鎺ユ敹杩欎釜鎺ㄦ祦
+                            StreamPushItem pushListItem = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream());
+                            if (pushListItem != null) {
+                                sendRtpItem.setServerId(pushListItem.getServerId());
+                                sendRtpItem.setMediaServerId(pushListItem.getMediaServerId());
+
+                                pushListItem.setSelf(userSetting.getServerId().equals(pushListItem.getServerId()));
+                                redisCatchStorage.updateSendRTPSever(sendRtpItem);
+                                // 寮�濮嬫帹娴�
+                                sendPushStream(sendRtpItem, mediaServerItem, platform, request);
+                            }else {
+                                if (!platform.isStartOfflinePush()) {
+                                    // 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
+                                    try {
+                                        logger.info("[涓婄骇鐐规挱] 澶辫触锛屾帹娴佽澶囨湭鎺ㄦ祦锛宑hannel: {}, app: {}, stream: {}", sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream());
+                                        responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
+                                    } catch (SipException | InvalidArgumentException | ParseException e) {
+                                        logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
+                                    }
+                                    return;
+                                }
+                                notifyPushStreamOnline(sendRtpItem, mediaServerItem, platform, request);
                             }
                         }
-
-
+                    } else if ("proxy".equals(gbStream.getStreamType())) {
+                        if (null != proxyByAppAndStream) {
+                            if (sendRtpItem.getSsrc() == null) {
+                                // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+                                String ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+                                sendRtpItem.setSsrc(ssrc);
+                            }
+                            if (proxyByAppAndStream.isStatus()) {
+                                sendProxyStream(sendRtpItem, mediaServerItem, platform, request);
+                            } else {
+                                //寮�鍚唬鐞嗘媺娴�
+                                notifyProxyStreamOnline(sendRtpItem, mediaServerItem, platform, request);
+                            }
+                        }
                     }
                 }
             }
@@ -587,17 +655,14 @@
     /**
      * 瀹夋帓鎺ㄦ祦
      */
-    private void pushProxyStream(RequestEvent evt, SIPRequest request, GbStream gbStream, ParentPlatform platform,
-                            CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
-                            int port, Boolean tcpActive, boolean mediaTransmissionTCP,
-                            String channelId, String addressStr, String ssrc, String requesterId) {
-            Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
-            if (streamReady != null && streamReady) {
-                // 鑷钩鍙板唴瀹�
-                SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
-                        gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
+    private void sendProxyStream(SendRtpItem sendRtpItem, MediaServer mediaServerItem, ParentPlatform platform, SIPRequest request) {
+        MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
+        
+        if (mediaInfo != null) {
 
-                if (sendRtpItem == null) {
+                // 鑷钩鍙板唴瀹�
+                int localPort = sendRtpPortManager.getNextPort(mediaServerItem);
+                if (localPort == 0) {
                     logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                     try {
                         responseAck(request, Response.BUSY_HERE);
@@ -606,37 +671,27 @@
                     }
                     return;
                 }
-                if (tcpActive != null) {
-                    sendRtpItem.setTcpActive(tcpActive);
-                }
-                sendRtpItem.setPlayType(InviteStreamType.PUSH);
-                // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
-                sendRtpItem.setStatus(1);
-                sendRtpItem.setCallId(callIdHeader.getCallId());
-                sendRtpItem.setFromTag(request.getFromTag());
+            sendRtpItem.setPlayType(InviteStreamType.PROXY);
+            // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+            sendRtpItem.setStatus(1);
+            sendRtpItem.setLocalIp(mediaServerItem.getSdpIp());
 
-                SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
-                if (response != null) {
-                    sendRtpItem.setToTag(response.getToTag());
-                }
-                redisCatchStorage.updateSendRTPSever(sendRtpItem);
-
+            SIPResponse response = sendStreamAck(request, sendRtpItem, platform);
+            if (response != null) {
+                sendRtpItem.setToTag(response.getToTag());
+            }
+            redisCatchStorage.updateSendRTPSever(sendRtpItem);
         }
-
     }
-    private void pushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
-                            CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
-                            int port, Boolean tcpActive, boolean mediaTransmissionTCP,
-                            String channelId, String addressStr, String ssrc, String requesterId) {
-        // 鎺ㄦ祦
-        if (streamPushItem.isSelf()) {
-            Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
-            if (streamReady != null && streamReady) {
-                // 鑷钩鍙板唴瀹�
-                SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
-                        gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
 
-                if (sendRtpItem == null) {
+    private void sendPushStream(SendRtpItem sendRtpItem, MediaServer mediaServerItem, ParentPlatform platform, SIPRequest request) {
+        // 鎺ㄦ祦
+        if (sendRtpItem.getServerId().equals(userSetting.getServerId())) {
+            MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
+            if (mediaInfo != null ) {
+                // 鑷钩鍙板唴瀹�
+                int localPort = sendRtpPortManager.getNextPort(mediaServerItem);
+                if (localPort == 0) {
                     logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                     try {
                         responseAck(request, Response.BUSY_HERE);
@@ -645,237 +700,179 @@
                     }
                     return;
                 }
-                if (tcpActive != null) {
-                    sendRtpItem.setTcpActive(tcpActive);
-                }
-                sendRtpItem.setPlayType(InviteStreamType.PUSH);
                 // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                 sendRtpItem.setStatus(1);
-                sendRtpItem.setCallId(callIdHeader.getCallId());
-
-                sendRtpItem.setFromTag(request.getFromTag());
-                SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
+                SIPResponse response = sendStreamAck(request, sendRtpItem, platform);
                 if (response != null) {
                     sendRtpItem.setToTag(response.getToTag());
                 }
-
+                if (sendRtpItem.getSsrc() == null) {
+                    // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+                    String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+                    sendRtpItem.setSsrc(ssrc);
+                }
                 redisCatchStorage.updateSendRTPSever(sendRtpItem);
-
             } else {
                 // 涓嶅湪绾� 鎷夎捣
-                notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                notifyPushStreamOnline(sendRtpItem, mediaServerItem, platform, request);
             }
-
         } else {
             // 鍏朵粬骞冲彴鍐呭
-            otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+            otherWvpPushStream(sendRtpItem, request, platform);
         }
     }
+
     /**
      * 閫氱煡娴佷笂绾�
      */
-    private void notifyStreamOnline(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
-                                    CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
-                                    int port, Boolean tcpActive, boolean mediaTransmissionTCP,
-                                    String channelId, String addressStr, String ssrc, String requesterId) {
-        if ("proxy".equals(gbStream.getStreamType())) {
-            // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
-            logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
-            // 鐩戝惉娴佷笂绾�
-            HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId());
-            zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> {
-                OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
-                logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream());
-                dynamicTask.stop(callIdHeader.getCallId());
-                pushProxyStream(evt, request, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
-                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-            });
-            dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
-                logger.info("[ app={}, stream={} ] 绛夊緟鎷夋祦浠g悊娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
-                zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
-            }, userSetting.getPlatformPlayTimeout());
-            boolean start = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
-            if (!start) {
-                try {
-                    responseAck(request, Response.BUSY_HERE, "channel [" + gbStream.getGbId() + "] offline");
-                } catch (SipException | InvalidArgumentException | ParseException e) {
-                    logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
-                }
-                zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
-                dynamicTask.stop(callIdHeader.getCallId());
+    private void notifyProxyStreamOnline(SendRtpItem sendRtpItem, MediaServer mediaServerItem, ParentPlatform platform, SIPRequest request) {
+        // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
+        logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", sendRtpItem.getApp(), sendRtpItem.getStream());
+        // 鐩戝惉娴佷笂绾�
+        Hook hook = Hook.getInstance(HookType.on_media_arrival, sendRtpItem.getApp(), sendRtpItem.getStream(), mediaServerItem.getId());
+        hookSubscribe.addSubscribe(hook, (hookData)->{
+            logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream());
+            dynamicTask.stop(sendRtpItem.getCallId());
+            sendProxyStream(sendRtpItem, mediaServerItem, platform, request);
+        });
+        dynamicTask.startDelay(sendRtpItem.getCallId(), () -> {
+            logger.info("[ app={}, stream={} ] 绛夊緟鎷夋祦浠g悊娴佽秴鏃�", sendRtpItem.getApp(), sendRtpItem.getStream());
+            hookSubscribe.removeSubscribe(hook);
+        }, userSetting.getPlatformPlayTimeout());
+        boolean start = streamProxyService.start(sendRtpItem.getApp(), sendRtpItem.getStream());
+        if (!start) {
+            try {
+                responseAck(request, Response.BUSY_HERE, "channel [" + sendRtpItem.getChannelId() + "] offline");
+            } catch (SipException | InvalidArgumentException | ParseException e) {
+                logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
             }
+            hookSubscribe.removeSubscribe(hook);
+            dynamicTask.stop(sendRtpItem.getCallId());
+        }
+    }
 
-
-
-        } else if ("push".equals(gbStream.getStreamType())) {
-            if (!platform.isStartOfflinePush()) {
-                // 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
-                try {
-                    logger.info("[涓婄骇鐐规挱] 澶辫触锛屾帹娴佽澶囨湭鎺ㄦ祦锛宑hannel: {}, app: {}, stream: {}", gbStream.getGbId(), gbStream.getApp(), gbStream.getStream());
-                    responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
-                } catch (SipException | InvalidArgumentException | ParseException e) {
-                    logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
-                }
-                return;
+    /**
+     * 閫氱煡娴佷笂绾�
+     */
+    private void notifyPushStreamOnline(SendRtpItem sendRtpItem, MediaServer mediaServerItem, ParentPlatform platform, SIPRequest request) {
+        // 鍙戦�乺edis娑堟伅浠ヤ娇璁惧涓婄嚎锛屾祦涓婄嚎鍚庤
+        logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍙戦�乺edis淇℃伅鎺у埗璁惧寮�濮嬫帹娴�", sendRtpItem.getApp(), sendRtpItem.getStream());
+        MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1,
+                sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getChannelId(), sendRtpItem.getPlatformId(),
+                platform.getName(), userSetting.getServerId(), sendRtpItem.getMediaServerId());
+        redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
+        // 璁剧疆瓒呮椂
+        dynamicTask.startDelay(sendRtpItem.getCallId(), () -> {
+            redisRpcService.stopWaitePushStreamOnline(sendRtpItem);
+            logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", sendRtpItem.getApp(), sendRtpItem.getStream());
+            try {
+                responseAck(request, Response.REQUEST_TIMEOUT); // 瓒呮椂
+            } catch (SipException | InvalidArgumentException | ParseException e) {
+                logger.error("鏈鐞嗙殑寮傚父 ", e);
             }
-            // 鍙戦�乺edis娑堟伅浠ヤ娇璁惧涓婄嚎
-            logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍙戦�乺edis淇℃伅鎺у埗璁惧寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
-
-            MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1,
-                    gbStream.getApp(), gbStream.getStream(), gbStream.getGbId(), gbStream.getPlatformId(),
-                    platform.getName(), null, gbStream.getMediaServerId());
-            redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel);
-            // 璁剧疆瓒呮椂
-            dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
-                logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
+        }, userSetting.getPlatformPlayTimeout());
+        //
+        long key = redisRpcService.waitePushStreamOnline(sendRtpItem, (sendRtpItemKey) -> {
+            dynamicTask.stop(sendRtpItem.getCallId());
+            if (sendRtpItemKey == null) {
+                logger.warn("[绾ц仈鐐规挱] 绛夊緟鎺ㄦ祦寰楀埌缁撴灉鏈┖锛� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream());
                 try {
-                    mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
-                    responseAck(request, Response.REQUEST_TIMEOUT); // 瓒呮椂
+                    responseAck(request, Response.BUSY_HERE);
                 } catch (SipException | InvalidArgumentException | ParseException e) {
                     logger.error("鏈鐞嗙殑寮傚父 ", e);
                 }
-            }, userSetting.getPlatformPlayTimeout());
-            // 娣诲姞鐩戝惉
-            int finalPort = port;
-            Boolean finalTcpActive = tcpActive;
-
-            // 娣诲姞鍦ㄦ湰鏈轰笂绾跨殑閫氱煡
-            mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
-                dynamicTask.stop(callIdHeader.getCallId());
-                if (serverId.equals(userSetting.getServerId())) {
-                    SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
-                            app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
-
-                    if (sendRtpItem == null) {
-                        logger.warn("涓婄骇鐐规椂鍒涘缓sendRTPItem澶辫触锛屽彲鑳芥槸鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                        try {
-                            responseAck(request, Response.BUSY_HERE);
-                        } catch (SipException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        } catch (InvalidArgumentException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        } catch (ParseException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        }
-                        return;
-                    }
-                    if (finalTcpActive != null) {
-                        sendRtpItem.setTcpActive(finalTcpActive);
-                    }
-                    sendRtpItem.setPlayType(InviteStreamType.PUSH);
-                    // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
-                    sendRtpItem.setStatus(1);
-                    sendRtpItem.setCallId(callIdHeader.getCallId());
-
-                    sendRtpItem.setFromTag(request.getFromTag());
-                    SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
-                    if (response != null) {
-                        sendRtpItem.setToTag(response.getToTag());
-                    }
-                    redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                } else {
-                    // 鍏朵粬骞冲彴鍐呭
-                    otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                            mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                return;
+            }
+            SendRtpItem sendRtpItemFromRedis = (SendRtpItem)redisTemplate.opsForValue().get(sendRtpItemKey);
+            if (sendRtpItemFromRedis == null) {
+                logger.warn("[绾ц仈鐐规挱] 绛夊緟鎺ㄦ祦, 鏈壘鍒皉edis涓紦瀛樼殑鍙戞祦淇℃伅锛� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream());
+                try {
+                    responseAck(request, Response.BUSY_HERE);
+                } catch (SipException | InvalidArgumentException | ParseException e) {
+                    logger.error("鏈鐞嗙殑寮傚父 ", e);
                 }
-            });
-
-            // 娣诲姞鍥炲鐨勬嫆缁濇垨鑰呴敊璇殑閫氱煡
-            redisPushStreamResponseListener.addEvent(gbStream.getApp(), gbStream.getStream(), response -> {
-                if (response.getCode() != 0) {
-                    dynamicTask.stop(callIdHeader.getCallId());
-                    mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
+                return;
+            }
+            if (sendRtpItemFromRedis.getServerId().equals(userSetting.getServerId())) {
+                logger.info("[绾ц仈鐐规挱] 绛夊緟鐨勬帹娴佸湪鏈钩鍙颁笂绾� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream());
+                int localPort = sendRtpPortManager.getNextPort(mediaServerItem);
+                if (localPort == 0) {
+                    logger.warn("涓婄骇鐐规椂鍒涘缓sendRTPItem澶辫触锛屽彲鑳芥槸鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                     try {
-                        responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+                        responseAck(request, Response.BUSY_HERE);
                     } catch (SipException | InvalidArgumentException | ParseException e) {
-                        logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鐐规挱鍥炲: {}", e.getMessage());
+                        logger.error("鏈鐞嗙殑寮傚父 ", e);
                     }
+                    return;
                 }
-            });
-        }
+                sendRtpItem.setLocalPort(localPort);
+                if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) {
+                    sendRtpItem.setLocalIp(platform.getSendStreamIp());
+                }
+
+                // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+                sendRtpItem.setStatus(1);
+                SIPResponse response = sendStreamAck(request, sendRtpItem, platform);
+                if (response != null) {
+                    sendRtpItem.setToTag(response.getToTag());
+                }
+                redisCatchStorage.updateSendRTPSever(sendRtpItem);
+            } else {
+                // 鍏朵粬骞冲彴鍐呭
+                otherWvpPushStream(sendRtpItemFromRedis, request, platform);
+            }
+        });
+        // 娣诲姞鍥炲鐨勬嫆缁濇垨鑰呴敊璇殑閫氱煡
+        // redis娑堟伅渚嬪锛� PUBLISH VM_MSG_STREAM_PUSH_RESPONSE  '{"code":1,"msg":"澶辫触","app":"1","stream":"2"}'
+        redisPushStreamResponseListener.addEvent(sendRtpItem.getApp(), sendRtpItem.getStream(), response -> {
+            if (response.getCode() != 0) {
+                dynamicTask.stop(sendRtpItem.getCallId());
+                redisRpcService.stopWaitePushStreamOnline(sendRtpItem);
+                redisRpcService.removeCallback(key);
+                try {
+                    responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+                } catch (SipException | InvalidArgumentException | ParseException e) {
+                    logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鐐规挱鍥炲: {}", e.getMessage());
+                }
+            }
+        });
     }
+
+
 
     /**
      * 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴�
      */
-    private void otherWvpPushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
-                                    CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
-                                    int port, Boolean tcpActive, boolean mediaTransmissionTCP,
-                                    String channelId, String addressStr, String ssrc, String requesterId) {
-        logger.info("[绾ц仈鐐规挱]鐩存挱娴佹潵鑷叾浠栧钩鍙帮紝鍙戦�乺edis娑堟伅");
-        // 鍙戦�乺edis娑堟伅
-        redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(),
-                streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId,
-                channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> {
-                    SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem();
-                    if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
-                        logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                        try {
-                            responseAck(request, Response.BUSY_HERE);
-                        } catch (SipException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        } catch (InvalidArgumentException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        } catch (ParseException e) {
-                            logger.error("鏈鐞嗙殑寮傚父 ", e);
-                        }
-                        return;
-                    }
-                    // 鏀跺埌sendItem
-                    if (tcpActive != null) {
-                        sendRtpItem.setTcpActive(tcpActive);
-                    }
-                    sendRtpItem.setPlayType(InviteStreamType.PUSH);
-                    // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
-                    sendRtpItem.setStatus(1);
-                    sendRtpItem.setCallId(callIdHeader.getCallId());
-
-                    sendRtpItem.setFromTag(request.getFromTag());
-                    SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request,sendRtpItem, platform, evt);
-                    if (response != null) {
-                        sendRtpItem.setToTag(response.getToTag());
-                    }
-                    redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                }, (wvpResult) -> {
-
-                    // 閿欒
-                    if (wvpResult.getCode() == RedisGbPlayMsgListener.ERROR_CODE_OFFLINE) {
-                        // 绂荤嚎
-                        // 鏌ヨ鏄惁鍦ㄦ湰鏈轰笂绾夸簡
-                        StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream());
-                        if (currentStreamPushItem.isPushIng()) {
-                            // 鍦ㄧ嚎鐘舵��
-                            pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-
-                        } else {
-                            // 涓嶅湪绾� 鎷夎捣
-                            notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-                        }
-                    }
-                    try {
-                        responseAck(request, Response.BUSY_HERE);
-                    } catch (InvalidArgumentException | ParseException | SipException e) {
-                        logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鐐规挱鍥炲 BUSY_HERE: {}", e.getMessage());
-                    }
-                });
+    private void otherWvpPushStream(SendRtpItem sendRtpItem, SIPRequest request, ParentPlatform platform) {
+        logger.info("[绾ц仈鐐规挱] 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴� {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream());
+        sendRtpItem = redisRpcService.getSendRtpItem(sendRtpItem.getRedisKey());
+        if (sendRtpItem == null) {
+            return;
+        }
+        // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+        sendRtpItem.setStatus(1);
+        SIPResponse response = sendStreamAck(request, sendRtpItem, platform);
+        if (response != null) {
+            sendRtpItem.setToTag(response.getToTag());
+        }
+        redisCatchStorage.updateSendRTPSever(sendRtpItem);
     }
 
-    public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
+    public SIPResponse sendStreamAck(SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform) {
 
+        String sdpIp = sendRtpItem.getLocalIp();
+        if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) {
+            sdpIp = platform.getSendStreamIp();
+        }
         StringBuffer content = new StringBuffer(200);
         content.append("v=0\r\n");
-        content.append("o=" + sendRtpItem.getChannelId() + " 0 0 IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+        content.append("o=" + sendRtpItem.getChannelId() + " 0 0 IN IP4 " + sdpIp + "\r\n");
         content.append("s=Play\r\n");
-        content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+        content.append("c=IN IP4 " + sdpIp + "\r\n");
         content.append("t=0 0\r\n");
         // 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
         int localPort = sendRtpItem.getLocalPort();
-        if(localPort == 0)
-        {
+        if (localPort == 0) {
             localPort = new Random().nextInt(65535) + 1;
         }
         content.append("m=video " + localPort + " RTP/AVP 96\r\n");
@@ -894,39 +891,78 @@
 
         try {
             return responseSdpAck(request, content.toString(), platform);
-        } catch (SipException e) {
-            logger.error("鏈鐞嗙殑寮傚父 ", e);
-        } catch (InvalidArgumentException e) {
-            logger.error("鏈鐞嗙殑寮傚父 ", e);
-        } catch (ParseException e) {
+        } catch (SipException | InvalidArgumentException | ParseException e) {
             logger.error("鏈鐞嗙殑寮傚父 ", e);
         }
         return null;
     }
 
-    public void inviteFromDeviceHandle(SIPRequest request, String requesterId) {
+    public void inviteFromDeviceHandle(SIPRequest request, String requesterId, String channelId) {
+
+        String realChannelId = null;
 
         // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
         Device device = redisCatchStorage.getDevice(requesterId);
+        // 鍒ゆ柇requesterId鏄澶囪繕鏄�氶亾
+        if (device == null) {
+            device = storager.queryVideoDeviceByChannelId(requesterId);
+            realChannelId = requesterId;
+        }else {
+            realChannelId = channelId;
+        }
+        if (device == null) {
+            // 妫�鏌hannelID鏄惁鍙敤
+            device = redisCatchStorage.getDevice(channelId);
+            if (device == null) {
+                device = storager.queryVideoDeviceByChannelId(channelId);
+                realChannelId = channelId;
+            }
+        }
+
+        if (device == null) {
+            logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰锛屾棤娉曚粠璇锋眰淇℃伅涓‘瀹氭墍灞炶澶囷紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
+            try {
+                responseAck(request, Response.FORBIDDEN);
+            } catch (SipException | InvalidArgumentException | ParseException e) {
+                logger.error("[鍛戒护鍙戦�佸け璐 鏉ヨ嚜璁惧鐨処nvite璇锋眰锛屾棤娉曚粠璇锋眰淇℃伅涓‘瀹氭墍灞炶澶� FORBIDDEN: {}", e.getMessage());
+            }
+            return;
+        }
+
+        AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), realChannelId);
+        if (broadcastCatch == null) {
+            logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
+            try {
+                responseAck(request, Response.FORBIDDEN);
+            } catch (SipException | InvalidArgumentException | ParseException e) {
+                logger.error("[鍛戒护鍙戦�佸け璐 鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾� FORBIDDEN: {}", e.getMessage());
+            }
+            return;
+        }
         if (device != null) {
             logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
+            String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId();
+            if (!SipUtils.isFrontEnd(device.getDeviceId())) {
+                key += broadcastCatch.getChannelId();
+            }
+            dynamicTask.stop(key);
             try {
                 responseAck(request, Response.TRYING);
             } catch (SipException | InvalidArgumentException | ParseException e) {
                 logger.error("[鍛戒护鍙戦�佸け璐 invite BAD_REQUEST: {}", e.getMessage());
+                playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+                return;
             }
             String contentString = new String(request.getRawContent());
-            // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
-            String ssrc = "0000000404";
 
             try {
                 Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
                 SessionDescription sdp = gb28181Sdp.getBaseSdb();
                 //  鑾峰彇鏀寔鐨勬牸寮�
                 Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+
                 // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
                 int port = -1;
-                //boolean recvonly = false;
                 boolean mediaTransmissionTCP = false;
                 Boolean tcpActive = null;
                 for (int i = 0; i < mediaDescriptions.size(); i++) {
@@ -934,7 +970,7 @@
                     Media media = mediaDescription.getMedia();
 
                     Vector mediaFormats = media.getMediaFormats(false);
-                    if (mediaFormats.contains("8")) {
+//                    if (mediaFormats.contains("8")) {
                         port = media.getMediaPort();
                         String protocol = media.getProtocol();
                         // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
@@ -950,7 +986,7 @@
                             }
                         }
                         break;
-                    }
+//                    }
                 }
                 if (port == -1) {
                     logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
@@ -958,26 +994,147 @@
                     try {
                         responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
                     } catch (SipException | InvalidArgumentException | ParseException e) {
-                        logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415锛� {}", e.getMessage());
+                        logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑濯掍綋鏍煎紡: {}", e.getMessage());
+                        playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+                        return;
                     }
                     return;
                 }
-                String username = sdp.getOrigin().getUsername();
-                String addressStr = sdp.getConnection().getAddress();
-                logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+                String addressStr = sdp.getOrigin().getAddress();
+                logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}, {}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
+                        mediaTransmissionTCP ? (tcpActive ? "TCP涓诲姩" : "TCP琚姩") : "UDP");
+
+                MediaServer mediaServerItem = broadcastCatch.getMediaServerItem();
+                if (mediaServerItem == null) {
+                    logger.warn("鏈壘鍒拌闊冲枈璇濅娇鐢ㄧ殑zlm");
+                    try {
+                        responseAck(request, Response.BUSY_HERE);
+                    } catch (SipException | InvalidArgumentException | ParseException e) {
+                        logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈壘鍒板彲鐢ㄧ殑zlm: {}", e.getMessage());
+                        playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+                    }
+                    return;
+                }
+                logger.info("璁惧{}璇锋眰璇煶娴侊紝 鏀舵祦鍦板潃锛歿}:{}锛宻src锛歿}, {}, 瀵硅鏂瑰紡锛歿}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
+                        mediaTransmissionTCP ? (tcpActive ? "TCP涓诲姩" : "TCP琚姩") : "UDP", sdp.getSessionName().getValue());
+                CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
+
+                SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServerItem, addressStr, port, gb28181Sdp.getSsrc(), requesterId,
+                        device.getDeviceId(), broadcastCatch.getChannelId(),
+                        mediaTransmissionTCP, false);
+
+                if (sendRtpItem == null) {
+                    logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+                    try {
+                        responseAck(request, Response.BUSY_HERE);
+                    } catch (SipException | InvalidArgumentException | ParseException e) {
+                        logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
+                        playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+                        return;
+                    }
+                    return;
+                }
+
+
+                sendRtpItem.setPlayType(InviteStreamType.BROADCAST);
+                sendRtpItem.setCallId(callIdHeader.getCallId());
+                sendRtpItem.setPlatformId(requesterId);
+                sendRtpItem.setStatus(1);
+                sendRtpItem.setApp(broadcastCatch.getApp());
+                sendRtpItem.setStream(broadcastCatch.getStream());
+                sendRtpItem.setPt(8);
+                sendRtpItem.setUsePs(false);
+                sendRtpItem.setRtcp(false);
+                sendRtpItem.setOnlyAudio(true);
+                sendRtpItem.setTcp(mediaTransmissionTCP);
+                if (tcpActive != null) {
+                    sendRtpItem.setTcpActive(tcpActive);
+                }
+
+                redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+                Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream());
+                if (streamReady) {
+                    sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, gb28181Sdp.getSsrc());
+                } else {
+                    logger.warn("[璇煶閫氳瘽]锛� 鏈彂鐜板緟鎺ㄩ�佺殑娴�,app={},stream={}", broadcastCatch.getApp(), broadcastCatch.getStream());
+                    try {
+                        responseAck(request, Response.GONE);
+                    } catch (SipException | InvalidArgumentException | ParseException e) {
+                        logger.error("[鍛戒护鍙戦�佸け璐 璇煶閫氳瘽 鍥炲410澶辫触锛� {}", e.getMessage());
+                        return;
+                    }
+                    playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+                }
             } catch (SdpException e) {
                 logger.error("[SDP瑙f瀽寮傚父]", e);
+                playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
             }
-
-
-
         } else {
             logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
             try {
-                responseAck(request, Response.BAD_REQUEST);; // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+                responseAck(request, Response.BAD_REQUEST);
+                ; // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
             } catch (SipException | InvalidArgumentException | ParseException e) {
                 logger.error("[鍛戒护鍙戦�佸け璐 invite 鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹傦紝 {}", e.getMessage());
             }
         }
     }
+
+    SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServer mediaServerItem, boolean mediaTransmissionTCP, String ssrc) {
+        SIPResponse sipResponse = null;
+        try {
+            sendRtpItem.setStatus(2);
+            redisCatchStorage.updateSendRTPSever(sendRtpItem);
+            StringBuffer content = new StringBuffer(200);
+            content.append("v=0\r\n");
+            content.append("o=" + config.getId() + " " + sdp.getOrigin().getSessionId() + " " + sdp.getOrigin().getSessionVersion() + " IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+            content.append("s=Play\r\n");
+            content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+            content.append("t=0 0\r\n");
+
+            if (mediaTransmissionTCP) {
+                content.append("m=audio " + sendRtpItem.getLocalPort() + " TCP/RTP/AVP 8\r\n");
+            } else {
+                content.append("m=audio " + sendRtpItem.getLocalPort() + " RTP/AVP 8\r\n");
+            }
+
+            content.append("a=rtpmap:8 PCMA/8000/1\r\n");
+
+            content.append("a=sendonly\r\n");
+            if (sendRtpItem.isTcp()) {
+                content.append("a=connection:new\r\n");
+                if (!sendRtpItem.isTcpActive()) {
+                    content.append("a=setup:active\r\n");
+                } else {
+                    content.append("a=setup:passive\r\n");
+                }
+            }
+            content.append("y=" + ssrc + "\r\n");
+            content.append("f=v/////a/1/8/1\r\n");
+
+            ParentPlatform parentPlatform = new ParentPlatform();
+            parentPlatform.setServerIP(device.getIp());
+            parentPlatform.setServerPort(device.getPort());
+            parentPlatform.setServerGBId(device.getDeviceId());
+
+            sipResponse = responseSdpAck(request, content.toString(), parentPlatform);
+
+            AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), sendRtpItem.getChannelId());
+
+            audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.Ok);
+            audioBroadcastCatch.setSipTransactionInfoByRequset(sipResponse);
+            audioBroadcastManager.update(audioBroadcastCatch);
+            streamSession.put(device.getDeviceId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), sendRtpItem.getStream(), sendRtpItem.getSsrc(), sendRtpItem.getMediaServerId(), sipResponse, InviteSessionType.BROADCAST);
+            // 寮�鍚彂娴侊紝澶у崕鍦ㄦ敹鍒�200OK鍚庡氨浼氬紑濮嬪缓绔嬭繛鎺�
+            if (!device.isBroadcastPushAfterAck()) {
+                logger.info("[璇煶鍠婅瘽] 鍥炲200OK鍚庡彂鐜� BroadcastPushAfterAck涓篎alse锛岀幇鍦ㄥ紑濮嬫帹娴�");
+                playService.startPushStream(sendRtpItem, sipResponse, parentPlatform, request.getCallIdHeader());
+            }
+
+        } catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
+            logger.error("[鍛戒护鍙戦�佸け璐 璇煶鍠婅瘽 鍥炲200OK锛圫DP锛�: {}", e.getMessage());
+        }
+        return sipResponse;
+    }
 }

--
Gitblit v1.8.0