重构SSRC获取逻辑,支持根据MediaServer动态获取SSRC

This commit is contained in:
lin 2026-05-21 14:07:20 +08:00
parent 324f75ce76
commit 667a85c2a1
6 changed files with 36 additions and 55 deletions

View File

@ -481,7 +481,7 @@ public class PlayServiceImpl implements IPlayService {
private void talk(MediaServer mediaServerItem, Device device, DeviceChannel channel, String stream, private void talk(MediaServer mediaServerItem, Device device, DeviceChannel channel, String stream,
SipSubscribe.Event errorEvent, Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { SipSubscribe.Event errorEvent, Runnable timeoutCallback, AudioBroadcastEvent audioEvent) {
String ySsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); String ySsrc = ssrcFactory.getPlaySsrc(mediaServerItem);
if (ySsrc == null) { if (ySsrc == null) {
audioEvent.call("ssrc已经用尽"); audioEvent.call("ssrc已经用尽");

View File

@ -63,13 +63,19 @@ public class SSRCFactory {
return suffix != null ? "1" + suffix : null; return suffix != null ? "1" + suffix : null;
} }
public String getPlaySsrcRandom() { public String getPlaySsrc(MediaServer mediaServer) {
if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
return "0" + domainPart + String.format("%04d", ThreadLocalRandom.current().nextInt(10000)); return "0" + domainPart + String.format("%04d", ThreadLocalRandom.current().nextInt(10000));
} }
return getPlaySsrc(mediaServer.getId());
}
public String getPlayBackSsrcRandom() { public String getPlayBackSsrc(MediaServer mediaServer) {
if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
return "1" + domainPart + String.format("%04d", ThreadLocalRandom.current().nextInt(10000)); return "1" + domainPart + String.format("%04d", ThreadLocalRandom.current().nextInt(10000));
} }
return getPlayBackSsrc(mediaServer.getId());
}
private String allocate(String mediaServerId) { private String allocate(String mediaServerId) {
synchronized (lockMap.computeIfAbsent(mediaServerId, k -> new Object())) { synchronized (lockMap.computeIfAbsent(mediaServerId, k -> new Object())) {

View File

@ -18,11 +18,11 @@ public class RTPServerParam {
private String app; private String app;
private String streamId; private String streamId;
/** /**
* 传递给zlm创建rtp server的streamId不填则使用streamId * 是否将ssrc传递给zlm做校验
*/ */
private String zlmStreamId; private boolean ssrcCheck;
/** /**
* 开启rtpServer时使用的ssrc开启rtpServer时会根据这个ssrc进行校验如果不填则不校验 * 开启rtpServer时使用的ssrc
*/ */
private Long ssrc; private Long ssrc;
private Integer port; private Integer port;

View File

@ -90,10 +90,8 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
final String ssrc; final String ssrc;
if (presetSSRC != null) { if (presetSSRC != null) {
ssrc = presetSSRC; ssrc = presetSSRC;
} else if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
ssrc = playback ? ssrcFactory.getPlayBackSsrcRandom() : ssrcFactory.getPlaySsrcRandom();
} else { } else {
ssrc = playback ? ssrcFactory.getPlayBackSsrc(mediaServer.getId()) : ssrcFactory.getPlaySsrc(mediaServer.getId()); ssrc = playback ? ssrcFactory.getPlayBackSsrc(mediaServer) : ssrcFactory.getPlaySsrc(mediaServer);
} }
if (streamId == null) { if (streamId == null) {
streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase(); streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
@ -104,7 +102,8 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
} }
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamId); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamId);
RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.RTP_APP, streamId, ssrcCheck ? Long.parseLong(ssrc): 0L, null, onlyAuto, disableAuto, false, tcpMode); RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.RTP_APP, streamId, Long.parseLong(ssrc), null, onlyAuto, disableAuto, false, tcpMode);
rtpServerParam.setSsrcCheck(ssrcCheck);
int rtpServerPort = openCommonRTPServer(rtpServerParam, ((code, msg, data) -> { int rtpServerPort = openCommonRTPServer(rtpServerParam, ((code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) { if (code == InviteErrorCode.SUCCESS.getCode()) {
OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult(); OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult();
@ -137,10 +136,8 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
final String ssrc; final String ssrc;
if (presetSSRC != null) { if (presetSSRC != null) {
ssrc = presetSSRC; ssrc = presetSSRC;
} else if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
ssrc = ssrcFactory.getPlaySsrcRandom();
} else { } else {
ssrc = ssrcFactory.getPlaySsrc(mediaServer.getId()); ssrc = ssrcFactory.getPlaySsrc(mediaServer);
} }
String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase(); String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
@ -149,14 +146,11 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0); int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0);
if (device.isSsrcCheck() && tcpMode > 0) { if (device.isSsrcCheck() && tcpMode > 0) {
// 目前zlm不支持 tcp模式更新ssrc暂时关闭ssrc校验
log.warn("[开启国标点播RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验"); log.warn("[开启国标点播RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验");
} }
Long checkSsrc = device.isSsrcCheck() ? Long.parseLong(ssrc) : 0L;
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace);
openRtpServer(mediaServer, ssrcInfo, checkSsrc, !channel.isHasAudio(), false, tcpMode, callback, streamId); openRtpServer(mediaServer, ssrcInfo, Long.parseLong(ssrc), !channel.isHasAudio(), false, tcpMode, callback, device.isSsrcCheck());
addAuthenticateInfo(streamId, streamReplace, channel.isHasAudio(), record, null); addAuthenticateInfo(streamId, streamReplace, channel.isHasAudio(), record, null);
return ssrcInfo; return ssrcInfo;
} }
@ -174,12 +168,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
} }
// 获取 mediaServer 可用的 ssrc // 获取 mediaServer 可用的 ssrc
String ssrc; String ssrc = ssrcFactory.getPlayBackSsrc(mediaServer);
if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
ssrc = ssrcFactory.getPlayBackSsrcRandom();
} else {
ssrc = ssrcFactory.getPlayBackSsrc(mediaServer.getId());
}
String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase(); String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
String streamReplace = getPlaybackStream(device, channel, startTime, endTime); String streamReplace = getPlaybackStream(device, channel, startTime, endTime);
@ -187,14 +176,11 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0); int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0);
if (device.isSsrcCheck() && tcpMode > 0) { if (device.isSsrcCheck() && tcpMode > 0) {
// 目前zlm不支持 tcp模式更新ssrc暂时关闭ssrc校验
log.warn("[开启国标回放RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验"); log.warn("[开启国标回放RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验");
} }
Long checkSsrc = device.isSsrcCheck() ? Long.parseLong(ssrc) : 0L;
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace);
openRtpServer(mediaServer, ssrcInfo, checkSsrc, !channel.isHasAudio(), false, tcpMode, callback, streamId); openRtpServer(mediaServer, ssrcInfo, Long.parseLong(ssrc), !channel.isHasAudio(), false, tcpMode, callback, device.isSsrcCheck());
addAuthenticateInfo(streamId, streamReplace, channel.isHasAudio(), false,null); addAuthenticateInfo(streamId, streamReplace, channel.isHasAudio(), false,null);
return ssrcInfo; return ssrcInfo;
} }
@ -226,12 +212,7 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0); int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0);
// 获取 mediaServer 可用的 ssrc // 获取 mediaServer 可用的 ssrc
String ssrc; String ssrc = ssrcFactory.getPlayBackSsrc(mediaServer);
if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
ssrc = ssrcFactory.getPlayBackSsrcRandom();
} else {
ssrc = ssrcFactory.getPlayBackSsrc(mediaServer.getId());
}
String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase(); String streamId = String.format("%08x", Long.parseLong(ssrc)).toUpperCase();
String streamReplace = String.format("%s_%s_%s_%s", device.getDeviceId(), channel.getDeviceId(), String streamReplace = String.format("%s_%s_%s_%s", device.getDeviceId(), channel.getDeviceId(),
@ -239,14 +220,11 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
endTime.replace("-", "").replace(":", "").replace(" ", "")); endTime.replace("-", "").replace(":", "").replace(" ", ""));
if (device.isSsrcCheck() && tcpMode > 0) { if (device.isSsrcCheck() && tcpMode > 0) {
// 目前zlm不支持 tcp模式更新ssrc暂时关闭ssrc校验
log.warn("[开启国标录像下载RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验"); log.warn("[开启国标录像下载RTP收流] 平台对接时下级可能自定义ssrc但是tcp模式zlm收流目前无法更新ssrc可能收流超时此时请使用udp收流或者关闭ssrc校验");
} }
Long checkSsrc = device.isSsrcCheck() ? Long.parseLong(ssrc) : 0L;
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamReplace);
openRtpServer(mediaServer, ssrcInfo, checkSsrc, !channel.isHasAudio(), false, tcpMode, callback, streamId); openRtpServer(mediaServer, ssrcInfo, Long.parseLong(ssrc), !channel.isHasAudio(), false, tcpMode, callback, device.isSsrcCheck());
long difference = DateUtil.getDifference(startTime, endTime) / 1000; long difference = DateUtil.getDifference(startTime, endTime) / 1000;
@ -281,28 +259,23 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
} }
// 获取 mediaServer 可用的 ssrc // 获取 mediaServer 可用的 ssrc
String ssrc; String ssrc = ssrcFactory.getPlaySsrc(mediaServer);
if (mediaServer.isRtpEnable() && userSetting.getSsrcRandom()) {
ssrc = ssrcFactory.getPlaySsrcRandom();
} else {
ssrc = ssrcFactory.getPlaySsrc(mediaServer.getId());
}
SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamId); SSRCInfo ssrcInfo = new SSRCInfo(0, ssrc, MediaStreamUtil.RTP_APP, streamId);
openRtpServer(mediaServer, ssrcInfo, 0L, false, true, tcpMode, callback); openRtpServer(mediaServer, ssrcInfo, Long.parseLong(ssrc), false, true, tcpMode, callback, false);
return ssrcInfo; return ssrcInfo;
} }
private void openRtpServer(MediaServer mediaServer, SSRCInfo ssrcInfo, Long checkSsrc, boolean disableAuto, boolean onlyAuto, int tcpMode, private void openRtpServer(MediaServer mediaServer, SSRCInfo ssrcInfo, Long checkSsrc, boolean disableAuto, boolean onlyAuto, int tcpMode,
ErrorCallback<OpenRTPServerResult> callback) { ErrorCallback<OpenRTPServerResult> callback) {
openRtpServer(mediaServer, ssrcInfo, checkSsrc, disableAuto, onlyAuto, tcpMode, callback, null); openRtpServer(mediaServer, ssrcInfo, checkSsrc, disableAuto, onlyAuto, tcpMode, callback, false);
} }
private void openRtpServer(MediaServer mediaServer, SSRCInfo ssrcInfo, Long checkSsrc, boolean disableAuto, boolean onlyAuto, int tcpMode, private void openRtpServer(MediaServer mediaServer, SSRCInfo ssrcInfo, Long checkSsrc, boolean disableAuto, boolean onlyAuto, int tcpMode,
ErrorCallback<OpenRTPServerResult> callback, String zlmStreamId) { ErrorCallback<OpenRTPServerResult> callback, boolean ssrcCheck) {
RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.RTP_APP, ssrcInfo.getStream(), checkSsrc, null, onlyAuto, disableAuto, false, tcpMode); RTPServerParam rtpServerParam = new RTPServerParam(mediaServer, MediaStreamUtil.RTP_APP, ssrcInfo.getStream(), checkSsrc, null, onlyAuto, disableAuto, false, tcpMode);
rtpServerParam.setZlmStreamId(zlmStreamId); rtpServerParam.setSsrcCheck(ssrcCheck);
int rtpServerPort = openCommonRTPServer(rtpServerParam, ((code, msg, data) -> { int rtpServerPort = openCommonRTPServer(rtpServerParam, ((code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) { if (code == InviteErrorCode.SUCCESS.getCode()) {
OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult(); OpenRTPServerResult openRTPServerResult = new OpenRTPServerResult();
@ -336,7 +309,9 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
dynamicTask.startDelay(timeOutTaskKey, () -> { dynamicTask.startDelay(timeOutTaskKey, () -> {
// 收流超时 // 收流超时
// 关闭收流端口 // 关闭收流端口
mediaServerService.closeRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), rtpServerParam.getStreamId()); String closeStreamId = rtpServerParam.getMediaServer().isRtpEnable()
? String.format("%08x", rtpServerParam.getSsrc()) : rtpServerParam.getStreamId();
mediaServerService.closeRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), closeStreamId);
subscribe.removeSubscribe(rtpHook); subscribe.removeSubscribe(rtpHook);
callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null); callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
}, userSetting.getPlayTimeout()); }, userSetting.getPlayTimeout());
@ -350,9 +325,9 @@ public class RtpServerServiceImpl implements IReceiveRtpServerService {
int rtpServerPort; int rtpServerPort;
if (rtpServerParam.getMediaServer().isRtpEnable()) { if (rtpServerParam.getMediaServer().isRtpEnable()) {
String effectiveStreamId = rtpServerParam.getZlmStreamId() != null ? rtpServerParam.getZlmStreamId() : rtpServerParam.getStreamId(); String zlmStreamId = String.format("%08x", rtpServerParam.getSsrc());
rtpServerPort = mediaServerService.createRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), effectiveStreamId, Long checkSsrc = rtpServerParam.isSsrcCheck() ? rtpServerParam.getSsrc() : 0L;
Objects.requireNonNullElse(rtpServerParam.getSsrc(), 0L), rtpServerParam.getPort(), rtpServerParam.isOnlyAuto(), rtpServerPort = mediaServerService.createRTPServer(rtpServerParam.getMediaServer(), rtpServerParam.getApp(), zlmStreamId, checkSsrc, rtpServerParam.getPort(), rtpServerParam.isOnlyAuto(),
rtpServerParam.isDisableAudio(), rtpServerParam.isReUsePort(), rtpServerParam.getTcpMode()); rtpServerParam.isDisableAudio(), rtpServerParam.isReUsePort(), rtpServerParam.getTcpMode());
} else { } else {
rtpServerPort = rtpServerParam.getMediaServer().getRtpProxyPort(); rtpServerPort = rtpServerParam.getMediaServer().getRtpProxyPort();

View File

@ -4,8 +4,7 @@
style="width:100%; height: 100%; background-color: #000000;margin:0 auto;position: relative;" style="width:100%; height: 100%; background-color: #000000;margin:0 auto;position: relative;"
@dblclick="fullscreenSwich" @dblclick="fullscreenSwich"
> >
<div style="width:100%; padding-top: 56.25%; position: relative;" /> <div id="buttonsBox" class="buttons-box" v-if="showButton === undefined || showButton">
<div id="buttonsBox" class="buttons-box" v-if="showButton">
<div class="buttons-box-left"> <div class="buttons-box-left">
<i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick" /> <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick" />
<i v-if="playing" class="iconfont icon-pause jessibuca-btn" @click="pause" /> <i v-if="playing" class="iconfont icon-pause jessibuca-btn" @click="pause" />

View File

@ -29,6 +29,7 @@
:error="videoError" :error="videoError"
:message="videoError" :message="videoError"
:has-audio="hasAudio" :has-audio="hasAudio"
:show-button="true"
fluent fluent
autoplay autoplay
live live