From 72c1b36d6d2ece497e032c8434641d6576590f9d Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期日, 03 七月 2022 00:44:36 +0800 Subject: [PATCH] 优化对讲逻辑 --- src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 1492 ++++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 959 insertions(+), 533 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 2723da4..7b7136f 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,12 +1,18 @@ 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; @@ -15,18 +21,29 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils; 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.MediaItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItemLite; +import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; 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.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.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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; @@ -50,564 +67,973 @@ @Component public class InviteRequestProcessor extends SIPRequestProcessorParent implements InitializingBean, ISIPRequestProcessor { - private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class); + private final static Logger logger = LoggerFactory.getLogger(InviteRequestProcessor.class); - private String method = "INVITE"; + private final String method = "INVITE"; + + @Autowired + private SIPCommanderFroPlatform cmderFroPlatform; + + @Autowired + private IVideoManagerStorage storager; + + @Autowired + private IStreamPushService streamPushService; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + @Autowired + private DynamicTask dynamicTask; + + @Autowired + private SIPCommander cmder; + + @Autowired + private IPlayService playService; + + @Autowired + private ISIPCommander commander; + + @Autowired + private AudioBroadcastManager audioBroadcastManager; + + @Autowired + private ZLMRTPServerFactory zlmrtpServerFactory; + + @Autowired + private IMediaServerService mediaServerService; + + @Autowired + private IMediaService mediaService; @Autowired - private SIPCommanderFroPlatform cmderFroPlatform; + private ZLMRESTfulUtils zlmresTfulUtils; + + @Autowired + private SIPProcessorObserver sipProcessorObserver; + + @Autowired + private VideoStreamSessionManager sessionManager; + + @Autowired + private UserSetting userSetting; + + @Autowired + private ZLMMediaListManager mediaListManager; @Autowired - private IVideoManagerStorage storager; + private DeferredResultHolder resultHolder; @Autowired - private IRedisCatchStorage redisCatchStorage; + private ZLMHttpHookSubscribe subscribe; @Autowired - private DynamicTask dynamicTask; - - @Autowired - private SIPCommander cmder; - - @Autowired - private IPlayService playService; - - @Autowired - private ISIPCommander commander; - - @Autowired - private ZLMRTPServerFactory zlmrtpServerFactory; - - @Autowired - private IMediaServerService mediaServerService; - - @Autowired - private SIPProcessorObserver sipProcessorObserver; - - @Autowired - private VideoStreamSessionManager sessionManager; - - @Autowired - private UserSetting userSetting; - - @Autowired - private ZLMMediaListManager mediaListManager; + private SipConfig config; - @Override - public void afterPropertiesSet() throws Exception { - // 娣诲姞娑堟伅澶勭悊鐨勮闃� - sipProcessorObserver.addRequestProcessor(method, this); - } - /** - * 澶勭悊invite璇锋眰 - * - * @param evt - * 璇锋眰娑堟伅 - */ - @Override - public void process(RequestEvent evt) { - // 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 requesterId = SipUtils.getUserIdFromFromHeader(request); - CallIdHeader callIdHeader = (CallIdHeader)request.getHeader(CallIdHeader.NAME); - if (requesterId == null || channelId == null) { - logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400"); - responseAck(evt, Response.BAD_REQUEST); // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇� - return; - } - - // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧 - ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId); - if (platform == null) { - inviteFromDeviceHandle(evt, requesterId); - }else { - // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾 - DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); - GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); - PlatformCatalog catalog = storager.getCatalog(channelId); - MediaServerItem mediaServerItem = 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锛屽懠鍙浆鎺ヤ腑 - }else if(channel == null && gbStream != null){ - String mediaServerId = gbStream.getMediaServerId(); - mediaServerItem = mediaServerService.getOne(mediaServerId); - if (mediaServerItem == null) { - logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410",gbStream.getApp(), gbStream.getStream(), mediaServerId); - responseAck(evt, Response.GONE); - return; - } - responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑 - }else if (catalog != null) { - responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾� - return; - } else { - logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404"); - responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪 - return; - } - // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡 - String contentString = new String(request.getRawContent()); - - // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� - int ssrcIndex = contentString.indexOf("y="); - // 妫�鏌ユ槸鍚︽湁y瀛楁 - String ssrcDefault = "0000000000"; - String ssrc; - SessionDescription sdp; - if (ssrcIndex >= 0) { - //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈� - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); - String substring = contentString.substring(0, contentString.indexOf("y=")); - sdp = SdpFactory.getInstance().createSessionDescription(substring); - }else { - ssrc = ssrcDefault; - sdp = SdpFactory.getInstance().createSessionDescription(contentString); - } - String sessionName = sdp.getSessionName().getValue(); - - Long startTime = null; - Long stopTime = null; - Instant start = null; - Instant end = null; - if (sdp.getTimeDescriptions(false) != null && sdp.getTimeDescriptions(false).size() > 0) { - TimeDescriptionImpl timeDescription = (TimeDescriptionImpl)(sdp.getTimeDescriptions(false).get(0)); - TimeField startTimeFiled = (TimeField)timeDescription.getTime(); - startTime = startTimeFiled.getStartTime(); - stopTime = startTimeFiled.getStopTime(); - - start = Instant.ofEpochMilli(startTime*1000); - end = Instant.ofEpochMilli(stopTime*1000); - } - // 鑾峰彇鏀寔鐨勬牸寮� - Vector mediaDescriptions = sdp.getMediaDescriptions(true); - // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96 - //String ip = null; - int port = -1; - boolean mediaTransmissionTCP = false; - Boolean tcpActive = null; - for (Object description : mediaDescriptions) { - MediaDescription mediaDescription = (MediaDescription) description; - Media media = mediaDescription.getMedia(); - - Vector mediaFormats = media.getMediaFormats(false); - if (mediaFormats.contains("96")) { - port = media.getMediaPort(); - //String mediaType = media.getMediaType(); - String protocol = media.getProtocol(); - - // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp - if ("TCP/RTP/AVP".equals(protocol)) { - String setup = mediaDescription.getAttribute("setup"); - if (setup != null) { - mediaTransmissionTCP = true; - if ("active".equals(setup)) { - tcpActive = true; - // 涓嶆敮鎸乼cp涓诲姩 - responseAck(evt, Response.NOT_IMPLEMENTED, "tcp active not support"); // 鐩綍涓嶆敮鎸佺偣鎾� - return; - } else if ("passive".equals(setup)) { - tcpActive = false; - } - } - } - break; - } - } - if (port == -1) { - logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415"); - // 鍥炲涓嶆敮鎸佺殑鏍煎紡 - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415 - return; - } - String username = sdp.getOrigin().getUsername(); - String addressStr = sdp.getOrigin().getAddress(); - - logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, addressStr, port, ssrc); - Device device = null; - // 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍� - if (channel != null) { - device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); - if (device == null) { - logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", requesterId, channel); - responseAck(evt, Response.SERVER_INTERNAL_ERROR); - return; - } - mediaServerItem = playService.getNewMediaServerItem(device); - if (mediaServerItem == null) { - logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm"); - responseAck(evt, 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); - return; - } - sendRtpItem.setCallId(callIdHeader.getCallId()); - sendRtpItem.setPlayType("Play".equals(sessionName)?InviteStreamType.PLAY:InviteStreamType.PLAYBACK); - byte[] dialogByteArray = SerializeUtils.serialize(evt.getDialog()); - sendRtpItem.setDialog(dialogByteArray); - byte[] transactionByteArray = SerializeUtils.serialize(evt.getServerTransaction()); - sendRtpItem.setTransaction(transactionByteArray); - Long finalStartTime = startTime; - Long finalStopTime = stopTime; - ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON)->{ - String app = responseJSON.getString("app"); - String stream = responseJSON.getString("stream"); - logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", app, stream); - // * 0 绛夊緟璁惧鎺ㄦ祦涓婃潵 - // * 1 涓嬬骇宸茬粡鎺ㄦ祦锛岀瓑寰呬笂绾у钩鍙板洖澶峚ck - // * 2 鎺ㄦ祦涓� - sendRtpItem.setStatus(1); - redisCatchStorage.updateSendRTPSever(sendRtpItem); - - 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("s=" + sessionName+"\r\n"); - content.append("c=IN IP4 "+mediaServerItemInUSe.getSdpIp()+"\r\n"); - if ("Playback".equals(sessionName)) { - content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n"); - }else { - content.append("t=0 0\r\n"); - } - content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); - content.append("a=sendonly\r\n"); - content.append("a=rtpmap:96 PS/90000\r\n"); - content.append("y="+ ssrc + "\r\n"); - content.append("f=\r\n"); - - try { - // 瓒呮椂鏈敹鍒癆ck搴旇鍥炲bye,褰撳墠绛夊緟鏃堕棿涓�10绉� - dynamicTask.startDelay(callIdHeader.getCallId(), ()->{ - logger.info("Ack 绛夊緟瓒呮椂"); - mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), ssrc); - // 鍥炲bye - cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId()); - }, 60*1000); - responseSdpAck(evt, content.toString(), platform); - - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - }; - SipSubscribe.Event errorEvent = ((event) -> { - // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒 - Response response = null; - try { - response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); - ServerTransaction serverTransaction = getServerTransaction(evt); - serverTransaction.sendResponse(response); - if (serverTransaction.getDialog() != null) { - serverTransaction.getDialog().delete(); - } - } catch (ParseException | SipException | InvalidArgumentException e) { - e.printStackTrace(); - } - }); - sendRtpItem.setApp("rtp"); - if ("Playback".equals(sessionName)) { - sendRtpItem.setPlayType(InviteStreamType.PLAYBACK); - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true, true); - sendRtpItem.setStreamId(ssrcInfo.getStream()); - // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� - redisCatchStorage.updateSendRTPSever(sendRtpItem); - playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), - DateUtil.formatter.format(end), null, result -> { - if (result.getCode() != 0){ - logger.warn("褰曞儚鍥炴斁澶辫触"); - if (result.getEvent() != null) { - errorEvent.response(result.getEvent()); - } - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); - try { - responseAck(evt, Response.REQUEST_TIMEOUT); - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - }else { - if (result.getMediaServerItem() != null) { - hookEvent.response(result.getMediaServerItem(), result.getResponse()); - } - } - }); - }else { - sendRtpItem.setPlayType(InviteStreamType.PLAY); - SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); - if (playTransaction != null) { - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream()); - if (!streamReady) { - playTransaction = null; - } - } - if (playTransaction == null) { - String streamId = null; - if (mediaServerItem.isRtpEnable()) { - streamId = String.format("%s_%s", device.getDeviceId(), channelId); - } - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, true, false); - sendRtpItem.setStreamId(ssrcInfo.getStream()); - // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� - redisCatchStorage.updateSendRTPSever(sendRtpItem); - playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg)->{ - redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); - }, null); - }else { - sendRtpItem.setStreamId(playTransaction.getStream()); - // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� - redisCatchStorage.updateSendRTPSever(sendRtpItem); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("app", sendRtpItem.getApp()); - jsonObject.put("stream", sendRtpItem.getStreamId()); - hookEvent.response(mediaServerItem, jsonObject); - } - } - }else if (gbStream != null) { - - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream()); - if (!streamReady ) { - if ("proxy".equals(gbStream.getStreamType())) { - // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎 - logger.info("[ app={}, stream={} ]閫氶亾绂荤嚎锛屽惎鐢ㄦ祦鍚庡紑濮嬫帹娴�",gbStream.getApp(), gbStream.getStream()); - responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); - }else if ("push".equals(gbStream.getStreamType())) { - if (!platform.isStartOfflinePush()) { - responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable"); - return; - } - // 鍙戦�乺edis娑堟伅浠ヤ娇璁惧涓婄嚎 - logger.info("[ app={}, stream={} ]閫氶亾绂荤嚎锛屽彂閫乺edis淇℃伅鎺у埗璁惧寮�濮嬫帹娴�",gbStream.getApp(), gbStream.getStream()); - MessageForPushChannel messageForPushChannel = new MessageForPushChannel(); - messageForPushChannel.setType(1); - messageForPushChannel.setGbId(gbStream.getGbId()); - messageForPushChannel.setApp(gbStream.getApp()); - messageForPushChannel.setStream(gbStream.getStream()); - // TODO 鑾峰彇浣庤礋杞界殑鑺傜偣 - messageForPushChannel.setMediaServerId(gbStream.getMediaServerId()); - messageForPushChannel.setPlatFormId(platform.getServerGBId()); - messageForPushChannel.setPlatFormName(platform.getName()); - redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); - // 璁剧疆瓒呮椂 - dynamicTask.startDelay(callIdHeader.getCallId(), ()->{ - logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", gbStream.getApp(), gbStream.getStream()); - try { - mediaListManager.removedChannelOnlineEventLister(gbStream.getGbId()); - responseAck(evt, Response.REQUEST_TIMEOUT); // 瓒呮椂 - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - }, userSetting.getPlatformPlayTimeout()); - // 娣诲姞鐩戝惉 - MediaServerItem finalMediaServerItem = mediaServerItem; - int finalPort = port; - boolean finalMediaTransmissionTCP = mediaTransmissionTCP; - Boolean finalTcpActive = tcpActive; - mediaListManager.addChannelOnlineEventLister(gbStream.getGbId(), (app, stream)->{ - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(finalMediaServerItem, addressStr, finalPort, ssrc, requesterId, - app, stream, channelId, finalMediaTransmissionTCP); - - if (sendRtpItem == null) { - logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�"); - try { - responseAck(evt, Response.BUSY_HERE); - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - return; - } - if (finalTcpActive != null) { - sendRtpItem.setTcpActive(finalTcpActive); - } - sendRtpItem.setPlayType(InviteStreamType.PUSH); - // 鍐欏叆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); - redisCatchStorage.updateSendRTPSever(sendRtpItem); - sendStreamAck(finalMediaServerItem, sendRtpItem, platform, evt); - - }); - } - }else { - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, - gbStream.getApp(), gbStream.getStream(), channelId, - mediaTransmissionTCP); + @Autowired + private RedisGbPlayMsgListener redisGbPlayMsgListener; - if (sendRtpItem == null) { - logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�"); - responseAck(evt, Response.BUSY_HERE); - return; - } - if (tcpActive != null) { - sendRtpItem.setTcpActive(tcpActive); - } - sendRtpItem.setPlayType(InviteStreamType.PUSH); - // 鍐欏叆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); - redisCatchStorage.updateSendRTPSever(sendRtpItem); - sendStreamAck(mediaServerItem, sendRtpItem, platform, evt); - } + @Override + public void afterPropertiesSet() throws Exception { + // 娣诲姞娑堟伅澶勭悊鐨勮闃� + sipProcessorObserver.addRequestProcessor(method, this); + } + + /** + * 澶勭悊invite璇锋眰 + * + * @param evt 璇锋眰娑堟伅 + */ + @Override + public void process(RequestEvent evt) { + // 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 requesterId = SipUtils.getUserIdFromFromHeader(request); + CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); + if (requesterId == null || channelId == null) { + logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400"); + // 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇� + responseAck(evt, Response.BAD_REQUEST); + return; + } + + // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧 + ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId); + if (platform == null) { + inviteFromDeviceHandle(evt, requesterId, channelId); + } else { + // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾 + DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); + GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); + PlatformCatalog catalog = storager.getCatalog(channelId); + + MediaServerItem mediaServerItem = null; + StreamPushItem streamPushItem = 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锛屽懠鍙浆鎺ヤ腑 + } else if (channel == null && gbStream != null) { + + String mediaServerId = gbStream.getMediaServerId(); + mediaServerItem = mediaServerService.getOne(mediaServerId); + if (mediaServerItem == null) { + if ("proxy".equals(gbStream.getStreamType())) { + logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId); + responseAck(evt, 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); + return; + } + } + } else { + if ("push".equals(gbStream.getStreamType())) { + 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); + return; + } + } + } + responseAck(evt, Response.CALL_IS_BEING_FORWARDED); // 閫氶亾瀛樺湪锛屽彂181锛屽懠鍙浆鎺ヤ腑 + } else if (catalog != null) { + responseAck(evt, Response.BAD_REQUEST, "catalog channel can not play"); // 鐩綍涓嶆敮鎸佺偣鎾� + return; + } else { + logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404"); + responseAck(evt, Response.NOT_FOUND); // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪 + return; + } + // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡 + String contentString = new String(request.getRawContent()); + + // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎浠ヨВ鏋愩�� + int ssrcIndex = contentString.indexOf("y="); + // 妫�鏌ユ槸鍚︽湁y瀛楁 + String ssrcDefault = "0000000000"; + String ssrc; + SessionDescription sdp; + if (ssrcIndex >= 0) { + //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈� + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + String substring = contentString.substring(0, contentString.indexOf("y=")); + sdp = SdpFactory.getInstance().createSessionDescription(substring); + } else { + ssrc = ssrcDefault; + sdp = SdpFactory.getInstance().createSessionDescription(contentString); + } + String sessionName = sdp.getSessionName().getValue(); + + Long startTime = null; + Long stopTime = null; + Instant start = null; + Instant end = null; + if (sdp.getTimeDescriptions(false) != null && sdp.getTimeDescriptions(false).size() > 0) { + TimeDescriptionImpl timeDescription = (TimeDescriptionImpl) (sdp.getTimeDescriptions(false).get(0)); + TimeField startTimeFiled = (TimeField) timeDescription.getTime(); + startTime = startTimeFiled.getStartTime(); + stopTime = startTimeFiled.getStopTime(); + + start = Instant.ofEpochSecond(startTime); + end = Instant.ofEpochSecond(stopTime); + } + // 鑾峰彇鏀寔鐨勬牸寮� + Vector mediaDescriptions = sdp.getMediaDescriptions(true); + // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96 + //String ip = null; + int port = -1; + boolean mediaTransmissionTCP = false; + Boolean tcpActive = null; + for (Object description : mediaDescriptions) { + MediaDescription mediaDescription = (MediaDescription) description; + Media media = mediaDescription.getMedia(); + + Vector mediaFormats = media.getMediaFormats(false); + if (mediaFormats.contains("96")) { + port = media.getMediaPort(); + //String mediaType = media.getMediaType(); + String protocol = media.getProtocol(); + + // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp + if ("TCP/RTP/AVP".equals(protocol)) { + String setup = mediaDescription.getAttribute("setup"); + if (setup != null) { + mediaTransmissionTCP = true; + if ("active".equals(setup)) { + tcpActive = true; + // 涓嶆敮鎸乼cp涓诲姩 + responseAck(evt, Response.NOT_IMPLEMENTED, "tcp active not support"); // 鐩綍涓嶆敮鎸佺偣鎾� + return; + } else if ("passive".equals(setup)) { + tcpActive = false; + } + } + } + break; + } + } + if (port == -1) { + logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415"); + // 鍥炲涓嶆敮鎸佺殑鏍煎紡 + responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415 + return; + } + String username = sdp.getOrigin().getUsername(); + String addressStr = sdp.getOrigin().getAddress(); + + logger.info("[涓婄骇鐐规挱]鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}, 鍦板潃锛歿}:{}锛� ssrc锛歿}", username, channelId, addressStr, port, ssrc); + Device device = null; + // 閫氳繃 channel 鍜� gbStream 鏄惁涓簄ull 鍊煎垽鏂潵婧愭槸鐩存挱娴佸悎閫傚浗鏍� + if (channel != null) { + device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); + if (device == null) { + logger.warn("鐐规挱骞冲彴{}鐨勯�氶亾{}鏃舵湭鎵惧埌璁惧淇℃伅", requesterId, channel); + responseAck(evt, Response.SERVER_INTERNAL_ERROR); + return; + } + mediaServerItem = playService.getNewMediaServerItem(device); + if (mediaServerItem == null) { + logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm"); + responseAck(evt, 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); + return; + } + sendRtpItem.setCallId(callIdHeader.getCallId()); + sendRtpItem.setPlayType("Play".equals(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK); + + Long finalStartTime = startTime; + Long finalStopTime = stopTime; + ZLMHttpHookSubscribe.Event hookEvent = (mediaServerItemInUSe, responseJSON) -> { + String app = responseJSON.getString("app"); + String stream = responseJSON.getString("stream"); + logger.info("[涓婄骇鐐规挱]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", app, stream); + // * 0 绛夊緟璁惧鎺ㄦ祦涓婃潵 + // * 1 涓嬬骇宸茬粡鎺ㄦ祦锛岀瓑寰呬笂绾у钩鍙板洖澶峚ck + // * 2 鎺ㄦ祦涓� + sendRtpItem.setStatus(1); + redisCatchStorage.updateSendRTPSever(sendRtpItem); + + 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("s=" + sessionName + "\r\n"); + content.append("c=IN IP4 " + mediaServerItemInUSe.getSdpIp() + "\r\n"); + if ("Playback".equals(sessionName)) { + content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n"); + } else { + content.append("t=0 0\r\n"); + } + content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n"); + content.append("a=sendonly\r\n"); + content.append("a=rtpmap:96 PS/90000\r\n"); + content.append("y=" + ssrc + "\r\n"); + content.append("f=\r\n"); + + try { + // 瓒呮椂鏈敹鍒癆ck搴旇鍥炲bye,褰撳墠绛夊緟鏃堕棿涓�10绉� + dynamicTask.startDelay(callIdHeader.getCallId(), () -> { + logger.info("Ack 绛夊緟瓒呮椂"); + mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), ssrc); + // 鍥炲bye + cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId()); + }, 60 * 1000); + responseSdpAck(evt, content.toString(), platform); + + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + }; + SipSubscribe.Event errorEvent = ((event) -> { + // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒 + Response response = null; + try { + response = getMessageFactory().createResponse(event.statusCode, evt.getRequest()); + ServerTransaction serverTransaction = getServerTransaction(evt); + serverTransaction.sendResponse(response); + if (serverTransaction.getDialog() != null) { + serverTransaction.getDialog().delete(); + } + } catch (ParseException | SipException | InvalidArgumentException e) { + e.printStackTrace(); + } + }); + sendRtpItem.setApp("rtp"); + if ("Playback".equals(sessionName)) { + sendRtpItem.setPlayType(InviteStreamType.PLAYBACK); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, true, true); + sendRtpItem.setStreamId(ssrcInfo.getStream()); + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); + playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), + DateUtil.formatter.format(end), null, result -> { + if (result.getCode() != 0) { + logger.warn("褰曞儚鍥炴斁澶辫触"); + if (result.getEvent() != null) { + errorEvent.response(result.getEvent()); + } + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); + try { + responseAck(evt, Response.REQUEST_TIMEOUT); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + } else { + if (result.getMediaServerItem() != null) { + hookEvent.response(result.getMediaServerItem(), result.getResponse()); + } + } + }); + } else { + sendRtpItem.setPlayType(InviteStreamType.PLAY); + SsrcTransaction playTransaction = sessionManager.getSsrcTransaction(device.getDeviceId(), channelId, "play", null); + if (playTransaction != null) { + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, "rtp", playTransaction.getStream()); + if (!streamReady) { + playTransaction = null; + } + } + if (playTransaction == null) { + String streamId = null; + if (mediaServerItem.isRtpEnable()) { + streamId = String.format("%s_%s", device.getDeviceId(), channelId); + } + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false); + sendRtpItem.setStreamId(ssrcInfo.getStream()); + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); + playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { + logger.info("[涓婄骇鐐规挱]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId); + redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); + }, null); + } else { + sendRtpItem.setStreamId(playTransaction.getStream()); + // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶� + redisCatchStorage.updateSendRTPSever(sendRtpItem); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("app", sendRtpItem.getApp()); + jsonObject.put("stream", sendRtpItem.getStreamId()); + hookEvent.response(mediaServerItem, jsonObject); + } + } + } 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); + } + + } + + } + + } catch (SipException | InvalidArgumentException | ParseException e) { + e.printStackTrace(); + logger.warn("sdp瑙f瀽閿欒"); + e.printStackTrace(); + } catch (SdpParseException e) { + e.printStackTrace(); + } catch (SdpException e) { + e.printStackTrace(); + } + } + + /** + * 瀹夋帓鎺ㄦ祦 + */ + + private void pushStream(RequestEvent evt, 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.getServerId().equals(userSetting.getServerId())) { + 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(evt, Response.BUSY_HERE); + return; + } + if (tcpActive != null) { + sendRtpItem.setTcpActive(tcpActive); + } + sendRtpItem.setPlayType(InviteStreamType.PUSH); + // 鍐欏叆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); + redisCatchStorage.updateSendRTPSever(sendRtpItem); + sendStreamAck(mediaServerItem, sendRtpItem, platform, evt); + } else { + // 涓嶅湪绾� 鎷夎捣 + notifyStreamOnline(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, + mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); + } + + } else { + // 鍏朵粬骞冲彴鍐呭 + otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, + mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); + } + + } + + /** + * 閫氱煡娴佷笂绾� + */ + private void notifyStreamOnline(RequestEvent evt, 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"); + } else if ("push".equals(gbStream.getStreamType())) { + if (!platform.isStartOfflinePush()) { + responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable"); + return; + } + // 鍙戦�乺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()); + try { + mediaListManager.removedChannelOnlineEventLister(gbStream.getGbId()); + responseAck(evt, Response.REQUEST_TIMEOUT); // 瓒呮椂 + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + }, userSetting.getPlatformPlayTimeout()); + // 娣诲姞鐩戝惉 + int finalPort = port; + Boolean finalTcpActive = tcpActive; + + // 娣诲姞鍦ㄦ湰鏈轰笂绾跨殑閫氱煡 + mediaListManager.addChannelOnlineEventLister(gbStream.getGbId(), (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祫婧愪笉瓒�"); + try { + responseAck(evt, Response.BUSY_HERE); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + return; + } + if (finalTcpActive != null) { + sendRtpItem.setTcpActive(finalTcpActive); + } + sendRtpItem.setPlayType(InviteStreamType.PUSH); + // 鍐欏叆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); + redisCatchStorage.updateSendRTPSever(sendRtpItem); + sendStreamAck(mediaServerItem, sendRtpItem, platform, evt); + } else { + // 鍏朵粬骞冲彴鍐呭 + otherWvpPushStream(evt, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive, + mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); + } + }); + } + } + + /** + * 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴� + */ + private void otherWvpPushStream(RequestEvent evt, 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, null, responseSendItemMsg -> { + SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem(); + if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { + logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�"); + try { + responseAck(evt, Response.BUSY_HERE); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + return; + } + // 鏀跺埌sendItem + if (tcpActive != null) { + sendRtpItem.setTcpActive(tcpActive); + } + sendRtpItem.setPlayType(InviteStreamType.PUSH); + // 鍐欏叆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); + redisCatchStorage.updateSendRTPSever(sendRtpItem); + sendStreamAck(responseSendItemMsg.getMediaServerItem(), sendRtpItem, platform, evt); + }, (wvpResult) -> { + try { + // 閿欒 + if (wvpResult.getCode() == RedisGbPlayMsgListener.ERROR_CODE_OFFLINE) { + // 绂荤嚎 + // 鏌ヨ鏄惁鍦ㄦ湰鏈轰笂绾夸簡 + StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream()); + if (currentStreamPushItem.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); + } + } + } catch (InvalidArgumentException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } catch (SipException e) { + throw new RuntimeException(e); + } - } + try { + responseAck(evt, Response.BUSY_HERE); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + return; + }); + } - } + public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) { - } catch (SipException | InvalidArgumentException | ParseException e) { - e.printStackTrace(); - logger.warn("sdp瑙f瀽閿欒"); - e.printStackTrace(); - } catch (SdpParseException e) { - e.printStackTrace(); - } catch (SdpException e) { - e.printStackTrace(); - } - } + 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("s=Play\r\n"); + content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n"); + content.append("t=0 0\r\n"); + content.append("m=video " + sendRtpItem.getLocalPort() + " RTP/AVP 96\r\n"); + content.append("a=sendonly\r\n"); + content.append("a=rtpmap:96 PS/90000\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=" + sendRtpItem.getSsrc() + "\r\n"); + content.append("f=\r\n"); - public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt){ + try { + responseSdpAck(evt, content.toString(), platform); + } catch (SipException e) { + e.printStackTrace(); + } catch (InvalidArgumentException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + } - 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("s=Play\r\n"); - content.append("c=IN IP4 "+mediaServerItem.getSdpIp()+"\r\n"); - content.append("t=0 0\r\n"); - content.append("m=video "+ sendRtpItem.getLocalPort()+" RTP/AVP 96\r\n"); - content.append("a=sendonly\r\n"); - content.append("a=rtpmap:96 PS/90000\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="+ sendRtpItem.getSsrc() + "\r\n"); - content.append("f=\r\n"); + public void inviteFromDeviceHandle(RequestEvent evt, String requesterId, String channelId1) throws InvalidArgumentException, ParseException, SipException, SdpException { - try { - responseSdpAck(evt, content.toString(), platform); - } catch (SipException e) { - e.printStackTrace(); - } catch (InvalidArgumentException e) { - e.printStackTrace(); - } catch (ParseException e) { - e.printStackTrace(); - } - } + // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛� + Device device = redisCatchStorage.getDevice(requesterId); + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(requesterId, channelId1); + if (audioBroadcastCatch == null) { + logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾紝宸插拷鐣�"); + responseAck(evt, Response.FORBIDDEN); + return; + } + Request request = evt.getRequest(); + if (device != null) { + logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰"); + responseAck(evt, Response.TRYING); - public void inviteFromDeviceHandle(RequestEvent evt, String requesterId) throws InvalidArgumentException, ParseException, SipException, SdpException { + String contentString = new String(request.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).trim(); + } + ssrcIndex = substring.indexOf("f="); + if (ssrcIndex > 0) { + substring = contentString.substring(0, ssrcIndex); + } + SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); - // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛� - Device device = redisCatchStorage.getDevice(requesterId); - Request request = evt.getRequest(); - if (device != null) { - logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰"); - responseAck(evt, Response.TRYING); + // 鑾峰彇鏀寔鐨勬牸寮� + Vector mediaDescriptions = sdp.getMediaDescriptions(true); - String contentString = new String(request.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); - } - ssrcIndex = substring.indexOf("f="); - if (ssrcIndex > 0) { - substring = contentString.substring(0, ssrcIndex); - } - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); + // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96 + int port = -1; + boolean mediaTransmissionTCP = false; + Boolean tcpActive = null; + for (int i = 0; i < mediaDescriptions.size(); i++) { + MediaDescription mediaDescription = (MediaDescription)mediaDescriptions.get(i); + Media media = mediaDescription.getMedia(); - // 鑾峰彇鏀寔鐨勬牸寮� - 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); - Media media = mediaDescription.getMedia(); + Vector mediaFormats = media.getMediaFormats(false); + if (mediaFormats.contains("8")) { + port = media.getMediaPort(); + String protocol = media.getProtocol(); + // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp + if ("TCP/RTP/AVP".equals(protocol)) { + String setup = mediaDescription.getAttribute("setup"); + if (setup != null) { + mediaTransmissionTCP = true; + if ("active".equals(setup)) { + tcpActive = true; + } else if ("passive".equals(setup)) { + tcpActive = false; + } + } + } + break; + } + } + if (port == -1) { + logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415"); + // 鍥炲涓嶆敮鎸佺殑鏍煎紡 + responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415 + return; + } + String addressStr = sdp.getOrigin().getAddress(); + logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", requesterId, addressStr, port, ssrc); - Vector mediaFormats = media.getMediaFormats(false); - if (mediaFormats.contains("8")) { - port = media.getMediaPort(); - String protocol = media.getProtocol(); - // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp - if ("TCP/RTP/AVP".equals(protocol)) { - String setup = mediaDescription.getAttribute("setup"); - if (setup != null) { - mediaTransmissionTCP = true; - if ("active".equals(setup)) { - tcpActive = true; - } else if ("passive".equals(setup)) { - tcpActive = false; - } - } - } - break; - } - } - if (port == -1) { - logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415"); - // 鍥炲涓嶆敮鎸佺殑鏍煎紡 - responseAck(evt, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415 - return; - } - String username = sdp.getOrigin().getUsername(); - String addressStr = sdp.getOrigin().getAddress(); - logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc); + MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device); + if (mediaServerItem == null) { + logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm"); + responseAck(evt, 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(evt, Response.BUSY_HERE); + return; + } + sendRtpItem.setTcp(mediaTransmissionTCP); + if (tcpActive != null) { + sendRtpItem.setTcpActive(tcpActive); + } + String app = "broadcast"; + String stream = device.getDeviceId() + "_" + audioBroadcastCatch.getChannelId(); - } else { - logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�"); - responseAck(evt, Response.BAD_REQUEST); - } - } + 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鐩戝惉绛夊緟璁惧鎺ㄦ祦涓婃潵 + // 娣诲姞璁㈤槄 + JSONObject subscribeKey = new JSONObject(); + subscribeKey.put("app", app); + subscribeKey.put("stream", stream); + subscribeKey.put("regist", true); + subscribeKey.put("schema", "rtmp"); + subscribeKey.put("mediaServerId", mediaServerItem.getId()); + String finalSsrc = ssrc; + // 娴佸凡缁忓瓨鍦ㄦ椂鐩存帴鎺ㄦ祦 +// JSONObject mediaInfo = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream); +// System.out.println(mediaInfo != null); +// System.out.println(mediaInfo); +// if (mediaInfo != null && +// (mediaInfo.getInteger("code") != null && mediaInfo.getInteger("code") == 0 +// && mediaInfo.getJSONArray("data") != null && mediaInfo.getJSONArray("data").size() > 0)) { +// logger.info("鍙戠幇宸茬粡鍦ㄦ帹娴�"); +// JSONArray tracks = mediaInfo.getJSONArray("data").getJSONObject(0).getJSONArray("tracks"); +// Integer codecId = null; +// if (tracks != null && tracks.size() > 0) { +// for (int i = 0; i < tracks.size(); i++) { +// MediaItem.MediaTrack track = JSON.toJavaObject((JSON)tracks.get(i),MediaItem.MediaTrack.class); +// if (track.getCodecType() == 1) { +// codecId = track.getCodecId(); +// break; +// } +// } +// } +// 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 (codecId == null) { +// 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\r\n"); +// }else { +// if (codecId == 4) { +// if (mediaTransmissionTCP) { +// 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 (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\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("a=sendonly\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()); +// try { +// responseSdpAck(evt, content.toString(), parentPlatform); +// Dialog dialog = evt.getDialog(); +// audioBroadcastCatch.setDialog((SIPDialog) dialog); +// audioBroadcastCatch.setRequest((SIPRequest) request); +// audioBroadcastManager.update(audioBroadcastCatch); +// } catch (SipException e) { +// throw new RuntimeException(e); +// } catch (InvalidArgumentException e) { +// throw new RuntimeException(e); +// } catch (ParseException e) { +// throw new RuntimeException(e); +// } +// }else { + // 娴佷笉瀛樺湪鏃剁洃鍚祦涓婄嚎 + // 璁剧疆绛夊緟鎺ㄦ祦鐨勮秴鏃�; 榛樿20s + String waiteStreamTimeoutTaskKey = "waite-stream-" + device.getDeviceId() + audioBroadcastCatch.getChannelId(); + dynamicTask.startDelay(waiteStreamTimeoutTaskKey, ()->{ + logger.info("绛夊緟鎺ㄦ祦瓒呮椂: {}/{}", app, stream); + subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, 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(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey, + (MediaServerItem mediaServerItemInUse, JSONObject json)->{ + logger.info("鏀跺埌璇煶瀵硅鎺ㄦ祦"); + 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(evt, content.toString(), parentPlatform); + Dialog dialog = evt.getDialog(); + audioBroadcastCatch.setDialog((SIPDialog) dialog); + audioBroadcastCatch.setRequest((SIPRequest) request); + audioBroadcastManager.update(audioBroadcastCatch); + } catch (SipException e) { + throw new RuntimeException(e); + } catch (InvalidArgumentException e) { + throw new RuntimeException(e); + } catch (ParseException e) { + throw new RuntimeException(e); + } catch (SdpParseException e) { + throw new RuntimeException(e); + } + }); +// } + 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, 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); + } + } } -- Gitblit v1.8.0