Compare commits

...

8 Commits

Author SHA1 Message Date
WangXuewen
b526d1a896
Pre Merge pull request !34 from WangXuewen/master 2026-04-13 03:44:51 +00:00
lin
a9f2e406ce 修复dockerFile jdk版本 #2116 2026-04-13 11:44:25 +08:00
lin
c35bb73091 修复合并PR时的数据导入问题 2026-04-13 11:05:45 +08:00
648540858
2e149dc2a2
Merge pull request #2110 from q792602257/fix/ssrc_recycle
修复ssrc回收逻辑
2026-04-13 10:58:24 +08:00
648540858
f38f0bebdd
Merge pull request #2078 from yanyu510/docker_env
fix: docker环境下sip信令IP问题
2026-04-13 10:24:59 +08:00
Jerry Yan
6273c89b9d 修复SSRC无法正确回收的逻辑 2026-04-07 17:19:11 +08:00
yy
6741adb55b fix: docker环境下sip信令IP问题 2026-01-30 21:40:19 +08:00
wangxw
b05f770a57 解决sql错误,启动是PGSQL查询报错integer=boolean 2024-12-12 17:37:36 +08:00
22 changed files with 283 additions and 107 deletions

View File

@ -101,6 +101,8 @@ services:
- ./logs/wvp:/opt/wvp/logs/ - ./logs/wvp:/opt/wvp/logs/
environment: environment:
TZ: "Asia/Shanghai" TZ: "Asia/Shanghai"
# docker env
RUN_ENV: "docker"
# 流链接的IP # 流链接的IP
Stream_IP: ${Stream_IP} Stream_IP: ${Stream_IP}
# SDP里的IP # SDP里的IP

View File

@ -1,4 +1,4 @@
FROM ringcentral/jdk:11 AS builder FROM ringcentral/jdk:21.0.9 AS builder
EXPOSE 18978/tcp EXPOSE 18978/tcp
EXPOSE 8116/tcp EXPOSE 8116/tcp
@ -56,11 +56,11 @@ COPY . /build
WORKDIR /build WORKDIR /build
RUN ls && mvn clean package -Dmaven.test.skip=true RUN ls && mvn clean package -Dmaven.test.skip=true
WORKDIR /build/target WORKDIR /build/target
#确保文件名一致 #ȷ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
RUN mv wvp-pro-*.jar wvp.jar RUN mv wvp-pro-*.jar wvp.jar
FROM ringcentral/jdk:11 FROM ringcentral/jdk:21.0.9
RUN mkdir -p /opt/wvp RUN mkdir -p /opt/wvp
WORKDIR /opt/wvp WORKDIR /opt/wvp
COPY --from=builder /build/target /opt/wvp COPY --from=builder /build/target /opt/wvp

View File

