|
@@ -241,21 +241,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
// 解析sdp消息, 使用jainsip 自带的sdp解析方式
|
|
// 解析sdp消息, 使用jainsip 自带的sdp解析方式
|
|
|
String contentString = new String(request.getRawContent());
|
|
String contentString = new String(request.getRawContent());
|
|
|
|
|
|
|
|
- // jainSip不支持y=字段, 移除以解析。
|
|
|
|
|
- int ssrcIndex = contentString.indexOf("y=");
|
|
|
|
|
- // 检查是否有y字段
|
|
|
|
|
- String ssrcDefault = "0000000000";
|
|
|
|
|
- String ssrc;
|
|
|
|
|
- SessionDescription sdp;
|
|
|
|
|
- if (ssrcIndex >= 0) {
|
|
|
|
|
- //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段
|
|
|
|
|
- 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);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
|
|
|
|
|
+ SessionDescription sdp = gb28181Sdp.getBaseSdb();
|
|
|
String sessionName = sdp.getSessionName().getValue();
|
|
String sessionName = sdp.getSessionName().getValue();
|
|
|
|
|
|
|
|
Long startTime = null;
|
|
Long startTime = null;
|
|
@@ -317,7 +304,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
String username = sdp.getOrigin().getUsername();
|
|
String username = sdp.getOrigin().getUsername();
|
|
|
String addressStr = sdp.getConnection().getAddress();
|
|
String addressStr = sdp.getConnection().getAddress();
|
|
|
|
|
|
|
|
- logger.info("[上级点播]用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc);
|
|
|
|
|
|
|
+
|
|
|
Device device = null;
|
|
Device device = null;
|
|
|
// 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标
|
|
// 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标
|
|
|
if (channel != null) {
|
|
if (channel != null) {
|
|
@@ -341,8 +328,30 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
}
|
|
}
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ String ssrc;
|
|
|
|
|
+ if (gb28181Sdp.getSsrc() == null) {
|
|
|
|
|
+ // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
|
|
|
|
|
+ ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
|
|
|
|
|
+ logger.warn("[上级Invite] {} 平台:{}, 通道:{}, 缺少 ssrc,补充为: {}", sessionName, username, channelId, ssrc);
|
|
|
|
|
+ }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 = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
|
- device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
|
|
|
|
|
|
|
+ device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp(), ssrcFromCallback -> {
|
|
|
|
|
+ return redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, null, callIdHeader.getCallId()) != null;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
if (tcpActive != null) {
|
|
if (tcpActive != null) {
|
|
|
sendRtpItem.setTcpActive(tcpActive);
|
|
sendRtpItem.setTcpActive(tcpActive);
|
|
@@ -469,7 +478,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
|
|
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
|
|
|
logger.info(JSONObject.toJSONString(ssrcInfo));
|
|
logger.info(JSONObject.toJSONString(ssrcInfo));
|
|
|
sendRtpItem.setStreamId(ssrcInfo.getStream());
|
|
sendRtpItem.setStreamId(ssrcInfo.getStream());
|
|
|
- sendRtpItem.setSsrc(ssrc.equals(ssrcDefault) ? ssrcInfo.getSsrc() : ssrc);
|
|
|
|
|
|
|
+ sendRtpItem.setSsrc(ssrc);
|
|
|
|
|
|
|
|
// 写入redis, 超时时回复
|
|
// 写入redis, 超时时回复
|
|
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
|
@@ -480,12 +489,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
});
|
|
});
|
|
|
} else {
|
|
} else {
|
|
|
// 当前系统作为下级平台使用,当上级平台点播时不携带ssrc时,并且设备在当前系统中已经点播了。这个时候需要重新给生成一个ssrc,不使用默认的"0000000000"。
|
|
// 当前系统作为下级平台使用,当上级平台点播时不携带ssrc时,并且设备在当前系统中已经点播了。这个时候需要重新给生成一个ssrc,不使用默认的"0000000000"。
|
|
|
- if (ssrc.equals(ssrcDefault)) {
|
|
|
|
|
- ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
|
|
|
|
|
- ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
|
|
|
|
|
- sendRtpItem.setSsrc(ssrc);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ sendRtpItem.setSsrc(ssrc);
|
|
|
sendRtpItem.setStreamId(playTransaction.getStream());
|
|
sendRtpItem.setStreamId(playTransaction.getStream());
|
|
|
// 写入redis, 超时时回复
|
|
// 写入redis, 超时时回复
|
|
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
|
@@ -496,11 +500,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} else if (gbStream != null) {
|
|
} else if (gbStream != null) {
|
|
|
- if(ssrc.equals(ssrcDefault))
|
|
|
|
|
- {
|
|
|
|
|
- ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
|
|
|
|
|
- ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ String ssrc;
|
|
|
|
|
+ if (gb28181Sdp.getSsrc() == null) {
|
|
|
|
|
+ // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式
|
|
|
|
|
+ ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
|
|
|
|
|
+ }else {
|
|
|
|
|
+ ssrc = gb28181Sdp.getSsrc();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
if("push".equals(gbStream.getStreamType())) {
|
|
if("push".equals(gbStream.getStreamType())) {
|
|
|
if (streamPushItem != null && streamPushItem.isPushIng()) {
|
|
if (streamPushItem != null && streamPushItem.isPushIng()) {
|
|
|
// 推流状态
|
|
// 推流状态
|
|
@@ -545,7 +553,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
if (streamReady) {
|
|
if (streamReady) {
|
|
|
// 自平台内容
|
|
// 自平台内容
|
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
|
- gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
|
|
|
|
|
|
|
+ gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp(), ssrcFromCallback ->{
|
|
|
|
|
+ return redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, null, callIdHeader.getCallId()) != null;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
if (sendRtpItem == null) {
|
|
if (sendRtpItem == null) {
|
|
|
logger.warn("服务器端口资源不足");
|
|
logger.warn("服务器端口资源不足");
|
|
@@ -584,7 +594,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
if (streamReady) {
|
|
if (streamReady) {
|
|
|
// 自平台内容
|
|
// 自平台内容
|
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
|
|
|
- gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
|
|
|
|
|
|
|
+ gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp(), ssrcFromCallback ->{
|
|
|
|
|
+ return redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, null, callIdHeader.getCallId()) != null;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
if (sendRtpItem == null) {
|
|
if (sendRtpItem == null) {
|
|
|
logger.warn("服务器端口资源不足");
|
|
logger.warn("服务器端口资源不足");
|
|
@@ -701,7 +713,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|
|
dynamicTask.stop(callIdHeader.getCallId());
|
|
dynamicTask.stop(callIdHeader.getCallId());
|
|
|
if (serverId.equals(userSetting.getServerId())) {
|
|
if (serverId.equals(userSetting.getServerId())) {
|
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
|
|
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
|
|
|
- app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
|
|
|
|
|
|
|
+ app, stream, channelId, mediaTransmissionTCP, platform.isRtcp(), ssrcFromCallback -> {
|
|
|
|
|
+ return redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, null, callIdHeader.getCallId()) != null;
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
if (sendRtpItem == null) {
|
|
if (sendRtpItem == null) {
|
|
|
logger.warn("上级点时创建sendRTPItem失败,可能是服务器端口资源不足");
|
|
logger.warn("上级点时创建sendRTPItem失败,可能是服务器端口资源不足");
|