From a01295603af6ef75776bdee328c9df18b1a9a9f2 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期五, 03 十一月 2023 17:32:37 +0800
Subject: [PATCH] 简化配置
---
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 1460 ++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 917 insertions(+), 543 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
old mode 100644
new mode 100755
index 2723da4..a4f3b5e
--- 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,32 +1,37 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
-import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.DynamicTask;
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.VideoStreamSessionManager;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
-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.SIPSender;
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.ZLMMediaListManager;
-import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.service.IMediaServerService;
-import com.genersoft.iot.vmp.service.IPlayService;
+import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
+import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
+import com.genersoft.iot.vmp.media.zlm.dto.*;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+import com.genersoft.iot.vmp.service.*;
+import com.genersoft.iot.vmp.service.bean.ErrorCallback;
+import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
+import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener;
+import com.genersoft.iot.vmp.service.redisMsg.RedisPushStreamResponseListener;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
-import com.genersoft.iot.vmp.utils.SerializeUtils;
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.message.SIPResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -34,13 +39,16 @@
import org.springframework.stereotype.Component;
import javax.sdp.*;
-import javax.sip.*;
-import javax.sip.address.SipURI;
+import javax.sip.InvalidArgumentException;
+import javax.sip.RequestEvent;
+import javax.sip.SipException;
import javax.sip.header.CallIdHeader;
-import javax.sip.message.Request;
import javax.sip.message.Response;
import java.text.ParseException;
import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
import java.util.Vector;
/**
@@ -50,564 +58,930 @@
@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 SIPCommanderFroPlatform cmderFroPlatform;
- @Autowired
- private IVideoManagerStorage storager;
+ @Autowired
+ private IVideoManagerStorage storager;
- @Autowired
- private IRedisCatchStorage redisCatchStorage;
+ @Autowired
+ private IStreamPushService streamPushService;
+ @Autowired
+ private IStreamProxyService streamProxyService;
- @Autowired
- private DynamicTask dynamicTask;
+ @Autowired
+ private IRedisCatchStorage redisCatchStorage;
- @Autowired
- private SIPCommander cmder;
+ @Autowired
+ private IInviteStreamService inviteStreamService;
- @Autowired
- private IPlayService playService;
+ @Autowired
+ private SSRCFactory ssrcFactory;
- @Autowired
- private ISIPCommander commander;
+ @Autowired
+ private DynamicTask dynamicTask;
- @Autowired
- private ZLMRTPServerFactory zlmrtpServerFactory;
+ @Autowired
+ private RedisPushStreamResponseListener redisPushStreamResponseListener;
- @Autowired
- private IMediaServerService mediaServerService;
+ @Autowired
+ private IPlayService playService;
- @Autowired
- private SIPProcessorObserver sipProcessorObserver;
+ @Autowired
+ private SIPSender sipSender;
- @Autowired
- private VideoStreamSessionManager sessionManager;
+ @Autowired
+ private ZLMServerFactory zlmServerFactory;
- @Autowired
- private UserSetting userSetting;
+ @Autowired
+ private IMediaServerService mediaServerService;
- @Autowired
- private ZLMMediaListManager mediaListManager;
+ @Autowired
+ private ZlmHttpHookSubscribe zlmHttpHookSubscribe;
+
+ @Autowired
+ private SIPProcessorObserver sipProcessorObserver;
+
+ @Autowired
+ private UserSetting userSetting;
+
+ @Autowired
+ private ZLMMediaListManager mediaListManager;
- @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 {
+ SIPRequest request = (SIPRequest)evt.getRequest();
+ String channelId = SipUtils.getChannelIdFromRequest(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锛岃姹傞敊璇�
+ try {
+ responseAck(request, Response.BAD_REQUEST);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite BAD_REQUEST: {}", e.getMessage());
+ }
+ return;
+ }
- }
+ // 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
+ ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
+ if (platform == null) {
+ inviteFromDeviceHandle(request, requesterId);
- }
+ } else {
+ // 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
+ DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
+ GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
+ PlatformCatalog catalog = storager.getCatalog(requesterId, channelId);
- } catch (SipException | InvalidArgumentException | ParseException e) {
- e.printStackTrace();
- logger.warn("sdp瑙f瀽閿欒");
- e.printStackTrace();
- } catch (SdpParseException e) {
- e.printStackTrace();
- } catch (SdpException e) {
- e.printStackTrace();
- }
- }
+ MediaServerItem mediaServerItem = null;
+ StreamPushItem streamPushItem = null;
+ StreamProxyItem proxyByAppAndStream =null;
+ // 涓嶆槸閫氶亾鍙兘鏄洿鎾祦
+ if (channel != null && gbStream == null) {
+ // 閫氶亾瀛樺湪锛屽彂100锛孴RYING
+ try {
+ responseAck(request, Response.TRYING);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite TRYING: {}", e.getMessage());
+ }
+ } else if (channel == null && gbStream != null) {
- public void sendStreamAck(MediaServerItem mediaServerItem, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt){
+ 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);
+ try {
+ responseAck(request, Response.GONE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite GONE: {}", e.getMessage());
+ }
+ return;
+ } else {
+ streamPushItem = streamPushService.getPush(gbStream.getApp(), gbStream.getStream());
+ if (streamPushItem != null) {
+ mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId());
+ }
+ if (mediaServerItem == null) {
+ mediaServerItem = mediaServerService.getDefaultMediaServer();
+ }
+ }
+ } 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);
+ try {
+ responseAck(request, Response.GONE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite GONE: {}", e.getMessage());
+ }
+ 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);
+ try {
+ responseAck(request, Response.GONE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite GONE: {}", e.getMessage());
+ }
+ return;
+ }
+ }
+ }
+ try {
+ responseAck(request, Response.CALL_IS_BEING_FORWARDED);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite CALL_IS_BEING_FORWARDED: {}", e.getMessage());
+ }
+ } else if (catalog != null) {
+ try {
+ // 鐩綍涓嶆敮鎸佺偣鎾�
+ responseAck(request, Response.BAD_REQUEST, "catalog channel can not play");
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鐩綍涓嶆敮鎸佺偣鎾�: {}", e.getMessage());
+ }
+ return;
+ } else {
+ logger.info("閫氶亾涓嶅瓨鍦紝杩斿洖404: {}", channelId);
+ try {
+ // 閫氶亾涓嶅瓨鍦紝鍙�404锛岃祫婧愪笉瀛樺湪
+ responseAck(request, Response.NOT_FOUND);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾涓嶅瓨鍦�: {}", e.getMessage());
+ }
+ return;
+ }
+ // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
+ String contentString = new String(request.getRawContent());
- 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");
+ Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
+ SessionDescription sdp = gb28181Sdp.getBaseSdb();
+ String sessionName = sdp.getSessionName().getValue();
- try {
- responseSdpAck(evt, content.toString(), platform);
- } catch (SipException e) {
- e.printStackTrace();
- } catch (InvalidArgumentException e) {
- e.printStackTrace();
- } catch (ParseException e) {
- e.printStackTrace();
- }
- }
+ 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();
- public void inviteFromDeviceHandle(RequestEvent evt, String requesterId) throws InvalidArgumentException, ParseException, SipException, SdpException {
+ 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();
- // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
- Device device = redisCatchStorage.getDevice(requesterId);
- Request request = evt.getRequest();
- if (device != null) {
- logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
- responseAck(evt, Response.TRYING);
+ Vector mediaFormats = media.getMediaFormats(false);
+ if (mediaFormats.contains("96")) {
+ port = media.getMediaPort();
+ //String mediaType = media.getMediaType();
+ String protocol = media.getProtocol();
- 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);
+ // 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
+ if ("TCP/RTP/AVP".equalsIgnoreCase(protocol)) {
+ String setup = mediaDescription.getAttribute("setup");
+ if (setup != null) {
+ mediaTransmissionTCP = true;
+ if ("active".equalsIgnoreCase(setup)) {
+ tcpActive = true;
+ } else if ("passive".equalsIgnoreCase(setup)) {
+ tcpActive = false;
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (port == -1) {
+ logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
+ // 鍥炲涓嶆敮鎸佺殑鏍煎紡
+ try {
+ // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑鏍煎紡: {}", e.getMessage());
+ }
+ return;
+ }
+ String username = sdp.getOrigin().getUsername();
+ String addressStr = sdp.getConnection().getAddress();
- // 鑾峰彇鏀寔鐨勬牸寮�
- 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 username = sdp.getOrigin().getUsername();
- String addressStr = sdp.getOrigin().getAddress();
- logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", 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);
+ try {
+ responseAck(request, Response.SERVER_INTERNAL_ERROR);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈壘鍒拌澶囦俊鎭�: {}", e.getMessage());
+ }
+ return;
+ }
+ mediaServerItem = playService.getNewMediaServerItem(device);
+ if (mediaServerItem == null) {
+ logger.warn("鏈壘鍒板彲鐢ㄧ殑zlm");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite BUSY_HERE: {}", e.getMessage());
+ }
+ return;
+ }
- } else {
- logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
- responseAck(evt, Response.BAD_REQUEST);
- }
- }
+ String ssrc;
+ if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
+ // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+ ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+ }else {
+ ssrc = gb28181Sdp.getSsrc();
+ }
+ String streamTypeStr = null;
+ if (mediaTransmissionTCP) {
+ if (tcpActive) {
+ streamTypeStr = "TCP-ACTIVE";
+ }else {
+ streamTypeStr = "TCP-PASSIVE";
+ }
+ }else {
+ streamTypeStr = "UDP";
+ }
+ logger.info("[涓婄骇Invite] {}, 骞冲彴锛歿}锛� 閫氶亾锛歿}, 鏀舵祦鍦板潃锛歿}:{}锛屾敹娴佹柟寮忥細{}, ssrc锛歿}", sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc);
+ SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+ device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
+
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+ if (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
+ }
+ return;
+ }
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+ sendRtpItem.setPlayType("Play".equalsIgnoreCase(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK);
+
+ Long finalStartTime = startTime;
+ Long finalStopTime = stopTime;
+ ErrorCallback<Object> hookEvent = (code, msg, data) -> {
+ StreamInfo streamInfo = (StreamInfo)data;
+ MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId());
+ logger.info("[涓婄骇Invite]涓嬬骇宸茬粡寮�濮嬫帹娴併�� 鍥炲200OK(SDP)锛� {}/{}", streamInfo.getApp(), streamInfo.getStream());
+ // * 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".equalsIgnoreCase(sessionName)) {
+ content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n");
+ } else {
+ content.append("t=0 0\r\n");
+ }
+ int localPort = sendRtpItem.getLocalPort();
+ if (localPort == 0) {
+ // 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
+ localPort = new Random().nextInt(65535) + 1;
+ }
+ content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+ content.append("a=sendonly\r\n");
+ content.append("a=rtpmap:96 PS/90000\r\n");
+ content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
+ content.append("f=\r\n");
+
+
+ try {
+ // 瓒呮椂鏈敹鍒癆ck搴旇鍥炲bye,褰撳墠绛夊緟鏃堕棿涓�10绉�
+ dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
+ logger.info("Ack 绛夊緟瓒呮椂");
+ mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc());
+ // 鍥炲bye
+ try {
+ cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId());
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+ }
+ }, 60 * 1000);
+ responseSdpAck(request, content.toString(), platform);
+ // tcp涓诲姩妯″紡锛屽洖澶峴dp鍚庡紑鍚洃鍚�
+ if (sendRtpItem.isTcpActive()) {
+ MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ Map<String, Object> param = new HashMap<>(12);
+ param.put("vhost","__defaultVhost__");
+ param.put("app",sendRtpItem.getApp());
+ param.put("stream",sendRtpItem.getStreamId());
+ param.put("ssrc", sendRtpItem.getSsrc());
+ if (!sendRtpItem.isTcpActive()) {
+ param.put("dst_url",sendRtpItem.getIp());
+ param.put("dst_port", sendRtpItem.getPort());
+ }
+ String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
+ param.put("is_udp", is_Udp);
+ param.put("src_port", localPort);
+ param.put("pt", sendRtpItem.getPt());
+ param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
+ param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
+ if (!sendRtpItem.isTcp()) {
+ // 寮�鍚痳tcp淇濇椿
+ param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");
+ }
+ JSONObject startSendRtpStreamResult = zlmServerFactory.startSendRtpStreamForPassive(mediaInfo, param);
+ if (startSendRtpStreamResult != null) {
+ startSendRtpStreamHand(evt, sendRtpItem, null, startSendRtpStreamResult, param, callIdHeader);
+ }
+ }
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍥炲SdpAck", e);
+ }
+ };
+ ErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
+ // 鏈煡閿欒銆傜洿鎺ヨ浆鍙戣澶囩偣鎾殑閿欒
+ try {
+ if (statusCode > 0) {
+ Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
+ sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
+ }
+ } catch (ParseException | SipException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ });
+ sendRtpItem.setApp("rtp");
+ if ("Playback".equalsIgnoreCase(sessionName)) {
+ sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
+ String startTimeStr = DateUtil.urlFormatter.format(start);
+ String endTimeStr = DateUtil.urlFormatter.format(end);
+ String stream = device.getDeviceId() + "_" + channelId + "_" + startTimeStr + "_" + endTimeStr;
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
+ sendRtpItem.setStreamId(ssrcInfo.getStream());
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
+ DateUtil.formatter.format(end),
+ (code, msg, data) -> {
+ if (code == InviteErrorCode.SUCCESS.getCode()){
+ hookEvent.run(code, msg, data);
+ }else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
+ logger.info("[褰曞儚鍥炴斁]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
+ redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
+ errorEvent.run(code, msg, data);
+ }else {
+ errorEvent.run(code, msg, data);
+ }
+ });
+ } else if ("Download".equalsIgnoreCase(sessionName)) {
+ // 鑾峰彇鎸囧畾鐨勪笅杞介�熷害
+ Vector sdpMediaDescriptions = sdp.getMediaDescriptions(true);
+ MediaDescription mediaDescription = null;
+ String downloadSpeed = "1";
+ if (sdpMediaDescriptions.size() > 0) {
+ mediaDescription = (MediaDescription) sdpMediaDescriptions.get(0);
+ }
+ if (mediaDescription != null) {
+ downloadSpeed = mediaDescription.getAttribute("downloadspeed");
+ }
+
+ sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD);
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
+ sendRtpItem.setStreamId(ssrcInfo.getStream());
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
+ DateUtil.formatter.format(end), Integer.parseInt(downloadSpeed),
+ (code, msg, data) -> {
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
+ hookEvent.run(code, msg, data);
+ } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
+ logger.info("[褰曞儚涓嬭浇]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
+ redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
+ errorEvent.run(code, msg, data);
+ } else {
+ errorEvent.run(code, msg, data);
+ }
+ });
+ } else {
+
+ SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> {
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
+ hookEvent.run(code, msg, data);
+ } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
+ logger.info("[涓婄骇鐐规挱]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
+ redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
+ errorEvent.run(code, msg, data);
+ } else {
+ errorEvent.run(code, msg, data);
+ }
+ }));
+ sendRtpItem.setPlayType(InviteStreamType.PLAY);
+ String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
+ sendRtpItem.setStreamId(streamId);
+ sendRtpItem.setSsrc(ssrcInfo.getSsrc());
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+ }
+ } else if (gbStream != null) {
+
+ String ssrc;
+ if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) {
+ // 涓婄骇骞冲彴鐐规挱鏃朵笉浣跨敤涓婄骇骞冲彴鎸囧畾鐨剆src锛屼娇鐢ㄨ嚜瀹氫箟鐨剆src锛屽弬鑰冨浗鏍囨枃妗�-鐐规挱澶栧煙璁惧濯掍綋娴丼SRC澶勭悊鏂瑰紡
+ ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
+ }else {
+ ssrc = gb28181Sdp.getSsrc();
+ }
+
+ if("push".equals(gbStream.getStreamType())) {
+ if (streamPushItem != null && streamPushItem.isPushIng()) {
+ // 鎺ㄦ祦鐘舵��
+ pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ } else {
+ // 鏈帹娴� 鎷夎捣
+ notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+ }else if ("proxy".equals(gbStream.getStreamType())){
+ if (null != proxyByAppAndStream) {
+ if(proxyByAppAndStream.isStatus()){
+ pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }else{
+ //寮�鍚唬鐞嗘媺娴�
+ notifyStreamOnline(evt, request,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+ }
+
+
+ }
+ }
+ }
+ } catch (SdpParseException e) {
+ logger.error("sdp瑙f瀽閿欒", e);
+ } catch (SdpException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ }
+
+ private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform,
+ JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) {
+ if (jsonObject == null) {
+ logger.error("涓嬬骇TCP琚姩鍚姩鐩戝惉澶辫触: 璇锋鏌LM鏈嶅姟");
+ } else if (jsonObject.getInteger("code") == 0) {
+ logger.info("璋冪敤ZLM-TCP琚姩鎺ㄦ祦鎺ュ彛, 缁撴灉锛� {}", jsonObject);
+ logger.info("鍚姩鐩戝惉TCP琚姩鎺ㄦ祦鎴愬姛[ {}/{} ]锛寋}->{}:{}, " ,param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
+ } else {
+ logger.error("鍚姩鐩戝惉TCP琚姩鎺ㄦ祦澶辫触: {}, 鍙傛暟锛歿}",jsonObject.getString("msg"), JSON.toJSONString(param));
+ }
+ }
+
+ /**
+ * 瀹夋帓鎺ㄦ祦
+ */
+ private void pushProxyStream(RequestEvent evt, SIPRequest request, GbStream gbStream, ParentPlatform platform,
+ CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
+ int port, Boolean tcpActive, boolean mediaTransmissionTCP,
+ String channelId, String addressStr, String ssrc, String requesterId) {
+ Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
+ if (streamReady != null && streamReady) {
+ // 鑷钩鍙板唴瀹�
+ SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+ gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
+
+ if (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
+ }
+ return;
+ }
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+ sendRtpItem.setPlayType(InviteStreamType.PUSH);
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+ sendRtpItem.setFromTag(request.getFromTag());
+
+ SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
+ if (response != null) {
+ sendRtpItem.setToTag(response.getToTag());
+ }
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+ }
+
+ }
+ private void pushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+ CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
+ int port, Boolean tcpActive, boolean mediaTransmissionTCP,
+ String channelId, String addressStr, String ssrc, String requesterId) {
+ // 鎺ㄦ祦
+ if (streamPushItem.isSelf()) {
+ Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, gbStream.getApp(), gbStream.getStream());
+ if (streamReady != null && streamReady) {
+ // 鑷钩鍙板唴瀹�
+ SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
+ gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
+
+ if (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
+ }
+ return;
+ }
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+ sendRtpItem.setPlayType(InviteStreamType.PUSH);
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+
+ sendRtpItem.setFromTag(request.getFromTag());
+ SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
+ if (response != null) {
+ sendRtpItem.setToTag(response.getToTag());
+ }
+
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+ } else {
+ // 涓嶅湪绾� 鎷夎捣
+ notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+
+ } else {
+ // 鍏朵粬骞冲彴鍐呭
+ otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+ }
+ /**
+ * 閫氱煡娴佷笂绾�
+ */
+ private void notifyStreamOnline(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+ CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
+ int port, Boolean tcpActive, boolean mediaTransmissionTCP,
+ String channelId, String addressStr, String ssrc, String requesterId) {
+ if ("proxy".equals(gbStream.getStreamType())) {
+ // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
+ logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
+ // 鐩戝惉娴佷笂绾�
+ HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId());
+ zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> {
+ OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
+ logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream());
+ dynamicTask.stop(callIdHeader.getCallId());
+ pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ });
+ dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
+ logger.info("[ app={}, stream={} ] 绛夊緟鎷夋祦浠g悊娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
+ zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
+ }, userSetting.getPlatformPlayTimeout());
+ boolean start = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
+ if (!start) {
+ try {
+ responseAck(request, Response.BUSY_HERE, "channel [" + gbStream.getGbId() + "] offline");
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
+ }
+ zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
+ dynamicTask.stop(callIdHeader.getCallId());
+ }
+
+
+
+ } else if ("push".equals(gbStream.getStreamType())) {
+ if (!platform.isStartOfflinePush()) {
+ // 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
+ try {
+ logger.info("[涓婄骇鐐规挱] 澶辫触锛屾帹娴佽澶囨湭鎺ㄦ祦锛宑hannel: {}, app: {}, stream: {}", gbStream.getGbId(), gbStream.getApp(), gbStream.getStream());
+ responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing");
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
+ }
+ return;
+ }
+ // 鍙戦�乺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.getApp(), gbStream.getStream());
+ responseAck(request, Response.REQUEST_TIMEOUT); // 瓒呮椂
+ } catch (SipException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (InvalidArgumentException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (ParseException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ }, userSetting.getPlatformPlayTimeout());
+ // 娣诲姞鐩戝惉
+ int finalPort = port;
+ Boolean finalTcpActive = tcpActive;
+
+ // 娣诲姞鍦ㄦ湰鏈轰笂绾跨殑閫氱煡
+ mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
+ dynamicTask.stop(callIdHeader.getCallId());
+ if (serverId.equals(userSetting.getServerId())) {
+ SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
+ app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
+
+ if (sendRtpItem == null) {
+ logger.warn("涓婄骇鐐规椂鍒涘缓sendRTPItem澶辫触锛屽彲鑳芥槸鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (InvalidArgumentException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (ParseException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ return;
+ }
+ if (finalTcpActive != null) {
+ sendRtpItem.setTcpActive(finalTcpActive);
+ }
+ sendRtpItem.setPlayType(InviteStreamType.PUSH);
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+
+ sendRtpItem.setFromTag(request.getFromTag());
+ SIPResponse response = sendStreamAck(mediaServerItem, request, sendRtpItem, platform, evt);
+ if (response != null) {
+ sendRtpItem.setToTag(response.getToTag());
+ }
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ } else {
+ // 鍏朵粬骞冲彴鍐呭
+ otherWvpPushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+ });
+
+ // 娣诲姞鍥炲鐨勬嫆缁濇垨鑰呴敊璇殑閫氱煡
+ redisPushStreamResponseListener.addEvent(gbStream.getApp(), gbStream.getStream(), response -> {
+ if (response.getCode() != 0) {
+ dynamicTask.stop(callIdHeader.getCallId());
+ mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
+ try {
+ responseAck(request, Response.TEMPORARILY_UNAVAILABLE, response.getMsg());
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鐐规挱鍥炲: {}", e.getMessage());
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * 鏉ヨ嚜鍏朵粬wvp鐨勬帹娴�
+ */
+ private void otherWvpPushStream(RequestEvent evt, SIPRequest request, GbStream gbStream, StreamPushItem streamPushItem, ParentPlatform platform,
+ CallIdHeader callIdHeader, MediaServerItem mediaServerItem,
+ int port, Boolean tcpActive, boolean mediaTransmissionTCP,
+ String channelId, String addressStr, String ssrc, String requesterId) {
+ logger.info("[绾ц仈鐐规挱]鐩存挱娴佹潵鑷叾浠栧钩鍙帮紝鍙戦�乺edis娑堟伅");
+ // 鍙戦�乺edis娑堟伅
+ redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(),
+ streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId,
+ channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> {
+ SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem();
+ if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (InvalidArgumentException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (ParseException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ return;
+ }
+ // 鏀跺埌sendItem
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+ sendRtpItem.setPlayType(InviteStreamType.PUSH);
+ // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+
+ sendRtpItem.setFromTag(request.getFromTag());
+ SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request,sendRtpItem, platform, evt);
+ if (response != null) {
+ sendRtpItem.setToTag(response.getToTag());
+ }
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ }, (wvpResult) -> {
+
+ // 閿欒
+ if (wvpResult.getCode() == RedisGbPlayMsgListener.ERROR_CODE_OFFLINE) {
+ // 绂荤嚎
+ // 鏌ヨ鏄惁鍦ㄦ湰鏈轰笂绾夸簡
+ StreamPushItem currentStreamPushItem = streamPushService.getPush(streamPushItem.getApp(), streamPushItem.getStream());
+ if (currentStreamPushItem.isPushIng()) {
+ // 鍦ㄧ嚎鐘舵��
+ pushStream(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+
+ } else {
+ // 涓嶅湪绾� 鎷夎捣
+ notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
+ }
+ }
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (InvalidArgumentException | ParseException | SipException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鐐规挱鍥炲 BUSY_HERE: {}", e.getMessage());
+ }
+ });
+ }
+
+ public SIPResponse sendStreamAck(MediaServerItem mediaServerItem, SIPRequest request, SendRtpItem sendRtpItem, ParentPlatform platform, RequestEvent evt) {
+
+ 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");
+ // 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
+ int localPort = sendRtpItem.getLocalPort();
+ if(localPort == 0)
+ {
+ localPort = new Random().nextInt(65535) + 1;
+ }
+ content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+ content.append("a=sendonly\r\n");
+ content.append("a=rtpmap:96 PS/90000\r\n");
+ 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");
+
+ try {
+ return responseSdpAck(request, content.toString(), platform);
+ } catch (SipException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (InvalidArgumentException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ } catch (ParseException e) {
+ logger.error("鏈鐞嗙殑寮傚父 ", e);
+ }
+ return null;
+ }
+
+ public void inviteFromDeviceHandle(SIPRequest request, String requesterId) {
+
+ // 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
+ Device device = redisCatchStorage.getDevice(requesterId);
+ if (device != null) {
+ logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
+ try {
+ responseAck(request, Response.TRYING);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite BAD_REQUEST: {}", e.getMessage());
+ }
+ String contentString = new String(request.getRawContent());
+ // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
+ String ssrc = "0000000404";
+
+ try {
+ Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
+ SessionDescription sdp = gb28181Sdp.getBaseSdb();
+ // 鑾峰彇鏀寔鐨勬牸寮�
+ Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+ // 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
+ int port = -1;
+ //boolean recvonly = false;
+ boolean mediaTransmissionTCP = false;
+ Boolean tcpActive = null;
+ for (int i = 0; i < mediaDescriptions.size(); i++) {
+ 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");
+ // 鍥炲涓嶆敮鎸佺殑鏍煎紡
+ try {
+ responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415锛� {}", e.getMessage());
+ }
+ return;
+ }
+ String username = sdp.getOrigin().getUsername();
+ String addressStr = sdp.getConnection().getAddress();
+ logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+ } catch (SdpException e) {
+ logger.error("[SDP瑙f瀽寮傚父]", e);
+ }
+
+
+
+ } else {
+ logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
+ try {
+ responseAck(request, Response.BAD_REQUEST);; // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹傦紝 {}", e.getMessage());
+ }
+ }
+ }
}
--
Gitblit v1.8.0