@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.GbStringMsgParserFactory; import com.genersoft.iot.vmp.gb28181.bean.GbStringMsgParserFactory;
import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties; import com.genersoft.iot.vmp.gb28181.conf.DefaultProperties;
import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.ISIPProcessorObserver;
import com.genersoft.iot.vmp.utils.EnvUtil;
import gov.nist.javax.sip.SipProviderImpl; import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.SipStackImpl; import gov.nist.javax.sip.SipStackImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -174,6 +175,9 @@ public class SipLayer implements CommandLineRunner {
} }
public String getLocalIp(String deviceLocalIp) { public String getLocalIp(String deviceLocalIp) {
if(EnvUtil.isDockerEnv()){
return sipConfig.getShowIp();
}
if (monitorIps.size() == 1) { if (monitorIps.size() == 1) {
return monitorIps.get(0); return monitorIps.get(0);
} }

View File

@ -10,6 +10,8 @@ public class InviteMessageInfo {
private String sourceChannelId; private String sourceChannelId;
private String sessionName; private String sessionName;
private String ssrc; private String ssrc;
private String allocatedSsrc;
private String allocatedSsrcMediaServerId;
private boolean tcp; private boolean tcp;
private boolean tcpActive; private boolean tcpActive;
private String callId; private String callId;

View File

@ -24,6 +24,11 @@ public class SendRtpInfo {
*/ */
private String ssrc; private String ssrc;
/**
* 从SSRC池中分配的SSRC
*/
private String allocatedSsrc;
/** /**
* 目标平台或设备的编号 * 目标平台或设备的编号
*/ */
@ -247,4 +252,8 @@ public class SendRtpInfo {
this.setPlayType("Play".equalsIgnoreCase(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK); this.setPlayType("Play".equalsIgnoreCase(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK);
} }
} }
public String getSsrcToRelease() {
return allocatedSsrc;
}
} }

View File

@ -47,6 +47,11 @@ public class SsrcTransaction {
*/ */
private String ssrc; private String ssrc;
/**
* 从SSRC池中分配的SSRC
*/
private String allocatedSsrc;
/** /**
* 事务信息 * 事务信息
*/ */
@ -88,4 +93,8 @@ public class SsrcTransaction {
public SsrcTransaction() { public SsrcTransaction() {
} }
public String getSsrcToRelease() {
return allocatedSsrc;
}
} }

View File

@ -268,7 +268,7 @@ public class DeviceServiceImpl implements IDeviceService, CommandLineRunner {
List<SsrcTransaction> ssrcTransactions = sessionManager.getSsrcTransactionByDeviceId(device.getDeviceId()); List<SsrcTransaction> ssrcTransactions = sessionManager.getSsrcTransactionByDeviceId(device.getDeviceId());
if (ssrcTransactions != null && !ssrcTransactions.isEmpty()) { if (ssrcTransactions != null && !ssrcTransactions.isEmpty()) {
for (SsrcTransaction ssrcTransaction : ssrcTransactions) { for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc()); mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrcToRelease());
receiveRtpServerService.closeRTPServerByMediaServerId(ssrcTransaction.getMediaServerId(), ssrcTransaction.getApp(), ssrcTransaction.getStream()); receiveRtpServerService.closeRTPServerByMediaServerId(ssrcTransaction.getMediaServerId(), ssrcTransaction.getApp(), ssrcTransaction.getStream());
sessionManager.removeByCallId(ssrcTransaction.getCallId()); sessionManager.removeByCallId(ssrcTransaction.getCallId());
} }

View File

@ -132,7 +132,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
} }
sendRtpServerService.delete(sendRtpItem); sendRtpServerService.delete(sendRtpItem);
if (mediaServerItem != null) { if (mediaServerItem != null) {
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrcToRelease());
boolean stopResult = mediaServerService.initStopSendRtp(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); boolean stopResult = mediaServerService.initStopSendRtp(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
if (stopResult) { if (stopResult) {
Platform platform = queryPlatformByServerGBId(sendRtpItem.getTargetId()); Platform platform = queryPlatformByServerGBId(sendRtpItem.getTargetId());
@ -339,7 +339,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp()) && sendRtpItem.isSendToPlatform()) { if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp()) && sendRtpItem.isSendToPlatform()) {
Platform platform = platformMapper.getParentPlatByServerGBId(sendRtpItem.getTargetId()); Platform platform = platformMapper.getParentPlatByServerGBId(sendRtpItem.getTargetId());
CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId()); CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrcToRelease());
try { try {
commanderForPlatform.streamByeCmd(platform, sendRtpItem, channel); commanderForPlatform.streamByeCmd(platform, sendRtpItem, channel);
} catch (SipException | InvalidArgumentException | ParseException e) { } catch (SipException | InvalidArgumentException | ParseException e) {
@ -526,7 +526,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
List<SendRtpInfo> sendRtpItems = sendRtpServerService.queryForPlatform(platformId); List<SendRtpInfo> sendRtpItems = sendRtpServerService.queryForPlatform(platformId);
if (sendRtpItems != null && !sendRtpItems.isEmpty()) { if (sendRtpItems != null && !sendRtpItems.isEmpty()) {
for (SendRtpInfo sendRtpItem : sendRtpItems) { for (SendRtpInfo sendRtpItem : sendRtpItems) {
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrcToRelease());
sendRtpServerService.delete(sendRtpItem); sendRtpServerService.delete(sendRtpItem);
MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null); mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), null);
@ -647,7 +647,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
log.error("[点播超时] 发送BYE失败 {}", e.getMessage()); log.error("[点播超时] 发送BYE失败 {}", e.getMessage());
} finally { } finally {
timeoutCallback.run(1, "收流超时"); timeoutCallback.run(1, "收流超时");
mediaServerService.releaseSsrc(mediaServerItem.getId(), data.getSsrcInfo().getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), data.getSsrcInfo().getSsrcToRelease());
receiveRtpServerService.closeRTPServer(mediaServerItem, data.getSsrcInfo().getApp(), data.getSsrcInfo().getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, data.getSsrcInfo().getApp(), data.getSsrcInfo().getStream());
sessionManager.removeByStream(data.getSsrcInfo().getApp(), data.getSsrcInfo().getStream()); sessionManager.removeByStream(data.getSsrcInfo().getApp(), data.getSsrcInfo().getStream());
} }
@ -728,8 +728,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
// ssrc检验 // ssrc检验
// 更新ssrc // 更新ssrc
log.info("[Invite 200OK] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); log.info("[Invite 200OK] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
// 释放ssrc releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse); Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse);
if (!result) { if (!result) {
try { try {
@ -739,7 +738,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage()); log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
} finally { } finally {
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrcToRelease());
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream());
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
@ -751,6 +750,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
} }
}else { }else {
ssrcInfo.setSsrc(ssrcInResponse); ssrcInfo.setSsrc(ssrcInResponse);
updateSsrcTransaction(ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse, null);
inviteInfo.setSsrcInfo(ssrcInfo); inviteInfo.setSsrcInfo(ssrcInfo);
inviteInfo.setStream(ssrcInfo.getStream()); inviteInfo.setStream(ssrcInfo.getStream());
if (tcpMode == 2) { if (tcpMode == 2) {
@ -764,7 +764,9 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
inviteStreamService.updateInviteInfo(inviteInfo); inviteStreamService.updateInviteInfo(inviteInfo);
} }
}else { }else {
releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
ssrcInfo.setSsrc(ssrcInResponse); ssrcInfo.setSsrc(ssrcInResponse);
updateSsrcTransaction(ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse, null);
inviteInfo.setSsrcInfo(ssrcInfo); inviteInfo.setSsrcInfo(ssrcInfo);
inviteInfo.setStream(ssrcInfo.getStream()); inviteInfo.setStream(ssrcInfo.getStream());
if (tcpMode == 2) { if (tcpMode == 2) {
@ -782,6 +784,10 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
// 单端口 // 单端口
// 重新订阅流上线 // 重新订阅流上线
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(ssrcInfo.getApp(), inviteInfo.getStream()); SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(ssrcInfo.getApp(), inviteInfo.getStream());
if (ssrcTransaction == null) {
return;
}
releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
sessionManager.removeByStream(ssrcInfo.getApp(), inviteInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), inviteInfo.getStream());
inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse); inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
@ -790,6 +796,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
ssrcTransaction.setApp(ssrcInfo.getApp()); ssrcTransaction.setApp(ssrcInfo.getApp());
ssrcTransaction.setStream(inviteInfo.getStream()); ssrcTransaction.setStream(inviteInfo.getStream());
ssrcTransaction.setSsrc(ssrcInResponse); ssrcTransaction.setSsrc(ssrcInResponse);
ssrcTransaction.setAllocatedSsrc(null);
ssrcTransaction.setMediaServerId(mediaServerItem.getId()); ssrcTransaction.setMediaServerId(mediaServerItem.getId());
ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo((SIPResponse) responseEvent.getResponse())); ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo((SIPResponse) responseEvent.getResponse()));
ssrcTransaction.setType(inviteSessionType); ssrcTransaction.setType(inviteSessionType);
@ -800,6 +807,24 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
} }
} }
private void releaseAllocatedSsrc(MediaServer mediaServerItem, SSRCInfo ssrcInfo) {
if (ssrcInfo == null || ssrcInfo.getAllocatedSsrc() == null) {
return;
}
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getAllocatedSsrc());
ssrcInfo.setAllocatedSsrc(null);
}
private void updateSsrcTransaction(String app, String stream, String ssrc, String allocatedSsrc) {
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(app, stream);
if (ssrcTransaction == null) {
return;
}
ssrcTransaction.setSsrc(ssrc);
ssrcTransaction.setAllocatedSsrc(allocatedSsrc);
sessionManager.put(ssrcTransaction);
}
private void tcpActiveHandler(Platform platform, CommonGBChannel channel, String contentString, private void tcpActiveHandler(Platform platform, CommonGBChannel channel, String contentString,
MediaServer mediaServerItem, int tcpMode, boolean ssrcCheck, MediaServer mediaServerItem, int tcpMode, boolean ssrcCheck,
@ -836,7 +861,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
log.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channel.getGbDeviceId(), e); log.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channel.getGbDeviceId(), e);
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream());
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrcToRelease());
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(), callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
@ -861,7 +886,7 @@ public class PlatformServiceImpl implements IPlatformService, CommandLineRunner
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(null, channel.getGbId(), stream); InviteInfo inviteInfo = inviteStreamService.getInviteInfo(null, channel.getGbId(), stream);
if (inviteInfo != null) { if (inviteInfo != null) {
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), inviteInfo.getSsrcInfo().getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), inviteInfo.getSsrcInfo().getSsrcToRelease());
inviteStreamService.removeInviteInfo(inviteInfo); inviteStreamService.removeInviteInfo(inviteInfo);
} }
sessionManager.removeByStream(app, stream); sessionManager.removeByStream(app, stream);

