From 62f716be9cd1cee2a5fba566db3fcd43bd9fc4cc Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 03 四月 2024 15:04:33 +0800
Subject: [PATCH] 添加idea logo
---
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java | 451 ++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 341 insertions(+), 110 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 a0f43e7..3205498
--- 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,13 +1,20 @@
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.genersoft.iot.vmp.common.InviteSessionType;
import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.common.VideoManagerConstants;
import com.genersoft.iot.vmp.conf.DynamicTask;
+import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*;
+import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
+import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
@@ -16,10 +23,7 @@
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.IMediaServerService;
-import com.genersoft.iot.vmp.service.IPlayService;
-import com.genersoft.iot.vmp.service.IStreamProxyService;
-import com.genersoft.iot.vmp.service.IStreamPushService;
+import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
@@ -31,8 +35,10 @@
import com.genersoft.iot.vmp.utils.DateUtil;
import gov.nist.javax.sdp.TimeDescriptionImpl;
import gov.nist.javax.sdp.fields.TimeField;
+import gov.nist.javax.sdp.fields.URIField;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -47,6 +53,8 @@
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;
@@ -62,18 +70,22 @@
private final String method = "INVITE";
@Autowired
- private SIPCommanderFroPlatform cmderFroPlatform;
+ private ISIPCommanderForPlatform cmderFroPlatform;
@Autowired
private IVideoManagerStorage storager;
@Autowired
private IStreamPushService streamPushService;
+
@Autowired
private IStreamProxyService streamProxyService;
@Autowired
private IRedisCatchStorage redisCatchStorage;
+
+ @Autowired
+ private IInviteStreamService inviteStreamService;
@Autowired
private SSRCFactory ssrcFactory;
@@ -89,6 +101,9 @@
@Autowired
private SIPSender sipSender;
+
+ @Autowired
+ private AudioBroadcastManager audioBroadcastManager;
@Autowired
private ZLMServerFactory zlmServerFactory;
@@ -108,9 +123,15 @@
@Autowired
private ZLMMediaListManager mediaListManager;
+ @Autowired
+ private SipConfig config;
+
@Autowired
private RedisGbPlayMsgListener redisGbPlayMsgListener;
+
+ @Autowired
+ private VideoStreamSessionManager streamSession;
@Override
@@ -129,11 +150,24 @@
// Invite Request娑堟伅瀹炵幇锛屾娑堟伅涓�鑸负绾ц仈娑堟伅锛屼笂绾х粰涓嬬骇鍙戦�佽姹傝棰戞寚浠�
try {
SIPRequest request = (SIPRequest)evt.getRequest();
- String channelId = SipUtils.getChannelIdFromRequest(request);
+ String channelIdFromSub = SipUtils.getChannelIdFromRequest(request);
+
+ // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
+ String contentString = new String(request.getRawContent());
+ Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
+ SessionDescription sdp = gb28181Sdp.getBaseSdb();
+ String sessionName = sdp.getSessionName().getValue();
+ String channelIdFromSdp = null;
+ if(StringUtils.equalsIgnoreCase("Playback", sessionName)){
+ URIField uriField = (URIField)sdp.getURI();
+ channelIdFromSdp = uriField.getURI().split(":")[0];
+ }
+ final String channelId = StringUtils.isNotBlank(channelIdFromSdp) ? channelIdFromSdp : channelIdFromSub;
+
String requesterId = SipUtils.getUserIdFromFromHeader(request);
CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
if (requesterId == null || channelId == null) {
- logger.info("鏃犳硶浠嶧romHeader鐨凙ddress涓幏鍙栧埌骞冲彴id锛岃繑鍥�400");
+ logger.info("鏃犳硶浠庤姹備腑鑾峰彇鍒板钩鍙癷d锛岃繑鍥�400");
// 鍙傛暟涓嶅叏锛� 鍙�400锛岃姹傞敊璇�
try {
responseAck(request, Response.BAD_REQUEST);
@@ -143,21 +177,23 @@
return;
}
+ logger.info("[INVITE] requesterId: {}, callId: {}, 鏉ヨ嚜锛歿}锛歿}",
+ requesterId, callIdHeader.getCallId(), request.getRemoteAddress(), request.getRemotePort());
// 鏌ヨ璇锋眰鏄惁鏉ヨ嚜涓婄骇骞冲彴\璁惧
ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
if (platform == null) {
- inviteFromDeviceHandle(request, requesterId);
+ inviteFromDeviceHandle(request, requesterId, channelId);
} else {
// 鏌ヨ骞冲彴涓嬫槸鍚︽湁璇ラ�氶亾
DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId);
GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId);
- PlatformCatalog catalog = storager.getCatalog(channelId);
+ PlatformCatalog catalog = storager.getCatalog(requesterId, channelId);
MediaServerItem mediaServerItem = null;
StreamPushItem streamPushItem = null;
- StreamProxyItem proxyByAppAndStream =null;
+ StreamProxyItem proxyByAppAndStream = null;
// 涓嶆槸閫氶亾鍙兘鏄洿鎾祦
if (channel != null && gbStream == null) {
// 閫氶亾瀛樺湪锛屽彂100锛孴RYING
@@ -200,7 +236,7 @@
}
return;
}
- }else if("proxy".equals(gbStream.getStreamType())){
+ } else if ("proxy".equals(gbStream.getStreamType())) {
proxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(gbStream.getApp(), gbStream.getStream());
if (proxyByAppAndStream == null) {
logger.info("[ app={}, stream={} ]鎵句笉鍒皕lm {}锛岃繑鍥�410", gbStream.getApp(), gbStream.getStream(), mediaServerId);
@@ -236,12 +272,6 @@
}
return;
}
- // 瑙f瀽sdp娑堟伅, 浣跨敤jainsip 鑷甫鐨剆dp瑙f瀽鏂瑰紡
- String contentString = new String(request.getRawContent());
-
- Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
- SessionDescription sdp = gb28181Sdp.getBaseSdb();
- String sessionName = sdp.getSessionName().getValue();
Long startTime = null;
Long stopTime = null;
@@ -338,10 +368,10 @@
if (mediaTransmissionTCP) {
if (tcpActive) {
streamTypeStr = "TCP-ACTIVE";
- }else {
+ } else {
streamTypeStr = "TCP-PASSIVE";
}
- }else {
+ } else {
streamTypeStr = "UDP";
}
logger.info("[涓婄骇Invite] {}, 骞冲彴锛歿}锛� 閫氶亾锛歿}, 鏀舵祦鍦板潃锛歿}:{}锛屾敹娴佹柟寮忥細{}, ssrc锛歿}", sessionName, username, channelId, addressStr, port, streamTypeStr, ssrc);
@@ -390,11 +420,21 @@
// 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
localPort = new Random().nextInt(65535) + 1;
}
- content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+ if (sendRtpItem.isTcp()) {
+ content.append("m=video " + localPort + " TCP/RTP/AVP 96\r\n");
+ if (!sendRtpItem.isTcpActive()) {
+ content.append("a=setup:active\r\n");
+ } else {
+ content.append("a=setup:passive\r\n");
+ }
+ }else {
+ content.append("m=video " + localPort + " RTP/AVP 96\r\n");
+ }
content.append("a=sendonly\r\n");
content.append("a=rtpmap:96 PS/90000\r\n");
content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
content.append("f=\r\n");
+
try {
// 瓒呮椂鏈敹鍒癆ck搴旇鍥炲bye,褰撳墠绛夊緟鏃堕棿涓�10绉�
@@ -409,7 +449,33 @@
}
}, 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.getStream());
+ 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.startSendRtpPassive(mediaInfo, param);
+ if (startSendRtpStreamResult != null) {
+ startSendRtpStreamHand(evt, sendRtpItem, null, startSendRtpStreamResult, param, callIdHeader);
+ }
+ }
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍥炲SdpAck", e);
}
@@ -421,81 +487,79 @@
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
}
- } catch (ParseException | SipException e) {
+ } catch (ParseException | SipException e) {
logger.error("鏈鐞嗙殑寮傚父 ", e);
}
});
sendRtpItem.setApp("rtp");
if ("Playback".equalsIgnoreCase(sessionName)) {
sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
- sendRtpItem.setStreamId(ssrcInfo.getStream());
+ 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, false, device.getStreamModeForParam());
+ sendRtpItem.setStream(stream);
// 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
redisCatchStorage.updateSendRTPSever(sendRtpItem);
playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
DateUtil.formatter.format(end),
(code, msg, data) -> {
- if (code == InviteErrorCode.SUCCESS.getCode()){
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
hookEvent.run(code, msg, data);
- }else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
+ } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
logger.info("[褰曞儚鍥炴斁]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
errorEvent.run(code, msg, data);
- }else {
+ } else {
errorEvent.run(code, msg, data);
}
});
- }else if ("Download".equalsIgnoreCase(sessionName)) {
+ } 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);
+ 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());
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam());
+ sendRtpItem.setStream(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()){
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
hookEvent.run(code, msg, data);
- }else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
+ } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
logger.info("[褰曞儚涓嬭浇]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
errorEvent.run(code, msg, data);
- }else {
+ } else {
errorEvent.run(code, msg, data);
}
});
- }else {
-
+ } else {
+ sendRtpItem.setPlayType(InviteStreamType.PLAY);
+ String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
+ sendRtpItem.setStream(streamId);
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> {
- if (code == InviteErrorCode.SUCCESS.getCode()){
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
hookEvent.run(code, msg, data);
- }else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
+ } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) {
logger.info("[涓婄骇鐐规挱]瓒呮椂, 鐢ㄦ埛锛歿}锛� 閫氶亾锛歿}", username, channelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
errorEvent.run(code, msg, data);
- }else {
+ } else {
errorEvent.run(code, msg, data);
}
}));
- sendRtpItem.setPlayType(InviteStreamType.PLAY);
- String streamId = null;
- if (mediaServerItem.isRtpEnable()) {
- streamId = String.format("%s_%s", device.getDeviceId(), channelId);
- }else {
- streamId = String.format("%08x", Integer.parseInt(ssrcInfo.getSsrc())).toUpperCase();
- }
- sendRtpItem.setStreamId(streamId);
sendRtpItem.setSsrc(ssrcInfo.getSsrc());
redisCatchStorage.updateSendRTPSever(sendRtpItem);
@@ -510,24 +574,24 @@
ssrc = gb28181Sdp.getSsrc();
}
- if("push".equals(gbStream.getStreamType())) {
+ 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,
+ notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
}
- }else if ("proxy".equals(gbStream.getStreamType())){
+ } else if ("proxy".equals(gbStream.getStreamType())) {
if (null != proxyByAppAndStream) {
- if(proxyByAppAndStream.isStatus()){
- pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ if (proxyByAppAndStream.isStatus()) {
+ pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
- }else{
+ } else {
//寮�鍚唬鐞嗘媺娴�
- notifyStreamOnline(evt, request,gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ notifyStreamOnline(evt, request, gbStream, null, platform, callIdHeader, mediaServerItem, port, tcpActive,
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
}
}
@@ -540,6 +604,18 @@
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));
}
}
@@ -556,33 +632,34 @@
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 (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
}
- if (tcpActive != null) {
- sendRtpItem.setTcpActive(tcpActive);
- }
- sendRtpItem.setPlayType(InviteStreamType.PUSH);
- // 鍐欏叆redis锛� 瓒呮椂鏃跺洖澶�
- sendRtpItem.setStatus(1);
- sendRtpItem.setCallId(callIdHeader.getCallId());
- sendRtpItem.setFromTag(request.getFromTag());
+ 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);
+ 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,
@@ -617,12 +694,11 @@
if (response != null) {
sendRtpItem.setToTag(response.getToTag());
}
-
redisCatchStorage.updateSendRTPSever(sendRtpItem);
} else {
// 涓嶅湪绾� 鎷夎捣
- notifyStreamOnline(evt, request,gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ notifyStreamOnline(evt, request, gbStream, streamPushItem, platform, callIdHeader, mediaServerItem, port, tcpActive,
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
}
@@ -632,6 +708,7 @@
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
}
}
+
/**
* 閫氱煡娴佷笂绾�
*/
@@ -648,7 +725,7 @@
OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream());
dynamicTask.stop(callIdHeader.getCallId());
- pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
+ pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
});
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
@@ -665,9 +742,6 @@
zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
dynamicTask.stop(callIdHeader.getCallId());
}
-
-
-
} else if ("push".equals(gbStream.getStreamType())) {
if (!platform.isStartOfflinePush()) {
// 骞冲彴璁剧疆涓叧闂簡鎷夎捣绂荤嚎鐨勬帹娴佸垯鐩存帴鍥炲
@@ -690,13 +764,10 @@
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
logger.info("[ app={}, stream={} ] 绛夊緟璁惧寮�濮嬫帹娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
try {
+ redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream());
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) {
+ } catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("鏈鐞嗙殑寮傚父 ", e);
}
}, userSetting.getPlatformPlayTimeout());
@@ -707,6 +778,7 @@
// 娣诲姞鍦ㄦ湰鏈轰笂绾跨殑閫氱煡
mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
dynamicTask.stop(callIdHeader.getCallId());
+ redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream());
if (serverId.equals(userSetting.getServerId())) {
SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
@@ -771,7 +843,7 @@
// 鍙戦�乺edis娑堟伅
redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(),
streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId,
- channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> {
+ channelId, mediaTransmissionTCP, platform.isRtcp(),platform.getName(), responseSendItemMsg -> {
SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem();
if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
@@ -796,7 +868,7 @@
sendRtpItem.setCallId(callIdHeader.getCallId());
sendRtpItem.setFromTag(request.getFromTag());
- SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request,sendRtpItem, platform, evt);
+ SIPResponse response = sendStreamAck(responseSendItemMsg.getMediaServerItem(), request, sendRtpItem, platform, evt);
if (response != null) {
sendRtpItem.setToTag(response.getToTag());
}
@@ -837,8 +909,7 @@
content.append("t=0 0\r\n");
// 闈炰弗鏍兼ā寮忕鍙d笉缁熶竴, 澧炲姞鍏煎鎬э紝淇敼涓轰竴涓笉涓�0鐨勭鍙�
int localPort = sendRtpItem.getLocalPort();
- if(localPort == 0)
- {
+ if (localPort == 0) {
localPort = new Random().nextInt(65535) + 1;
}
content.append("m=video " + localPort + " RTP/AVP 96\r\n");
@@ -857,39 +928,78 @@
try {
return responseSdpAck(request, content.toString(), platform);
- } catch (SipException e) {
- logger.error("鏈鐞嗙殑寮傚父 ", e);
- } catch (InvalidArgumentException e) {
- logger.error("鏈鐞嗙殑寮傚父 ", e);
- } catch (ParseException e) {
+ } catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("鏈鐞嗙殑寮傚父 ", e);
}
return null;
}
- public void inviteFromDeviceHandle(SIPRequest request, String requesterId) {
+ public void inviteFromDeviceHandle(SIPRequest request, String requesterId, String channelId) {
+
+ String realChannelId = null;
// 闈炰笂绾у钩鍙拌姹傦紝鏌ヨ鏄惁璁惧璇锋眰锛堥�氬父涓烘帴鏀惰闊冲箍鎾殑璁惧锛�
Device device = redisCatchStorage.getDevice(requesterId);
+ // 鍒ゆ柇requesterId鏄澶囪繕鏄�氶亾
+ if (device == null) {
+ device = storager.queryVideoDeviceByChannelId(requesterId);
+ realChannelId = requesterId;
+ }else {
+ realChannelId = channelId;
+ }
+ if (device == null) {
+ // 妫�鏌hannelID鏄惁鍙敤
+ device = redisCatchStorage.getDevice(channelId);
+ if (device == null) {
+ device = storager.queryVideoDeviceByChannelId(channelId);
+ realChannelId = channelId;
+ }
+ }
+
+ if (device == null) {
+ logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰锛屾棤娉曚粠璇锋眰淇℃伅涓‘瀹氭墍灞炶澶囷紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
+ try {
+ responseAck(request, Response.FORBIDDEN);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鏉ヨ嚜璁惧鐨処nvite璇锋眰锛屾棤娉曚粠璇锋眰淇℃伅涓‘瀹氭墍灞炶澶� FORBIDDEN: {}", e.getMessage());
+ }
+ return;
+ }
+
+ AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), realChannelId);
+ if (broadcastCatch == null) {
+ logger.warn("鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾紝宸插拷鐣ワ紝requesterId锛� {}/{}", requesterId, channelId);
+ try {
+ responseAck(request, Response.FORBIDDEN);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鏉ヨ嚜璁惧鐨処nvite璇锋眰闈炶闊冲箍鎾� FORBIDDEN: {}", e.getMessage());
+ }
+ return;
+ }
if (device != null) {
logger.info("鏀跺埌璁惧" + requesterId + "鐨勮闊冲箍鎾璉nvite璇锋眰");
+ String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId();
+ if (!SipUtils.isFrontEnd(device.getDeviceId())) {
+ key += broadcastCatch.getChannelId();
+ }
+ dynamicTask.stop(key);
try {
responseAck(request, Response.TRYING);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 invite BAD_REQUEST: {}", e.getMessage());
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+ return;
}
String contentString = new String(request.getRawContent());
- // jainSip涓嶆敮鎸亂=瀛楁锛� 绉婚櫎绉婚櫎浠ヨВ鏋愩��
- String ssrc = "0000000404";
try {
Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
SessionDescription sdp = gb28181Sdp.getBaseSdb();
// 鑾峰彇鏀寔鐨勬牸寮�
Vector mediaDescriptions = sdp.getMediaDescriptions(true);
+
// 鏌ョ湅鏄惁鏀寔PS 璐熻浇96
int port = -1;
- //boolean recvonly = false;
boolean mediaTransmissionTCP = false;
Boolean tcpActive = null;
for (int i = 0; i < mediaDescriptions.size(); i++) {
@@ -897,7 +1007,7 @@
Media media = mediaDescription.getMedia();
Vector mediaFormats = media.getMediaFormats(false);
- if (mediaFormats.contains("8")) {
+// if (mediaFormats.contains("8")) {
port = media.getMediaPort();
String protocol = media.getProtocol();
// 鍖哄垎TCP鍙戞祦杩樻槸udp锛� 褰撳墠榛樿udp
@@ -913,7 +1023,7 @@
}
}
break;
- }
+// }
}
if (port == -1) {
logger.info("涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415");
@@ -921,26 +1031,147 @@
try {
responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
} catch (SipException | InvalidArgumentException | ParseException e) {
- logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑濯掍綋鏍煎紡锛岃繑鍥�415锛� {}", e.getMessage());
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 涓嶆敮鎸佺殑濯掍綋鏍煎紡: {}", e.getMessage());
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+ return;
}
return;
}
- String username = sdp.getOrigin().getUsername();
- String addressStr = sdp.getConnection().getAddress();
- logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}", username, addressStr, port, ssrc);
+ String addressStr = sdp.getOrigin().getAddress();
+ logger.info("璁惧{}璇锋眰璇煶娴侊紝鍦板潃锛歿}:{}锛宻src锛歿}, {}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
+ mediaTransmissionTCP ? (tcpActive ? "TCP涓诲姩" : "TCP琚姩") : "UDP");
+
+ MediaServerItem mediaServerItem = broadcastCatch.getMediaServerItem();
+ if (mediaServerItem == null) {
+ logger.warn("鏈壘鍒拌闊冲枈璇濅娇鐢ㄧ殑zlm");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈壘鍒板彲鐢ㄧ殑zlm: {}", e.getMessage());
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+ }
+ return;
+ }
+ logger.info("璁惧{}璇锋眰璇煶娴侊紝 鏀舵祦鍦板潃锛歿}:{}锛宻src锛歿}, {}, 瀵硅鏂瑰紡锛歿}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
+ mediaTransmissionTCP ? (tcpActive ? "TCP涓诲姩" : "TCP琚姩") : "UDP", sdp.getSessionName().getValue());
+ CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
+
+ SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, gb28181Sdp.getSsrc(), requesterId,
+ device.getDeviceId(), broadcastCatch.getChannelId(),
+ mediaTransmissionTCP, false);
+
+ if (sendRtpItem == null) {
+ logger.warn("鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�");
+ try {
+ responseAck(request, Response.BUSY_HERE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 invite 鏈嶅姟鍣ㄧ鍙h祫婧愪笉瓒�: {}", e.getMessage());
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+ return;
+ }
+ return;
+ }
+
+
+ sendRtpItem.setPlayType(InviteStreamType.BROADCAST);
+ sendRtpItem.setCallId(callIdHeader.getCallId());
+ sendRtpItem.setPlatformId(requesterId);
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setApp(broadcastCatch.getApp());
+ sendRtpItem.setStream(broadcastCatch.getStream());
+ sendRtpItem.setPt(8);
+ sendRtpItem.setUsePs(false);
+ sendRtpItem.setRtcp(false);
+ sendRtpItem.setOnlyAudio(true);
+ sendRtpItem.setTcp(mediaTransmissionTCP);
+ if (tcpActive != null) {
+ sendRtpItem.setTcpActive(tcpActive);
+ }
+
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+ Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream());
+ if (streamReady) {
+ sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, gb28181Sdp.getSsrc());
+ } else {
+ logger.warn("[璇煶閫氳瘽]锛� 鏈彂鐜板緟鎺ㄩ�佺殑娴�,app={},stream={}", broadcastCatch.getApp(), broadcastCatch.getStream());
+ try {
+ responseAck(request, Response.GONE);
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 璇煶閫氳瘽 鍥炲410澶辫触锛� {}", e.getMessage());
+ return;
+ }
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
+ }
} catch (SdpException e) {
logger.error("[SDP瑙f瀽寮傚父]", e);
+ playService.stopAudioBroadcast(device.getDeviceId(), broadcastCatch.getChannelId());
}
-
-
-
} else {
logger.warn("鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹�");
try {
- responseAck(request, Response.BAD_REQUEST);; // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
+ responseAck(request, Response.BAD_REQUEST);
+ ; // 涓嶆敮鎸佺殑鏍煎紡锛屽彂415
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 invite 鏉ヨ嚜鏃犳晥璁惧/骞冲彴鐨勮姹傦紝 {}", e.getMessage());
}
}
}
+
+ SIPResponse sendOk(Device device, SendRtpItem sendRtpItem, SessionDescription sdp, SIPRequest request, MediaServerItem mediaServerItem, boolean mediaTransmissionTCP, String ssrc) {
+ SIPResponse sipResponse = null;
+ try {
+ sendRtpItem.setStatus(2);
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+ StringBuffer content = new StringBuffer(200);
+ content.append("v=0\r\n");
+ content.append("o=" + config.getId() + " " + sdp.getOrigin().getSessionId() + " " + sdp.getOrigin().getSessionVersion() + " IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+ content.append("s=Play\r\n");
+ content.append("c=IN IP4 " + mediaServerItem.getSdpIp() + "\r\n");
+ content.append("t=0 0\r\n");
+
+ if (mediaTransmissionTCP) {
+ content.append("m=audio " + sendRtpItem.getLocalPort() + " TCP/RTP/AVP 8\r\n");
+ } else {
+ content.append("m=audio " + sendRtpItem.getLocalPort() + " RTP/AVP 8\r\n");
+ }
+
+ content.append("a=rtpmap:8 PCMA/8000/1\r\n");
+
+ content.append("a=sendonly\r\n");
+ if (sendRtpItem.isTcp()) {
+ content.append("a=connection:new\r\n");
+ if (!sendRtpItem.isTcpActive()) {
+ content.append("a=setup:active\r\n");
+ } else {
+ content.append("a=setup:passive\r\n");
+ }
+ }
+ content.append("y=" + ssrc + "\r\n");
+ content.append("f=v/////a/1/8/1\r\n");
+
+ ParentPlatform parentPlatform = new ParentPlatform();
+ parentPlatform.setServerIP(device.getIp());
+ parentPlatform.setServerPort(device.getPort());
+ parentPlatform.setServerGBId(device.getDeviceId());
+
+ sipResponse = responseSdpAck(request, content.toString(), parentPlatform);
+
+ AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), sendRtpItem.getChannelId());
+
+ audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.Ok);
+ audioBroadcastCatch.setSipTransactionInfoByRequset(sipResponse);
+ audioBroadcastManager.update(audioBroadcastCatch);
+ streamSession.put(device.getDeviceId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), sendRtpItem.getStream(), sendRtpItem.getSsrc(), sendRtpItem.getMediaServerId(), sipResponse, InviteSessionType.BROADCAST);
+ // 寮�鍚彂娴侊紝澶у崕鍦ㄦ敹鍒�200OK鍚庡氨浼氬紑濮嬪缓绔嬭繛鎺�
+ if (!device.isBroadcastPushAfterAck()) {
+ logger.info("[璇煶鍠婅瘽] 鍥炲200OK鍚庡彂鐜� BroadcastPushAfterAck涓篎alse锛岀幇鍦ㄥ紑濮嬫帹娴�");
+ playService.startPushStream(sendRtpItem, sipResponse, parentPlatform, request.getCallIdHeader());
+ }
+
+ } catch (SipException | InvalidArgumentException | ParseException | SdpParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 璇煶鍠婅瘽 鍥炲200OK锛圫DP锛�: {}", e.getMessage());
+ }
+ return sipResponse;
+ }
}
--
Gitblit v1.8.0