From d7a1b94f905c5f28c9c8f2d48c3f9e28ebcf9cc4 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期六, 24 九月 2022 21:04:58 +0800
Subject: [PATCH] Merge branch 'wvp-28181-2.0'

---
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java |  498 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 391 insertions(+), 107 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 19908e4..a843159 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
@@ -1,35 +1,50 @@
 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 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.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 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.ZLMHttpHookSubscribe;
+import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
+import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
+import com.genersoft.iot.vmp.media.zlm.dto.*;
 import com.genersoft.iot.vmp.service.IMediaServerService;
+import com.genersoft.iot.vmp.service.IMediaService;
 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.service.bean.MessageForPushChannel;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.service.impl.RedisGbPlayMsgListener;
+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 com.genersoft.iot.vmp.utils.SerializeUtils;
+import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
+import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import gov.nist.javax.sdp.TimeDescriptionImpl;
 import gov.nist.javax.sdp.fields.TimeField;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.stack.SIPDialog;
+import gov.nist.javax.sip.message.SIPRequest;
+import gov.nist.javax.sip.message.SIPResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.InitializingBean;
@@ -38,7 +53,6 @@
 
 import javax.sdp.*;
 import javax.sip.*;
-import javax.sip.address.SipURI;
 import javax.sip.header.CallIdHeader;
 import javax.sip.message.Request;
 import javax.sip.message.Response;
@@ -67,13 +81,16 @@
     private IStreamPushService streamPushService;
 
     @Autowired
+    private IStreamProxyService streamProxyService;
+
+    @Autowired
     private IRedisCatchStorage redisCatchStorage;
 
     @Autowired
     private DynamicTask dynamicTask;
 
     @Autowired
-    private SIPCommander cmder;
+    private RedisPushStreamResponseListener redisPushStreamResponseListener;
 
     @Autowired
     private IPlayService playService;
@@ -81,11 +98,23 @@
     @Autowired
     private ISIPCommander commander;
 
+	@Autowired
+	private AudioBroadcastManager audioBroadcastManager;
+
     @Autowired
     private ZLMRTPServerFactory zlmrtpServerFactory;
 
     @Autowired
     private IMediaServerService mediaServerService;
+
+    @Autowired
+    private IMediaService mediaService;
+
+	@Autowired
+	private ZLMRESTfulUtils zlmresTfulUtils;
+
+    @Autowired
+    private ZlmHttpHookSubscribe zlmHttpHookSubscribe;
 
     @Autowired
     private SIPProcessorObserver sipProcessorObserver;
@@ -98,6 +127,16 @@
 
     @Autowired
     private ZLMMediaListManager mediaListManager;
+
+	@Autowired
+	private DeferredResultHolder resultHolder;
+
+	@Autowired
+	private ZlmHttpHookSubscribe subscribe;
+
+	@Autowired
+	private SipConfig config;
+
 
 
     @Autowired