View File

@ -495,8 +495,15 @@ public class PlayServiceImpl implements IPlayService {
try { try {
sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServerItem, null, null, playSsrc, device.getDeviceId(), MediaApp.GB28181_TALK, stream, sendRtpInfo = sendRtpServerService.createSendRtpInfo(mediaServerItem, null, null, playSsrc, device.getDeviceId(), MediaApp.GB28181_TALK, stream,
channel.getId(), true, false); channel.getId(), true, false);
if (sendRtpInfo == null) {
ssrcFactory.releaseSsrc(mediaServerItem.getId(), playSsrc);
audioEvent.call("获取发流端口失败");
return;
}
sendRtpInfo.setAllocatedSsrc(playSsrc);
sendRtpInfo.setPlayType(InviteStreamType.TALK); sendRtpInfo.setPlayType(InviteStreamType.TALK);
}catch (PlayException e) { }catch (PlayException e) {
ssrcFactory.releaseSsrc(mediaServerItem.getId(), playSsrc);
log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId()); log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId());
return; return;
} }
@ -523,7 +530,7 @@ public class PlayServiceImpl implements IPlayService {
log.error("[语音对讲]超时, 发送BYE失败 {}", e.getMessage()); log.error("[语音对讲]超时, 发送BYE失败 {}", e.getMessage());
} finally { } finally {
timeoutCallback.run(); timeoutCallback.run();
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrcToRelease());
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream()); sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
} }
}, userSetting.getPlayTimeout()); }, userSetting.getPlayTimeout());
@ -532,13 +539,13 @@ public class PlayServiceImpl implements IPlayService {
Integer localPort = mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpInfo, userSetting.getPlayTimeout() * 1000); Integer localPort = mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpInfo, userSetting.getPlayTimeout() * 1000);
if (localPort == null || localPort <= 0) { if (localPort == null || localPort <= 0) {
timeoutCallback.run(); timeoutCallback.run();
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrcToRelease());
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream()); sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
return; return;
} }
sendRtpInfo.setPort(localPort); sendRtpInfo.setPort(localPort);
}catch (ControllerException e) { }catch (ControllerException e) {
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrcToRelease());
log.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId()); log.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId());
audioEvent.call("失败, " + e.getMessage()); audioEvent.call("失败, " + e.getMessage());
// 查看是否已经建立了通道存在则发送bye // 查看是否已经建立了通道存在则发送bye
@ -584,7 +591,7 @@ public class PlayServiceImpl implements IPlayService {
dynamicTask.stop(timeOutTaskKey); dynamicTask.stop(timeOutTaskKey);
receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpInfo.getApp(), sendRtpInfo.getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpInfo.getApp(), sendRtpInfo.getStream());
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrcToRelease());
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream()); sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
errorEvent.response(event); errorEvent.response(event);
}, userSetting.getPlayTimeout().longValue()); }, userSetting.getPlayTimeout().longValue());
@ -594,7 +601,7 @@ public class PlayServiceImpl implements IPlayService {
dynamicTask.stop(timeOutTaskKey); dynamicTask.stop(timeOutTaskKey);
receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpInfo.getApp(), sendRtpInfo.getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpInfo.getApp(), sendRtpInfo.getStream());
// 释放ssrc // 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrcToRelease());
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream()); sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(); SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
@ -879,8 +886,7 @@ public class PlayServiceImpl implements IPlayService {
// ssrc检验 // ssrc检验
// 更新ssrc // 更新ssrc
log.info("[Invite 200OK] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); log.info("[Invite 200OK] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
// 释放ssrc releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse); Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse);
if (!result) { if (!result) {
try { try {
@ -890,8 +896,7 @@ public class PlayServiceImpl implements IPlayService {
log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage()); log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
} }
// 释放ssrc mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrcToRelease());
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
@ -903,6 +908,7 @@ public class PlayServiceImpl implements IPlayService {
}else { }else {
ssrcInfo.setSsrc(ssrcInResponse); ssrcInfo.setSsrc(ssrcInResponse);
updateSsrcTransaction(ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse, null);
inviteInfo.setSsrcInfo(ssrcInfo); inviteInfo.setSsrcInfo(ssrcInfo);
inviteInfo.setStream(ssrcInfo.getStream()); inviteInfo.setStream(ssrcInfo.getStream());
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) { if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
@ -914,18 +920,37 @@ public class PlayServiceImpl implements IPlayService {
} }
inviteStreamService.updateInviteInfo(inviteInfo); inviteStreamService.updateInviteInfo(inviteInfo);
} }
} else {
releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
ssrcInfo.setSsrc(ssrcInResponse);
updateSsrcTransaction(ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInResponse, null);
inviteInfo.setSsrcInfo(ssrcInfo);
inviteInfo.setStream(ssrcInfo.getStream());
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
if (mediaServerItem.isRtpEnable()) {
tcpActiveHandler(device, channel, contentString, mediaServerItem, ssrcInfo, callback);
}else {
log.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
}
}
inviteStreamService.updateInviteInfo(inviteInfo);
} }
}else { }else {
if (ssrcInResponse != null) { if (ssrcInResponse != null) {
// 单端口 // 单端口
// 重新订阅流上线 // 重新订阅流上线
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaApp.GB28181, inviteInfo.getStream()); SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(MediaApp.GB28181, inviteInfo.getStream());
if (ssrcTransaction == null) {
return;
}
releaseAllocatedSsrc(mediaServerItem, ssrcInfo);
sessionManager.removeByStream(MediaApp.GB28181, inviteInfo.getStream()); sessionManager.removeByStream(MediaApp.GB28181, inviteInfo.getStream());
inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse); inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
ssrcTransaction.setDeviceId(device.getDeviceId()); ssrcTransaction.setDeviceId(device.getDeviceId());
ssrcTransaction.setChannelId(ssrcTransaction.getChannelId()); ssrcTransaction.setChannelId(ssrcTransaction.getChannelId());
ssrcTransaction.setCallId(ssrcTransaction.getCallId()); ssrcTransaction.setCallId(ssrcTransaction.getCallId());
ssrcTransaction.setSsrc(ssrcInResponse); ssrcTransaction.setSsrc(ssrcInResponse);
ssrcTransaction.setAllocatedSsrc(null);
ssrcTransaction.setApp(MediaApp.GB28181); ssrcTransaction.setApp(MediaApp.GB28181);
ssrcTransaction.setStream(inviteInfo.getStream()); ssrcTransaction.setStream(inviteInfo.getStream());
ssrcTransaction.setMediaServerId(mediaServerItem.getId()); ssrcTransaction.setMediaServerId(mediaServerItem.getId());
@ -938,6 +963,24 @@ public class PlayServiceImpl implements IPlayService {
} }
} }
private void releaseAllocatedSsrc(MediaServer mediaServerItem, SSRCInfo ssrcInfo) {
if (ssrcInfo == null || ssrcInfo.getAllocatedSsrc() == null) {
return;
}
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getAllocatedSsrc());
ssrcInfo.setAllocatedSsrc(null);
}
private void updateSsrcTransaction(String app, String stream, String ssrc, String allocatedSsrc) {
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(app, stream);
if (ssrcTransaction == null) {
return;
}
ssrcTransaction.setSsrc(ssrc);
ssrcTransaction.setAllocatedSsrc(allocatedSsrc);
sessionManager.put(ssrcTransaction);
}
@Override @Override
public void download(Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback<StreamInfo> callback) { public void download(Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback<StreamInfo> callback) {
@ -1577,7 +1620,7 @@ public class PlayServiceImpl implements IPlayService {
mediaServerService.stopSendRtp(mediaServer, sendRtpInfo.getApp(), sendRtpInfo.getStream(), sendRtpInfo.getSsrc()); mediaServerService.stopSendRtp(mediaServer, sendRtpInfo.getApp(), sendRtpInfo.getStream(), sendRtpInfo.getSsrc());
} }
ssrcFactory.releaseSsrc(mediaServerId, sendRtpInfo.getSsrc()); ssrcFactory.releaseSsrc(mediaServerId, sendRtpInfo.getSsrcToRelease());
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream()); SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
if (ssrcTransaction != null) { if (ssrcTransaction != null) {

View File

@ -39,8 +39,7 @@ public class SSRCFactory {
public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) {
String sipDomain = sipConfig.getDomain(); String ssrcPrefix = getSsrcPrefix();
String ssrcPrefix = sipDomain.length() >= 8 ? sipDomain.substring(3, 8) : sipDomain;
String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
List<String> ssrcList = new ArrayList<>(); List<String> ssrcList = new ArrayList<>();
for (int i = 1; i < MAX_STREAM_COUNT; i++) { for (int i = 1; i < MAX_STREAM_COUNT; i++) {
@ -83,7 +82,12 @@ public class SSRCFactory {
if (ssrc == null) { if (ssrc == null) {
return; return;
} }
if (!isFactorySsrc(ssrc)) {
log.warn("[释放 SSRC] 忽略非SSRC池分配的值: {}", ssrc);
return;
}
String sn = ssrc.substring(1); String sn = ssrc.substring(1);
log.debug("[释放 SSRC] SSRC:{} -> SN: {}", ssrc, sn);
String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
redisTemplate.opsForSet().add(redisKey, sn); redisTemplate.opsForSet().add(redisKey, sn);
} }
@ -122,4 +126,18 @@ public class SSRCFactory {
return Boolean.TRUE.equals(redisTemplate.hasKey(redisKey)); return Boolean.TRUE.equals(redisTemplate.hasKey(redisKey));
} }
private String getSsrcPrefix() {
String sipDomain = sipConfig.getDomain();
return sipDomain.length() >= 8 ? sipDomain.substring(3, 8) : sipDomain;
}
private boolean isFactorySsrc(String ssrc) {
if (ssrc.length() < 2) {
return false;
}
String sn = ssrc.substring(1);
String ssrcPrefix = getSsrcPrefix();
return sn.length() == ssrcPrefix.length() + 4 && sn.startsWith(ssrcPrefix);
}
} }

View File

@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.utils.EnvUtil;
import com.genersoft.iot.vmp.utils.GitUtil; import com.genersoft.iot.vmp.utils.GitUtil;
import com.genersoft.iot.vmp.utils.IpPortUtil; import com.genersoft.iot.vmp.utils.IpPortUtil;
import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPRequest;
@ -334,6 +335,9 @@ public class SIPRequestHeaderProvider {
public Request createAckRequest(String localIp, SipURI sipURI, SIPResponse sipResponse) throws ParseException, InvalidArgumentException, PeerUnavailableException { public Request createAckRequest(String localIp, SipURI sipURI, SIPResponse sipResponse) throws ParseException, InvalidArgumentException, PeerUnavailableException {
if(EnvUtil.isDockerEnv()){
localIp = sipLayer.getLocalIp(localIp);
}
// via // via
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(localIp, sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtils.getNewViaTag()); ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(localIp, sipConfig.getPort(), sipResponse.getTopmostViaHeader().getTransport(), SipUtils.getNewViaTag());

View File

@ -285,7 +285,7 @@ public class SIPCommander implements ISIPCommander {
Request request = headerProvider.createInviteRequest(device, channel.getDeviceId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); Request request = headerProvider.createInviteRequest(device, channel.getDeviceId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> {
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrcToRelease());
errorEvent.response(e); errorEvent.response(e);
}), e -> { }), e -> {
ResponseEvent responseEvent = (ResponseEvent) e.event; ResponseEvent responseEvent = (ResponseEvent) e.event;
@ -294,6 +294,7 @@ public class SIPCommander implements ISIPCommander {
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(),
callId,ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, callId,ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response,
InviteSessionType.PLAY); InviteSessionType.PLAY);
ssrcTransaction.setAllocatedSsrc(ssrcInfo.getAllocatedSsrc());
sessionManager.put(ssrcTransaction); sessionManager.put(ssrcTransaction);
okEvent.response(e); okEvent.response(e);
}, timeout); }, timeout);
@ -391,6 +392,7 @@ public class SIPCommander implements ISIPCommander {
channel.getId(), sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), channel.getId(), sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),
device.getTransport()).getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), device.getTransport()).getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(),
mediaServerItem.getId(), response, InviteSessionType.PLAYBACK); mediaServerItem.getId(), response, InviteSessionType.PLAYBACK);
ssrcTransaction.setAllocatedSsrc(ssrcInfo.getAllocatedSsrc());
sessionManager.put(ssrcTransaction); sessionManager.put(ssrcTransaction);
okEvent.response(event); okEvent.response(event);
}, timeout); }, timeout);
@ -484,6 +486,7 @@ public class SIPCommander implements ISIPCommander {
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(),
response.getCallIdHeader().getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrc, response.getCallIdHeader().getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrc,
mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD);
ssrcTransaction.setAllocatedSsrc(ssrcInfo.getAllocatedSsrc());
sessionManager.put(ssrcTransaction); sessionManager.put(ssrcTransaction);
okEvent.response(event); okEvent.response(event);
}, timeout); }, timeout);
@ -544,13 +547,14 @@ public class SIPCommander implements ISIPCommander {
SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, sendRtpItem.getSsrc(), callIdHeader); SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, sendRtpItem.getSsrc(), callIdHeader);
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> {
sessionManager.removeByStream(sendRtpItem.getApp(), sendRtpItem.getStream()); sessionManager.removeByStream(sendRtpItem.getApp(), sendRtpItem.getStream());
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrcToRelease());
errorEvent.response(e); errorEvent.response(e);
}), e -> { }), e -> {
// 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
ResponseEvent responseEvent = (ResponseEvent) e.event; ResponseEvent responseEvent = (ResponseEvent) e.event;
SIPResponse response = (SIPResponse) responseEvent.getResponse(); SIPResponse response = (SIPResponse) responseEvent.getResponse();
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), MediaApp.GB28181_TALK,sendRtpItem.getApp(), stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.TALK); SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), MediaApp.GB28181_TALK,sendRtpItem.getApp(), stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.TALK);
ssrcTransaction.setAllocatedSsrc(sendRtpItem.getAllocatedSsrc());
sessionManager.put(ssrcTransaction); sessionManager.put(ssrcTransaction);
okEvent.response(e); okEvent.response(e);
}, timeout); }, timeout);

View File

@ -642,7 +642,7 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
String mediaServerId = sendRtpItem.getMediaServerId(); String mediaServerId = sendRtpItem.getMediaServerId();
MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId); MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId);
if (mediaServerItem != null) { if (mediaServerItem != null) {
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrcToRelease());
receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); receiveRtpServerService.closeRTPServer(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
} }
SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem, channel); SIPRequest byeRequest = headerProviderPlatformProvider.createByeRequest(platform, sendRtpItem, channel);
@ -744,13 +744,14 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
callIdHeader); callIdHeader);
sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> { sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> {
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream()); sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrcToRelease());
errorEvent.response(e); errorEvent.response(e);
}), e -> { }), e -> {
ResponseEvent responseEvent = (ResponseEvent) e.event; ResponseEvent responseEvent = (ResponseEvent) e.event;
SIPResponse response = (SIPResponse) responseEvent.getResponse(); SIPResponse response = (SIPResponse) responseEvent.getResponse();
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForPlatform(platform.getServerGBId(), channel.getGbId(), SsrcTransaction ssrcTransaction = SsrcTransaction.buildForPlatform(platform.getServerGBId(), channel.getGbId(),
callIdHeader.getCallId(), ssrcInfo.getApp(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.BROADCAST); callIdHeader.getCallId(), ssrcInfo.getApp(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.BROADCAST);
ssrcTransaction.setAllocatedSsrc(ssrcInfo.getAllocatedSsrc());
sessionManager.put(ssrcTransaction); sessionManager.put(ssrcTransaction);
okEvent.response(e); okEvent.response(e);
}); });