@@ -120,23 +159,22 @@
         //  Invite Request娑堟伅瀹炵幇锛屾娑堟伅涓�鑸负绾ц仈娑堟伅锛屼笂绾х粰涓嬬骇鍙戦�佽姹傝棰戞寚浠�
         try {
             Request request = evt.getRequest();
-            SipURI sipUri = (SipURI) request.getRequestURI();
-            //浠巗ubject璇诲彇channelId,涓嶅啀浠巖equest-line璇诲彇銆� 鏈変簺骞冲彴request-line鏄钩鍙板浗鏍囩紪鐮侊紝涓嶆槸璁惧鍥芥爣缂栫爜銆�
-            //String channelId = sipURI.getUser();
-            String channelId = SipUtils.getChannelIdFromHeader(request);
+            String channelId = SipUtils.getChannelIdFromRequest(request);
             String requesterId = SipUtils.getUserIdFromFromHeader(request);
             CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
+            ServerTransaction serverTransaction = getServerTransaction(evt);
             if (requesterId == null || channelId == null) {
                 logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400");
                 // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇�
-                responseAck(evt, Response.BAD_REQUEST);
+                responseAck(serverTransaction, Response.BAD_REQUEST);
                 return;
             }
+
 
             // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
             ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
             if (platform == null) {
-                inviteFromDeviceHandle(evt, requesterId);
+                inviteFromDeviceHandle(serverTransaction, requesterId);
             } else {
                 // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
                 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
@@ -145,14 +183,16 @@
 
                 MediaServerItem mediaServerItem = null;
                 StreamPushItem streamPushItem = null;
+                StreamProxyItem proxyByAppAndStream =null;
                 // 涓嶆槸閫氶亾鍙兘鏄洿鎾祦
                 if (channel != null && gbStream == null) {
-                    if (channel.getStatus() == 0) {
-                        logger.info("閫氶亾绂荤嚎锛岃繑鍥�400");
-                        responseAck(evt, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
-                        return;
-                    }
-                    responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
+//                    if (channel.getStatus() == 0) {
+//                        logger.info("閫氶亾绂荤嚎锛岃繑鍥�400");
+//                        responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + channel.getChannelId() + "] offline");
+//                        return;
+//                    }
+                    // 閫氶亾瀛樺湪锛屽彂100锛孴RYING
+                    responseAck(serverTransaction, Response.TRYING);
                 } else if (channel == null && gbStream != null) {
 
                     String mediaServerId = gbStream.getMediaServerId();
@@ -160,13 +200,13 @@
                     if (mediaServerItem == null) {
                         if ("proxy".equals(gbStream.getStreamType())) {
                             logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                            responseAck(evt, Response.GONE);
+                            responseAck(serverTransaction, Response.GONE);
                             return;
                         } else {
                             streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
                             if (streamPushItem == null || streamPushItem.getServerId().equals(userSetting.getServerId())) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                                responseAck(evt, Response.GONE);
+                                responseAck(serverTransaction, Response.GONE);
                                 return;
                             }
                         }
@@ -175,18 +215,25 @@
                             streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
                             if (streamPushItem == null) {
                                 logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
-                                responseAck(evt, Response.GONE);
+                                responseAck(serverTransaction, Response.GONE);
+                                return;
+                            }
+                        }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);
+                                responseAck(serverTransaction, Response.GONE);
                                 return;
                             }
                         }
                     }