View File

@ -132,7 +132,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
if (mediaServer != null) { if (mediaServer != null) {
mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
if (userSetting.getUseCustomSsrcForParentInvite()) { if (userSetting.getUseCustomSsrcForParentInvite()) {
mediaServerService.releaseSsrc(mediaServer.getId(), sendRtpItem.getSsrc()); mediaServerService.releaseSsrc(mediaServer.getId(), sendRtpItem.getSsrcToRelease());
} }
} }
} }
@ -144,7 +144,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
sendRtpServerService.delete(sendRtpItem); sendRtpServerService.delete(sendRtpItem);
mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); mediaServerService.stopSendRtp(mediaInfo, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
if (userSetting.getUseCustomSsrcForParentInvite()) { if (userSetting.getUseCustomSsrcForParentInvite()) {
mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrc()); mediaServerService.releaseSsrc(mediaInfo.getId(), sendRtpItem.getSsrcToRelease());
} }
} }
if (sendRtpItem.getServerId().equals(userSetting.getServerId())) { if (sendRtpItem.getServerId().equals(userSetting.getServerId())) {
@ -254,7 +254,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
// 释放ssrc // 释放ssrc
MediaServer mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId()); MediaServer mediaServerItem = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
if (mediaServerItem != null) { if (mediaServerItem != null) {
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrc()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcTransaction.getSsrcToRelease());
} }
sessionManager.removeByCallId(ssrcTransaction.getCallId()); sessionManager.removeByCallId(ssrcTransaction.getCallId());
} }

View File