-                    responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
+                    responseAck(serverTransaction, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑
                 } else if (catalog != null) {
-                    responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾�
+                    responseAck(serverTransaction, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾�
                     return;
                 } else {
                     logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404");
-                    responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
+                    responseAck(serverTransaction, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
                     return;
                 }
                 // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
@@ -199,7 +246,7 @@
                 String ssrc;
                 SessionDescription sdp;
                 if (ssrcIndex >= 0) {
-                    //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈�
+                    //ssrc瑙勫畾闀垮害涓�10涓瓧鑺傦紝涓嶅彇浣欎笅闀垮害浠ラ伩鍏嶅悗缁繕鏈夆�渇=鈥濆瓧娈�
                     ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
                     String substring = contentString.substring(0, contentString.indexOf("y="));
                     sdp = SdpFactory.getInstance().createSessionDescription(substring);
@@ -240,16 +287,13 @@
                         String protocol = media.getProtocol();
 
                         // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
-                        if ("TCP/RTP/AVP".equals(protocol)) {
+                        if ("TCP/RTP/AVP".equalsIgnoreCase(protocol)) {
                             String setup = mediaDescription.getAttribute("setup");
                             if (setup != null) {
                                 mediaTransmissionTCP = true;
-                                if ("active".equals(setup)) {
+                                if ("active".equalsIgnoreCase(setup)) {
                                     tcpActive = true;
-                                    // 涓嶆敮鎸乼cp涓诲姩
-                                    responseAck(evt, Response.NOT_IMPLEMENTED, "tcp active not support"); // 鐩綍涓嶆敮鎸佺偣鎾�
-                                    return;
-                                } else if ("passive".equals(setup)) {
+                                } else if ("passive".equalsIgnoreCase(setup)) {
                                     tcpActive = false;
                                 }
                             }
@@ -260,7 +304,7 @@
                 if (port == -1) {
                     logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
                     // 鍥炲涓嶆敮鎸佺殑鏍煎紡
-                    responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+                    responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
                     return;
                 }
                 String username = sdp.getOrigin().getUsername();
@@ -273,32 +317,33 @@
                     device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId);
                     if (device == null) {
                         logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", requesterId, channel);
-                        responseAck(evt, Response.SERVER_INTERNAL_ERROR);
+                        responseAck(serverTransaction, Response.SERVER_INTERNAL_ERROR);
                         return;
                     }
                     mediaServerItem = playService.getNewMediaServerItem(device);
                     if (mediaServerItem == null) {
                         logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm");
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                         return;
                     }
                     SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
                             device.getDeviceId(), channelId,
                             mediaTransmissionTCP);
+
                     if (tcpActive != null) {
                         sendRtpItem.setTcpActive(tcpActive);
                     }
                     if (sendRtpItem == null) {
                         logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                         return;
                     }
                     sendRtpItem.setCallId(callIdHeader.getCallId());
-                    sendRtpItem.setPlayType("Play".equals(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK);
+                    sendRtpItem.setPlayType("Play".equalsIgnoreCase(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK);
 
                     Long finalStartTime = startTime;
                     Long finalStopTime = stopTime;
-                    ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> {
+                    ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> {
                         String app = responseJSON.getString("app");
                         String stream = responseJSON.getString("stream");
                         logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", app, stream);
@@ -313,7 +358,7 @@
                         content.append("o=" + channelId + " 0 0 IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n");
                         content.append("s=" + sessionName + "\r\n");
                         content.append("c=IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n");
-                        if ("Playback".equals(sessionName)) {
+                        if ("Playback".equalsIgnoreCase(sessionName)) {
                             content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n");
                         } else {
                             content.append("t=0 0\r\n");
@@ -332,7 +377,7 @@
                                 // 鍥炲bye
                                 cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
                             }, 60 * 1000);
-                            responseSdpAck(evt, content.toString(), platform);
+                            responseSdpAck(serverTransaction, content.toString(), platform);
 
                         } catch (SipException e) {
                             e.printStackTrace();
@@ -347,8 +392,8 @@
                         Response response = null;
                         try {
                             response = getMessageFactory().createResponse(event.statusCode, evt.getRequest());
-                            ServerTransaction serverTransaction = getServerTransaction(evt);
                             serverTransaction.sendResponse(response);
+                            System.out.println("鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒");
                             if (serverTransaction.getDialog() != null) {
                                 serverTransaction.getDialog().delete();
                             }
@@ -357,7 +402,7 @@
                         }
                     });
                     sendRtpItem.setApp("rtp");
-                    if ("Playback".equals(sessionName)) {
+                    if ("Playback".equalsIgnoreCase(sessionName)) {
                         sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
                         SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true, true);
                         sendRtpItem.setStreamId(ssrcInfo.getStream());
@@ -372,7 +417,7 @@
                                         }
                                         redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
                                         try {
-                                            responseAck(evt, Response.REQUEST_TIMEOUT);
+                                            responseAck(serverTransaction, Response.REQUEST_TIMEOUT);
                                         } catch (SipException e) {
                                             e.printStackTrace();
                                         } catch (InvalidArgumentException e) {
@@ -392,7 +437,14 @@
                         if (playTransaction != null) {
                             Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream());
                             if (!streamReady) {
-                                playTransaction = null;
+                                boolean hasRtpServer = mediaServerService.checkRtpServer(mediaServerItem, "rtp", playTransaction.getStream());
+                                if (hasRtpServer) {
+                                    logger.info("[涓婄骇鐐规挱]宸茬粡寮�鍚痳tpServer浣嗘槸灏氭湭鏀跺埌娴侊紝寮�鍚洃鍚祦鐨勫埌鏉�");
+                                    HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", playTransaction.getStream(), true, "rtsp", mediaServerItem.getId());
+                                    zlmHttpHookSubscribe.addSubscribe(hookSubscribe, hookEvent);
+                                }else {
+                                    playTransaction = null;
+                                }
                             }
                         }
                         if (playTransaction == null) {
@@ -401,7 +453,9 @@
                                 streamId = String.format("%s_%s", device.getDeviceId(), channelId);
                             }
                             SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false);
+                            logger.info(JSONObject.toJSONString(ssrcInfo));
                             sendRtpItem.setStreamId(ssrcInfo.getStream());
+
                             // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                             redisCatchStorage.updateSendRTPSever(sendRtpItem);
                             playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> {
@@ -419,18 +473,35 @@
                         }
                     }
                 } else if (gbStream != null) {
-                    if (streamPushItem.isStatus()) {
-                        // 鍦ㄧ嚎鐘舵��
-                        pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
-                    } else {
-                        // 涓嶅湪绾� 鎷夎捣
-                        notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
-                                mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                    if("push".equals(gbStream.getStreamType())) {
+                        if (streamPushItem != null && streamPushItem.isPushIng()) {
+                            // 鎺ㄦ祦鐘舵��
+                            pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                        } else {
+                            // 鏈帹娴� 鎷夎捣
+                            notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                        }
+                    }else if ("proxy".equals(gbStream.getStreamType())){
+                        if(null != proxyByAppAndStream &&proxyByAppAndStream.isStatus()){
+                            pushProxyStream(evt, serverTransaction, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                    mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                        }else{
+                            //寮�鍚唬鐞嗘媺娴�
+                            boolean start1 = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
+                            if(start1) {
+                                pushProxyStream(evt, serverTransaction, gbStream,  platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                            }else{
+                                //澶辫触鍚庨�氱煡
+                                notifyStreamOnline(evt, serverTransaction,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                        mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                            }
+                        }
+
                     }
-
                 }
-
             }
 
         } catch (SipException | InvalidArgumentException | ParseException e) {
@@ -447,13 +518,10 @@
     /**
      * 瀹夋帓鎺ㄦ祦
      */
-
-    private void pushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void pushProxyStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, ParentPlatform platform,
                             CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                             int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                             String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
-        // 鎺ㄦ祦
-        if (streamPushItem.getServerId().equals(userSetting.getServerId())) {
             Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
             if (streamReady) {
                 // 鑷钩鍙板唴瀹�
@@ -463,7 +531,7 @@
 
                 if (sendRtpItem == null) {
                     logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
-                    responseAck(evt, Response.BUSY_HERE);
+                    responseAck(serverTransaction, Response.BUSY_HERE);
                     return;
                 }
                 if (tcpActive != null) {
@@ -473,44 +541,84 @@
                 // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                 sendRtpItem.setStatus(1);
                 sendRtpItem.setCallId(callIdHeader.getCallId());
-                byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                sendRtpItem.setDialog(dialogByteArray);
-                byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                sendRtpItem.setTransaction(transactionByteArray);
+                SIPRequest request = (SIPRequest) evt.getRequest();
+                sendRtpItem.setFromTag(request.getFromTag());
+
+                SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                if (response != null) {
+                    sendRtpItem.setToTag(response.getToTag());
+                }
                 redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);
+
+        }
+
+    }
+    private void pushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+                            CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
+                            int port, Boolean tcpActive, boolean mediaTransmissionTCP,
+                            String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
+        // 鎺ㄦ祦
+        if (streamPushItem.isSelf()) {
+            Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
+            if (streamReady) {
+                // 鑷钩鍙板唴瀹�
+                SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+                        gbStream.getApp(), gbStream.getStream(), channelId,
+                        mediaTransmissionTCP);
+
+                if (sendRtpItem == null) {
+                    logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+                    responseAck(serverTransaction, Response.BUSY_HERE);
+                    return;
+                }
+                if (tcpActive != null) {
+                    sendRtpItem.setTcpActive(tcpActive);
+                }
+                sendRtpItem.setPlayType(InviteStreamType.PUSH);
+                // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+                sendRtpItem.setStatus(1);
+                sendRtpItem.setCallId(callIdHeader.getCallId());
+
+                SIPRequest request = (SIPRequest) evt.getRequest();
+                sendRtpItem.setFromTag(request.getFromTag());
+                SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                if (response != null) {
+                    sendRtpItem.setToTag(response.getToTag());
+                }
+
+                redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
             } else {
                 // 涓嶅湪绾� 鎷夎捣
-                notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                notifyStreamOnline(evt, serverTransaction,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
             }
 
         } else {
             // 鍏朵粬骞冲彴鍐呭
-            otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+            otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                     mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
         }
-
     }
-
     /**
      * 閫氱煡娴佷笂绾�
      */
-    private void notifyStreamOnline(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void notifyStreamOnline(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
                                     CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                                     int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                                     String channelId, String addressStr, String ssrc, String requesterId) throws InvalidArgumentException, ParseException, SipException {
         if ("proxy".equals(gbStream.getStreamType())) {
             // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
-            logger.info("[ app={}, stream={} ]閫氶亾绂荤嚎锛屽惎鐢ㄦ祦鍚庡紑濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
-            responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
+            logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
+            responseAck(serverTransaction, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
         } else if ("push".equals(gbStream.getStreamType())) {
             if (!platform.isStartOfflinePush()) {
-                responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable");
+                // 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
+                responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
                 return;
             }
             // 鍙戦�乺edis娑堟伅浠ヤ娇璁惧涓婄嚎
-            logger.info("[ app={}, stream={} ]閫氶亾绂荤嚎锛屽彂閫乺edis淇℃伅鎺у埗璁惧寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
+            logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍙戦�乺edis淇℃伅鎺у埗璁惧寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
 
             MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(1,
                     gbStream.getApp(), gbStream.getStream(), gbStream.getGbId(), gbStream.getPlatformId(),
@@ -520,8 +628,8 @@
             dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
                 logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
                 try {
-                    mediaListManager.removedChannelOnlineEventLister(gbStream.getGbId());
-                    responseAck(evt, Response.REQUEST_TIMEOUT); // 瓒呮椂
+                    mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
+                    responseAck(serverTransaction, Response.REQUEST_TIMEOUT); // 瓒呮椂
                 } catch (SipException e) {
                     e.printStackTrace();
                 } catch (InvalidArgumentException e) {
@@ -535,16 +643,16 @@
             Boolean finalTcpActive = tcpActive;
 
             // 娣诲姞鍦ㄦ湰鏈轰笂绾跨殑閫氱煡
-            mediaListManager.addChannelOnlineEventLister(gbStream.getGbId(), (app, stream, serverId) -> {
+            mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
                 dynamicTask.stop(callIdHeader.getCallId());
                 if (serverId.equals(userSetting.getServerId())) {
                     SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
                             app, stream, channelId, mediaTransmissionTCP);
 
                     if (sendRtpItem == null) {
-                        logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+                        logger.warn("涓婄骇鐐规椂鍒涘缓sendRTPItem澶辫触锛屽彲鑳芥槸鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                         try {
-                            responseAck(evt, Response.BUSY_HERE);
+                            responseAck(serverTransaction, Response.BUSY_HERE);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -561,16 +669,35 @@
                     // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                     sendRtpItem.setStatus(1);
                     sendRtpItem.setCallId(callIdHeader.getCallId());
-                    byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                    sendRtpItem.setDialog(dialogByteArray);
-                    byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                    sendRtpItem.setTransaction(transactionByteArray);
+
+                    SIPRequest request = (SIPRequest) evt.getRequest();
+                    sendRtpItem.setFromTag(request.getFromTag());
+                    SIPResponse response = sendStreamAck(mediaServerItem, serverTransaction, sendRtpItem, platform, evt);
+                    if (response != null) {
+                        sendRtpItem.setToTag(response.getToTag());
+                    }
                     redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                    sendStreamAck(mediaServerItem, sendRtpItem, platform, evt);
                 } else {
                     // 鍏朵粬骞冲彴鍐呭
-                    otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                    otherWvpPushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                             mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+                }
+            });
+
+            // 娣诲姞鍥炲鐨勬嫆缁濇垨鑰呴敊璇殑閫氱煡
+            redisPushStreamResponseListener.addEvent(gbStream.getApp(), gbStream.getStream(), response -> {
+                if (response.getCode() != 0) {
+                    dynamicTask.stop(callIdHeader.getCallId());
+                    mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
+                    try {
+                        responseAck(serverTransaction, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+                    } catch (SipException e) {
+                        throw new RuntimeException(e);
+                    } catch (InvalidArgumentException e) {
+                        throw new RuntimeException(e);
+                    } catch (ParseException e) {
+                        throw new RuntimeException(e);
+                    }
                 }
             });
         }
@@ -579,7 +706,7 @@
     /**
      * 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴�
      */
-    private void otherWvpPushStream(RequestEvent evt, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+    private void otherWvpPushStream(RequestEvent evt, ServerTransaction serverTransaction, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
                                     CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
                                     int port, Boolean tcpActive, boolean mediaTransmissionTCP,
                                     String channelId, String addressStr, String ssrc, String requesterId) {
@@ -592,7 +719,7 @@
                     if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
                         logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
                         try {
-                            responseAck(evt, Response.BUSY_HERE);
+                            responseAck(serverTransaction, Response.BUSY_HERE);
                         } catch (SipException e) {
                             e.printStackTrace();
                         } catch (InvalidArgumentException e) {
@@ -610,12 +737,14 @@
                     // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
                     sendRtpItem.setStatus(1);
                     sendRtpItem.setCallId(callIdHeader.getCallId());
-                    byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog());
-                    sendRtpItem.setDialog(dialogByteArray);
-                    byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction());
-                    sendRtpItem.setTransaction(transactionByteArray);
+
+                    SIPRequest request = (SIPRequest) evt.getRequest();
+                    sendRtpItem.setFromTag(request.getFromTag());
+                    SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), serverTransaction,sendRtpItem, platform, evt);
+                    if (response != null) {
+                        sendRtpItem.setToTag(response.getToTag());
+                    }
                     redisCatchStorage.updateSendRTPSever(sendRtpItem);
-                    sendStreamAck(responseSendItemMsg.getMediaServerItem(), sendRtpItem, platform, evt);
                 }, (wvpResult) -> {
                     try {
                         // 閿欒
@@ -623,14 +752,14 @@
                             // 绂荤嚎
                             // 鏌ヨ鏄惁鍦ㄦ湰鏈轰笂绾夸簡
                             StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream());
-                            if (currentStreamPushItem.isStatus()) {
+                            if (currentStreamPushItem.isPushIng()) {
                                 // 鍦ㄧ嚎鐘舵��
-                                pushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                pushStream(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
 
                             } else {
                                 // 涓嶅湪绾� 鎷夎捣
-                                notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+                                notifyStreamOnline(evt, serverTransaction, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
                                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
                             }
                         }
@@ -644,7 +773,7 @@
 
 
                     try {
-                        responseAck(evt, Response.BUSY_HERE);
+                        responseAck(serverTransaction, Response.BUSY_HERE);
                     } catch (SipException e) {
                         e.printStackTrace();
                     } catch (InvalidArgumentException e) {
@@ -656,7 +785,7 @@
                 });
     }
 
-    public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
+    public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, ServerTransaction serverTransaction, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
 
         StringBuffer content = new StringBuffer(200);
         content.append("v=0\r\n");
@@ -679,7 +808,7 @@
         content.append("f=\r\n");
 
         try {
-            responseSdpAck(evt, content.toString(), platform);
+            return responseSdpAck(serverTransaction, content.toString(), platform);
         } catch (SipException e) {
             e.printStackTrace();
         } catch (InvalidArgumentException e) {
@@ -687,25 +816,32 @@
         } catch (ParseException e) {
             e.printStackTrace();
         }
+        return null;
     }
 
-    public void inviteFromDeviceHandle(RequestEvent evt, String requesterId) throws InvalidArgumentException, ParseException, SipException, SdpException {
+    public void inviteFromDeviceHandle(ServerTransaction serverTransaction, String requesterId, String channelId) throws InvalidArgumentException, ParseException, SipException, SdpException {
 
         // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
         Device device = redisCatchStorage.getDevice(requesterId);
-        Request request = evt.getRequest();
+        AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(requesterId, channelId);
+        if (audioBroadcastCatch == null) {
+            logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
+            responseAck(serverTransaction, Response.FORBIDDEN);
+            return;
+        }
+        Request request = serverTransaction.getRequest();
         if (device != null) {
             logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
-            responseAck(evt, Response.TRYING);
+            responseAck(serverTransaction, Response.TRYING);
 
-            String contentString = new String(request.getRawContent());
+            String contentString = new String(serverTransaction.getRequest().getRawContent());
             // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
             String substring = contentString;
             String ssrc = "0000000404";
             int ssrcIndex = contentString.indexOf("y=");
             if (ssrcIndex > 0) {
                 substring = contentString.substring(0, ssrcIndex);
-                ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
+                ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim();
             }
             ssrcIndex = substring.indexOf("f=");
             if (ssrcIndex > 0) {
@@ -715,13 +851,13 @@
 
             //  鑾峰彇鏀寔鐨勬牸寮�
             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++) {
-                MediaDescription mediaDescription = (MediaDescription) mediaDescriptions.get(i);
+                MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i);
                 Media media = mediaDescription.getMedia();
 
                 Vector mediaFormats = media.getMediaFormats(false);
@@ -746,16 +882,164 @@
             if (port == -1) {
                 logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
                 // 鍥炲涓嶆敮鎸佺殑鏍煎紡
-                responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+                responseAck(serverTransaction, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
                 return;
             }
-            String username = sdp.getOrigin().getUsername();
             String addressStr = sdp.getOrigin().getAddress();
-            logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+            logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", requesterId, addressStr, port, ssrc);
 
+            MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device);
+            if (mediaServerItem == null) {
+                logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm");
+                responseAck(serverTransaction, Response.BUSY_HERE);
+                return;
+            }
+            SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+                    device.getDeviceId(), audioBroadcastCatch.getChannelId(),
+                    mediaTransmissionTCP);
+            if (sendRtpItem == null) {
+                logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+                responseAck(serverTransaction, Response.BUSY_HERE);
+                return;
+            }
+            sendRtpItem.setTcp(mediaTransmissionTCP);
+            if (tcpActive != null) {
+                sendRtpItem.setTcpActive(tcpActive);
+            }
+            String app = "broadcast";
+            String stream = device.getDeviceId() + "_" + audioBroadcastCatch.getChannelId();
+
+            CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
+            sendRtpItem.setPlayType(InviteStreamType.PLAY);
+            sendRtpItem.setCallId(callIdHeader.getCallId());
+            sendRtpItem.setPlatformId(requesterId);
+            sendRtpItem.setStatus(1);
+            sendRtpItem.setApp(app);
+            sendRtpItem.setStreamId(stream);
+            sendRtpItem.setPt(8);
+            sendRtpItem.setUsePs(false);
+            sendRtpItem.setOnlyAudio(true);
+            redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+            // hook鐩戝惉绛夊緟璁惧鎺ㄦ祦涓婃潵
+            // 娣诲姞璁㈤槄
+            HookSubscribeForStreamChange subscribeKey = HookSubscribeFactory.on_stream_changed(app, stream, true, "rtsp", mediaServerItem.getId());
+
+            String finalSsrc = ssrc;
+            // 娴佸凡缁忓瓨鍦ㄦ椂鐩存帴鎺ㄦ祦
+                // 璁剧疆绛夊緟鎺ㄦ祦鐨勮秴鏃�; 榛樿20s
+                String waiteStreamTimeoutTaskKey = "waite-stream-" + device.getDeviceId() + audioBroadcastCatch.getChannelId();
+                dynamicTask.startDelay(waiteStreamTimeoutTaskKey, ()->{
+                    logger.info("绛夊緟鎺ㄦ祦瓒呮椂: {}/{}", app, stream);
+                    subscribe.removeSubscribe(subscribeKey);
+                    playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
+                    // 鍙戦�乥ye
+                    try {
+                        responseAck(evt, Response.BUSY_HERE);
+                    } catch (SipException e) {
+                        throw new RuntimeException(e);
+                    } catch (InvalidArgumentException e) {
+                        throw new RuntimeException(e);
+                    } catch (ParseException e) {
+                        throw new RuntimeException(e);
+                    }
+                }, 20*1000);
+
+                boolean finalMediaTransmissionTCP = mediaTransmissionTCP;
+                subscribe.addSubscribe(subscribeKey,
+                        (MediaServerItem mediaServerItemInUse, JSONObject json)->{
+                            logger.info("鏀跺埌璇煶瀵硅鎺ㄦ祦");
+                            dynamicTask.stop(waiteStreamTimeoutTaskKey);
+                            MediaItem mediaItem = JSON.toJavaObject(json, MediaItem.class);
+                            Integer audioCodecId = null;
+                            if (mediaItem.getTracks() != null && mediaItem.getTracks().size() > 0) {
+                                for (int i = 0; i < mediaItem.getTracks().size(); i++) {
+                                    MediaItem.MediaTrack mediaTrack = mediaItem.getTracks().get(i);
+                                    if (mediaTrack.getCodecType() == 1) {
+                                        audioCodecId = mediaTrack.getCodecId();
+                                        break;
+                                    }
+                                }
+                            }
+
+                            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 (audioCodecId == null) {
+                                    if (finalMediaTransmissionTCP) {
+                                        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\r\n");
+                                }else {
+                                    if (audioCodecId == 4) {
+                                        if (finalMediaTransmissionTCP) {
+                                            content.append("m=audio "+ sendRtpItem.getLocalPort()+" TCP/RTP/AVP 0\r\n");
+                                        }else {
+                                            content.append("m=audio "+ sendRtpItem.getLocalPort()+" RTP/AVP 0\r\n");
+                                        }
+                                        content.append("a=rtpmap:0 PCMU/8000\r\n");
+                                    }else {
+                                        if (finalMediaTransmissionTCP) {
+                                            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\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="+ finalSsrc + "\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());
+
+                                responseSdpAck(serverTransaction, content.toString(), parentPlatform);
+                                Dialog dialog = evt.getDialog();
+                                audioBroadcastCatch.setDialog((SIPDialog) dialog);
+                                audioBroadcastCatch.setRequest((SIPRequest) request);
+                                audioBroadcastManager.update(audioBroadcastCatch);
+                            } catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
+                                logger.error("[鍛戒护鍙戦�佸け璐 璇煶瀵硅: {}", e.getMessage());
+                            }
+                        });
+//            }
+            String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + device.getDeviceId();
+            WVPResult<AudioBroadcastResult> wvpResult = new WVPResult<>();
+            wvpResult.setCode(0);
+            wvpResult.setMsg("success");
+            AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult();
+            audioBroadcastResult.setApp(app);
+            audioBroadcastResult.setStream(stream);
+            audioBroadcastResult.setStreamInfo(mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null,false));
+            audioBroadcastResult.setCodec("G.711");
+            wvpResult.setData(audioBroadcastResult);
+            RequestMessage requestMessage = new RequestMessage();
+            requestMessage.setKey(key);
+            requestMessage.setData(wvpResult);
+            resultHolder.invokeAllResult(requestMessage);
         } else {
             logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
-            responseAck(evt, Response.BAD_REQUEST);
+            responseAck(serverTransaction, Response.BAD_REQUEST);
         }
     }
 }

--
Gitblit v1.8.0