@ -120,9 +120,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
@Override @Override
public void process(RequestEvent evt) { public void process(RequestEvent evt) {
SIPRequest request = (SIPRequest)evt.getRequest(); SIPRequest request = (SIPRequest) evt.getRequest();
InviteMessageInfo inviteInfo = null;
try { try {
InviteMessageInfo inviteInfo = decode(evt); inviteInfo = decode(evt);
// 查询请求是否来自上级平台\设备 // 查询请求是否来自上级平台\设备
Platform platform = platformService.queryPlatformByServerGBId(inviteInfo.getRequesterId()); Platform platform = platformService.queryPlatformByServerGBId(inviteInfo.getRequesterId());
@ -130,7 +131,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
inviteFromDeviceHandle(request, inviteInfo); inviteFromDeviceHandle(request, inviteInfo);
} else { } else {
// 查询平台下是否有该通道 // 查询平台下是否有该通道
CommonGBChannel channel= channelService.queryOneWithPlatform(platform.getId(), inviteInfo.getTargetChannelId()); CommonGBChannel channel = channelService.queryOneWithPlatform(platform.getId(), inviteInfo.getTargetChannelId());
if (channel == null) { if (channel == null) {
log.info("[上级INVITE] 通道不存在返回404: {}", inviteInfo.getTargetChannelId()); log.info("[上级INVITE] 通道不存在返回404: {}", inviteInfo.getTargetChannelId());
try { try {
@ -143,9 +144,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
} }
log.info("[上级INVITE] 平台:{} 通道:{}({}), 收流地址:{}:{},收流方式:{}, 点播类型:{}, SSRC{}", log.info("[上级INVITE] 平台:{} 通道:{}({}), 收流地址:{}:{},收流方式:{}, 点播类型:{}, SSRC{}",
platform.getName(), channel.getGbName(), channel.getGbDeviceId(), inviteInfo.getIp(), platform.getName(), channel.getGbName(), channel.getGbDeviceId(), inviteInfo.getIp(),
inviteInfo.getPort(), inviteInfo.isTcp()?(inviteInfo.isTcpActive()?"TCP主动":"TCP被动"): "UDP", inviteInfo.getPort(), inviteInfo.isTcp() ? (inviteInfo.isTcpActive() ? "TCP主动" : "TCP被动") : "UDP",
inviteInfo.getSessionName(), inviteInfo.getSsrc()); inviteInfo.getSessionName(), inviteInfo.getSsrc());
if(!userSetting.getUseCustomSsrcForParentInvite() && ObjectUtils.isEmpty(inviteInfo.getSsrc())) { if (!userSetting.getUseCustomSsrcForParentInvite() && ObjectUtils.isEmpty(inviteInfo.getSsrc())) {
log.warn("[上级INVITE] 点播失败, 上级未携带SSRC, 并且本级未设置使用自定义SSRC"); log.warn("[上级INVITE] 点播失败, 上级未携带SSRC, 并且本级未设置使用自定义SSRC");
// 通道存在发100TRYING // 通道存在发100TRYING
try { try {
@ -162,50 +163,54 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
log.error("[命令发送失败] 上级INVITE TRYING: {}", e.getMessage()); log.error("[命令发送失败] 上级INVITE TRYING: {}", e.getMessage());
} }
InviteMessageInfo finalInviteInfo = inviteInfo;
channelPlayService.startInvite(channel, inviteInfo, platform, ((code, msg, streamInfo) -> { channelPlayService.startInvite(channel, inviteInfo, platform, ((code, msg, streamInfo) -> {
if (code != InviteErrorCode.SUCCESS.getCode()) { if (code != InviteErrorCode.SUCCESS.getCode()) {
try { try {
responseAck(request, Response.BUSY_HERE , msg); responseAck(request, Response.BUSY_HERE, msg);
} catch (SipException | InvalidArgumentException | ParseException e) { } catch (SipException | InvalidArgumentException | ParseException e) {
log.error("[命令发送失败] 上级INVITE 点播失败: {}", e.getMessage()); log.error("[命令发送失败] 上级INVITE 点播失败: {}", e.getMessage());
} }
}else { } else {
// 点播成功 TODO 可以在此处检测cancel命令是否存在存在则不发送 // 点播成功 TODO 可以在此处检测cancel命令是否存在存在则不发送
if (userSetting.getUseCustomSsrcForParentInvite()) { if (userSetting.getUseCustomSsrcForParentInvite()) {
// 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式 // 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式
MediaServer mediaServer = mediaServerService.getOne(streamInfo.getMediaServer().getId()); MediaServer mediaServer = mediaServerService.getOne(streamInfo.getMediaServer().getId());
if (mediaServer != null) { if (mediaServer != null) {
String ssrc = "Play".equalsIgnoreCase(inviteInfo.getSessionName()) String ssrc = "Play".equalsIgnoreCase(finalInviteInfo.getSessionName())
? ssrcFactory.getPlaySsrc(streamInfo.getMediaServer().getId()) ? ssrcFactory.getPlaySsrc(streamInfo.getMediaServer().getId())
: ssrcFactory.getPlayBackSsrc(streamInfo.getMediaServer().getId()); : ssrcFactory.getPlayBackSsrc(streamInfo.getMediaServer().getId());
inviteInfo.setSsrc(ssrc); finalInviteInfo.setSsrc(ssrc);
finalInviteInfo.setAllocatedSsrc(ssrc);
finalInviteInfo.setAllocatedSsrcMediaServerId(streamInfo.getMediaServer().getId());
} }
} }
// 构建sendRTP内容 // 构建sendRTP内容
SendRtpInfo sendRtpItem = sendRtpServerService.createSendRtpInfo(streamInfo.getMediaServer(), SendRtpInfo sendRtpItem = sendRtpServerService.createSendRtpInfo(streamInfo.getMediaServer(),
inviteInfo.getIp(), inviteInfo.getPort(), inviteInfo.getSsrc(), platform.getServerGBId(), finalInviteInfo.getIp(), finalInviteInfo.getPort(), finalInviteInfo.getSsrc(), platform.getServerGBId(),
streamInfo.getApp(), streamInfo.getStream(), streamInfo.getApp(), streamInfo.getStream(),
channel.getGbId(), inviteInfo.isTcp(), platform.isRtcp()); channel.getGbId(), finalInviteInfo.isTcp(), platform.isRtcp());
if (inviteInfo.isTcp() && inviteInfo.isTcpActive()) { sendRtpItem.setAllocatedSsrc(finalInviteInfo.getAllocatedSsrc());
if (finalInviteInfo.isTcp() && finalInviteInfo.isTcpActive()) {
sendRtpItem.setTcpActive(true); sendRtpItem.setTcpActive(true);
} }
sendRtpItem.setStatus(1); sendRtpItem.setStatus(1);
sendRtpItem.setCallId(inviteInfo.getCallId()); sendRtpItem.setCallId(finalInviteInfo.getCallId());
sendRtpItem.setPlayTypeByChannelDataType(channel.getDataType(), inviteInfo.getSessionName()); sendRtpItem.setPlayTypeByChannelDataType(channel.getDataType(), finalInviteInfo.getSessionName());
sendRtpItem.setServerId(streamInfo.getServerId()); sendRtpItem.setServerId(streamInfo.getServerId());
sendRtpServerService.update(sendRtpItem); sendRtpServerService.update(sendRtpItem);
String sdpIp = streamInfo.getMediaServer().getSdpIp(); String sdpIp = streamInfo.getMediaServer().getSdpIp();
if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) { if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) {
sdpIp = platform.getSendStreamIp(); sdpIp = platform.getSendStreamIp();
} }
String content = createSendSdp(sendRtpItem, inviteInfo, sdpIp); String content = createSendSdp(sendRtpItem, finalInviteInfo, sdpIp);
// 超时未收到Ack应该回复bye,当前等待时间为10秒 // 超时未收到Ack应该回复bye,当前等待时间为10秒
dynamicTask.startDelay(inviteInfo.getCallId(), () -> { dynamicTask.startDelay(finalInviteInfo.getCallId(), () -> {
log.info("[Ack ] 等待超时, {}/{}", inviteInfo.getCallId(), channel.getGbDeviceId()); log.info("[Ack ] 等待超时, {}/{}", finalInviteInfo.getCallId(), channel.getGbDeviceId());
mediaServerService.releaseSsrc(streamInfo.getMediaServer().getId(), sendRtpItem.getSsrc()); mediaServerService.releaseSsrc(streamInfo.getMediaServer().getId(), sendRtpItem.getSsrcToRelease());
// 回复bye // 回复bye
sendBye(platform, inviteInfo.getCallId()); sendBye(platform, finalInviteInfo.getCallId());
}, 60 * 1000); }, 60 * 1000);
try { try {
responseSdpAck(request, content, platform); responseSdpAck(request, content, platform);
@ -222,9 +227,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (deviceChannel != null) { if (deviceChannel != null) {
redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, deviceChannel, platform); redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, deviceChannel, platform);
} }
}catch (ControllerException e) { } catch (ControllerException e) {
log.warn("[上级INVITE] tcp主动模式 发流失败", e); log.warn("[上级INVITE] tcp主动模式 发流失败", e);
sendBye(platform, inviteInfo.getCallId()); sendBye(platform, finalInviteInfo.getCallId());
} }
} }
} }
@ -243,14 +248,16 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
} catch (SipException | InvalidArgumentException | ParseException sendException) { } catch (SipException | InvalidArgumentException | ParseException sendException) {
log.error("[命令发送失败] invite BAD_REQUEST: {}", sendException.getMessage()); log.error("[命令发送失败] invite BAD_REQUEST: {}", sendException.getMessage());
} }
}catch (PlayException e) { } catch (PlayException e) {
releaseAllocatedSsrc(inviteInfo);
try { try {
responseAck(request, e.getCode(), e.getMsg()); responseAck(request, e.getCode(), e.getMsg());
} catch (SipException | InvalidArgumentException | ParseException sendException) { } catch (SipException | InvalidArgumentException | ParseException sendException) {
log.error("[命令发送失败] invite 点播失败: {}", sendException.getMessage()); log.error("[命令发送失败] invite 点播失败: {}", sendException.getMessage());
} }
}catch (Exception e) { } catch (Exception e) {
log.error("[Invite处理异常] ", e); log.error("[Invite处理异常] ", e);
releaseAllocatedSsrc(inviteInfo);
try { try {
responseAck(request, Response.SERVER_INTERNAL_ERROR, ""); responseAck(request, Response.SERVER_INTERNAL_ERROR, "");
} catch (SipException | InvalidArgumentException | ParseException sendException) { } catch (SipException | InvalidArgumentException | ParseException sendException) {
@ -259,6 +266,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
} }
} }
private void releaseAllocatedSsrc(InviteMessageInfo inviteInfo) {
if (inviteInfo == null || inviteInfo.getAllocatedSsrc() == null || inviteInfo.getAllocatedSsrcMediaServerId() == null) {
return;
}
mediaServerService.releaseSsrc(inviteInfo.getAllocatedSsrcMediaServerId(), inviteInfo.getAllocatedSsrc());
inviteInfo.setAllocatedSsrc(null);
inviteInfo.setAllocatedSsrcMediaServerId(null);
}
private InviteMessageInfo decode(RequestEvent evt) throws SdpException { private InviteMessageInfo decode(RequestEvent evt) throws SdpException {
InviteMessageInfo inviteInfo = new InviteMessageInfo(); InviteMessageInfo inviteInfo = new InviteMessageInfo();

View File

@ -7,6 +7,7 @@ public class SSRCInfo {
private int port; private int port;
private String ssrc; private String ssrc;
private String allocatedSsrc;
private String app; private String app;
private String Stream; private String Stream;
@ -17,4 +18,8 @@ public class SSRCInfo {
this.Stream = stream; this.Stream = stream;
} }
public String getSsrcToRelease() {
return allocatedSsrc;
}
} }

View File

@ -102,6 +102,9 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
} }
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaApp.GB28181, streamId); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaApp.GB28181, streamId);
if (presetSSRC == null) {
ssrcInfo.setAllocatedSsrc(ssrc);
}
RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaApp.GB28181, streamId, ssrcCheck ? Long.parseLong(ssrc): 0L, null, onlyAuto, disableAuto, false, tcpMode); RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaApp.GB28181, streamId, ssrcCheck ? Long.parseLong(ssrc): 0L, null, onlyAuto, disableAuto, false, tcpMode);
int rtpServerPort = openRTPServer(rtpServerParam, ((code, msg, data) -> { int rtpServerPort = openRTPServer(rtpServerParam, ((code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) { if (code == InviteErrorCode.SUCCESS.getCode()) {
@ -113,6 +116,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
// 释放ssrc // 释放ssrc
if (presetSSRC == null) { if (presetSSRC == null) {
ssrcFactory.releaseSsrc(mediaServer.getId(), ssrc); ssrcFactory.releaseSsrc(mediaServer.getId(), ssrc);
ssrcInfo.setAllocatedSsrc(null);
} }
OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult(); OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult();
openRTPServerResult.setSsrcInfo(ssrcInfo); openRTPServerResult.setSsrcInfo(ssrcInfo);

View File

@ -56,6 +56,7 @@ public class RedisRpcSendRtpController extends RpcController {
if (mediaServerItem == null) { if (mediaServerItem == null) {
RedisRpcResponse response = request.getResponse(); RedisRpcResponse response = request.getResponse();
response.setStatusCode(ErrorCode.SUCCESS.getCode()); response.setStatusCode(ErrorCode.SUCCESS.getCode());
return response;
} }
// 自平台内容 // 自平台内容
int localPort = sendRtpServerService.getNextPort(mediaServerItem); int localPort = sendRtpServerService.getNextPort(mediaServerItem);
@ -63,6 +64,7 @@ public class RedisRpcSendRtpController extends RpcController {
log.info("[redis-rpc] getSendRtpItem->服务器端口资源不足" ); log.info("[redis-rpc] getSendRtpItem->服务器端口资源不足" );
RedisRpcResponse response = request.getResponse(); RedisRpcResponse response = request.getResponse();
response.setStatusCode(ErrorCode.SUCCESS.getCode()); response.setStatusCode(ErrorCode.SUCCESS.getCode());
return response;
} }
// 写入redis 超时时回复 // 写入redis 超时时回复
sendRtpItem.setStatus(1); sendRtpItem.setStatus(1);
@ -72,6 +74,7 @@ public class RedisRpcSendRtpController extends RpcController {
// 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式 // 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式
String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId());
sendRtpItem.setSsrc(ssrc); sendRtpItem.setSsrc(ssrc);
sendRtpItem.setAllocatedSsrc(ssrc);
} }
sendRtpServerService.update(sendRtpItem); sendRtpServerService.update(sendRtpItem);
RedisRpcResponse response = request.getResponse(); RedisRpcResponse response = request.getResponse();
@ -99,6 +102,7 @@ public class RedisRpcSendRtpController extends RpcController {
MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
if (mediaServer == null) { if (mediaServer == null) {
log.info("[redis-rpc] startSendRtp->未找到MediaServer {}", sendRtpItem.getMediaServerId() ); log.info("[redis-rpc] startSendRtp->未找到MediaServer {}", sendRtpItem.getMediaServerId() );
clearSendRtpItem(sendRtpItem);
WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "未找到MediaServer"); WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "未找到MediaServer");
response.setBody(wvpResult); response.setBody(wvpResult);
return response; return response;
@ -106,6 +110,7 @@ public class RedisRpcSendRtpController extends RpcController {
MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream());
if (mediaInfo == null) { if (mediaInfo == null) {
log.info("[redis-rpc] startSendRtp->流不在线: {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream() ); log.info("[redis-rpc] startSendRtp->流不在线: {}/{}", sendRtpItem.getApp(), sendRtpItem.getStream() );
clearSendRtpItem(sendRtpItem);
WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "流不在线"); WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "流不在线");
response.setBody(wvpResult); response.setBody(wvpResult);
return response; return response;
@ -114,6 +119,7 @@ public class RedisRpcSendRtpController extends RpcController {
mediaServerService.startSendRtp(mediaServer, sendRtpItem); mediaServerService.startSendRtp(mediaServer, sendRtpItem);
}catch (ControllerException exception) { }catch (ControllerException exception) {
log.info("[redis-rpc] 发流失败: {}/{}, 目标地址: {}{} {}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), exception.getMsg()); log.info("[redis-rpc] 发流失败: {}/{}, 目标地址: {}{} {}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), exception.getMsg());
clearSendRtpItem(sendRtpItem);
WVPResult wvpResult = WVPResult.fail(exception.getCode(), exception.getMsg()); WVPResult wvpResult = WVPResult.fail(exception.getCode(), exception.getMsg());
response.setBody(wvpResult); response.setBody(wvpResult);
return response; return response;
@ -143,6 +149,7 @@ public class RedisRpcSendRtpController extends RpcController {
MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
if (mediaServer == null) { if (mediaServer == null) {
log.info("[redis-rpc] stopSendRtp->未找到MediaServer {}", sendRtpItem.getMediaServerId() ); log.info("[redis-rpc] stopSendRtp->未找到MediaServer {}", sendRtpItem.getMediaServerId() );
clearSendRtpItem(sendRtpItem);
WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "未找到MediaServer"); WVPResult wvpResult = WVPResult.fail(ErrorCode.ERROR100.getCode(), "未找到MediaServer");
response.setBody(wvpResult); response.setBody(wvpResult);
return response; return response;
@ -155,9 +162,20 @@ public class RedisRpcSendRtpController extends RpcController {
response.setBody(WVPResult.fail(exception.getCode(), exception.getMsg())); response.setBody(WVPResult.fail(exception.getCode(), exception.getMsg()));
return response; return response;
} }
clearSendRtpItem(sendRtpItem);
log.info("[redis-rpc] 停止推流成功: {}/{}, 目标地址: {}{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() ); log.info("[redis-rpc] 停止推流成功: {}/{}, 目标地址: {}{}", sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort() );
response.setBody(WVPResult.success()); response.setBody(WVPResult.success());
return response; return response;
} }
private void clearSendRtpItem(SendRtpInfo sendRtpItem) {
if (sendRtpItem == null) {
return;
}
sendRtpServerService.delete(sendRtpItem);
if (sendRtpItem.getMediaServerId() != null) {
mediaServerService.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrcToRelease());
}
}
} }

View File

@ -76,6 +76,7 @@ public class RedisRpcStreamPushController extends RpcController {
// 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式 // 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式
String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServer.getId()) : ssrcFactory.getPlayBackSsrc(mediaServer.getId()); String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(mediaServer.getId()) : ssrcFactory.getPlayBackSsrc(mediaServer.getId());
sendRtpItem.setSsrc(ssrc); sendRtpItem.setSsrc(ssrc);
sendRtpItem.setAllocatedSsrc(ssrc);
} }
sendRtpItem.setMediaServerId(mediaServer.getId()); sendRtpItem.setMediaServerId(mediaServer.getId());
sendRtpItem.setLocalIp(mediaServer.getSdpIp()); sendRtpItem.setLocalIp(mediaServer.getSdpIp());
@ -95,6 +96,7 @@ public class RedisRpcStreamPushController extends RpcController {
// 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式 // 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式
String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(hookData.getMediaServer().getId()) : ssrcFactory.getPlayBackSsrc(hookData.getMediaServer().getId()); String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(hookData.getMediaServer().getId()) : ssrcFactory.getPlayBackSsrc(hookData.getMediaServer().getId());
sendRtpItem.setSsrc(ssrc); sendRtpItem.setSsrc(ssrc);
sendRtpItem.setAllocatedSsrc(ssrc);
} }
sendRtpItem.setMediaServerId(hookData.getMediaServer().getId()); sendRtpItem.setMediaServerId(hookData.getMediaServer().getId());
sendRtpItem.setLocalIp(hookData.getMediaServer().getSdpIp()); sendRtpItem.setLocalIp(hookData.getMediaServer().getSdpIp());

View File

@ -110,6 +110,7 @@ public class RedisRpcServiceImpl implements IRedisRpcService {
// 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式 // 上级平台点播时不使用上级平台指定的ssrc使用自定义的ssrc参考国标文档-点播外域设备媒体流SSRC处理方式
String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(hookData.getMediaServer().getId()) : ssrcFactory.getPlayBackSsrc(hookData.getMediaServer().getId()); String ssrc = "Play".equalsIgnoreCase(sendRtpItem.getSessionName()) ? ssrcFactory.getPlaySsrc(hookData.getMediaServer().getId()) : ssrcFactory.getPlayBackSsrc(hookData.getMediaServer().getId());
sendRtpItem.setSsrc(ssrc); sendRtpItem.setSsrc(ssrc);
sendRtpItem.setAllocatedSsrc(ssrc);
} }
sendRtpItem.setMediaServerId(hookData.getMediaServer().getId()); sendRtpItem.setMediaServerId(hookData.getMediaServer().getId());
sendRtpItem.setLocalIp(hookData.getMediaServer().getSdpIp()); sendRtpItem.setLocalIp(hookData.getMediaServer().getSdpIp());

View File

@ -0,0 +1,8 @@
package com.genersoft.iot.vmp.utils;
public class EnvUtil {
public static boolean isDockerEnv() {
return "docker".equals(System.getenv("RUN_ENV"));
}
}

View File

@ -101,6 +101,7 @@ sip:
# 请不要使用127.0.0.1任何包括localhost在内的域名都是不可以的。 # 请不要使用127.0.0.1任何包括localhost在内的域名都是不可以的。
ip: 0.0.0.0 ip: 0.0.0.0
# [可选] 没有任何业务需求,仅仅是在前端展示的时候用 # [可选] 没有任何业务需求,仅仅是在前端展示的时候用
# [docker环境下必选] 在docker环境中运行时此配置为sip对外的ip地址 必须配置,否则无法正常使用
show-ip: 192.168.0.100 show-ip: 192.168.0.100
# [可选] 28181服务监听的端口 # [可选] 28181服务监听的端口
port: 5060 port: 5060