Commit 3fe47021b9aefb11b1e659383ac2f3d0edd2aa42
1 parent
ebc904e4
优化国标规范,参考国标文档中-点播外域设备媒体流SSRC处理方式,上级点播时自定义ssrc,不适用上级携带的ssrc,也避免上级兼容性差,不携带ssrc的问题,可通过配置关闭此特性
Showing
8 changed files
with
61 additions
and
21 deletions
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| @@ -53,6 +53,7 @@ public class UserSetting { | @@ -53,6 +53,7 @@ public class UserSetting { | ||
| 53 | private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; | 53 | private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; |
| 54 | 54 | ||
| 55 | private Boolean deviceStatusNotify = Boolean.FALSE; | 55 | private Boolean deviceStatusNotify = Boolean.FALSE; |
| 56 | + private Boolean useCustomSsrcForParentInvite = Boolean.TRUE; | ||
| 56 | 57 | ||
| 57 | private String serverId = "000000"; | 58 | private String serverId = "000000"; |
| 58 | 59 | ||
| @@ -277,4 +278,12 @@ public class UserSetting { | @@ -277,4 +278,12 @@ public class UserSetting { | ||
| 277 | public void setDeviceStatusNotify(Boolean deviceStatusNotify) { | 278 | public void setDeviceStatusNotify(Boolean deviceStatusNotify) { |
| 278 | this.deviceStatusNotify = deviceStatusNotify; | 279 | this.deviceStatusNotify = deviceStatusNotify; |
| 279 | } | 280 | } |
| 281 | + | ||
| 282 | + public Boolean getUseCustomSsrcForParentInvite() { | ||
| 283 | + return useCustomSsrcForParentInvite; | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) { | ||
| 287 | + this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite; | ||
| 288 | + } | ||
| 280 | } | 289 | } |
src/main/java/com/genersoft/iot/vmp/gb28181/task/SipRunner.java
| @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.conf.UserSetting; | ||
| 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; | 5 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 6 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 9 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| 9 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 10 | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| @@ -38,6 +39,9 @@ public class SipRunner implements CommandLineRunner { | @@ -38,6 +39,9 @@ public class SipRunner implements CommandLineRunner { | ||
| 38 | private IRedisCatchStorage redisCatchStorage; | 39 | private IRedisCatchStorage redisCatchStorage; |
| 39 | 40 | ||
| 40 | @Autowired | 41 | @Autowired |
| 42 | + private SSRCFactory ssrcFactory; | ||
| 43 | + | ||
| 44 | + @Autowired | ||
| 41 | private UserSetting userSetting; | 45 | private UserSetting userSetting; |
| 42 | 46 | ||
| 43 | @Autowired | 47 | @Autowired |
| @@ -96,6 +100,7 @@ public class SipRunner implements CommandLineRunner { | @@ -96,6 +100,7 @@ public class SipRunner implements CommandLineRunner { | ||
| 96 | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 100 | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 97 | redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStreamId()); | 101 | redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(),sendRtpItem.getChannelId(), sendRtpItem.getCallId(),sendRtpItem.getStreamId()); |
| 98 | if (mediaServerItem != null) { | 102 | if (mediaServerItem != null) { |
| 103 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | ||
| 99 | Map<String, Object> param = new HashMap<>(); | 104 | Map<String, Object> param = new HashMap<>(); |
| 100 | param.put("vhost","__defaultVhost__"); | 105 | param.put("vhost","__defaultVhost__"); |
| 101 | param.put("app",sendRtpItem.getApp()); | 106 | param.put("app",sendRtpItem.getApp()); |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; | ||
| 6 | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; | 6 | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType; |
| 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 7 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 8 | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | 8 | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; |
| 9 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | ||
| 9 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 10 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 10 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 11 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 11 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 12 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; |
| @@ -61,6 +62,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -61,6 +62,9 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 61 | private ZLMRTPServerFactory zlmrtpServerFactory; | 62 | private ZLMRTPServerFactory zlmrtpServerFactory; |
| 62 | 63 | ||
| 63 | @Autowired | 64 | @Autowired |
| 65 | + private SSRCFactory ssrcFactory; | ||
| 66 | + | ||
| 67 | + @Autowired | ||
| 64 | private IMediaServerService mediaServerService; | 68 | private IMediaServerService mediaServerService; |
| 65 | 69 | ||
| 66 | @Autowired | 70 | @Autowired |
| @@ -102,6 +106,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | @@ -102,6 +106,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In | ||
| 102 | logger.info("[收到bye] 停止向上级推流:{}", streamId); | 106 | logger.info("[收到bye] 停止向上级推流:{}", streamId); |
| 103 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 107 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 104 | redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); | 108 | redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); |
| 109 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | ||
| 105 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | 110 | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); |
| 106 | int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | 111 | int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); |
| 107 | if (totalReaderCount <= 0) { | 112 | if (totalReaderCount <= 0) { |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| @@ -245,18 +245,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -245,18 +245,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 245 | String contentString = new String(request.getRawContent()); | 245 | String contentString = new String(request.getRawContent()); |
| 246 | 246 | ||
| 247 | // jainSip不支持y=字段, 移除以解析。 | 247 | // jainSip不支持y=字段, 移除以解析。 |
| 248 | - int ssrcIndex = contentString.indexOf("y="); | ||
| 249 | // 检查是否有y字段 | 248 | // 检查是否有y字段 |
| 250 | - String ssrcDefault = "0000000000"; | ||
| 251 | - String ssrc; | 249 | + int ssrcIndex = contentString.indexOf("y="); |
| 250 | + | ||
| 252 | SessionDescription sdp; | 251 | SessionDescription sdp; |
| 253 | if (ssrcIndex >= 0) { | 252 | if (ssrcIndex >= 0) { |
| 254 | //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 | 253 | //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 |
| 255 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 256 | - String substring = contentString.substring(0, contentString.indexOf("y=")); | 254 | + String substring = contentString.substring(0, ssrcIndex); |
| 257 | sdp = SdpFactory.getInstance().createSessionDescription(substring); | 255 | sdp = SdpFactory.getInstance().createSessionDescription(substring); |
| 258 | } else { | 256 | } else { |
| 259 | - ssrc = ssrcDefault; | ||
| 260 | sdp = SdpFactory.getInstance().createSessionDescription(contentString); | 257 | sdp = SdpFactory.getInstance().createSessionDescription(contentString); |
| 261 | } | 258 | } |
| 262 | String sessionName = sdp.getSessionName().getValue(); | 259 | String sessionName = sdp.getSessionName().getValue(); |
| @@ -320,7 +317,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -320,7 +317,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 320 | String username = sdp.getOrigin().getUsername(); | 317 | String username = sdp.getOrigin().getUsername(); |
| 321 | String addressStr = sdp.getConnection().getAddress(); | 318 | String addressStr = sdp.getConnection().getAddress(); |
| 322 | 319 | ||
| 323 | - logger.info("[上级点播]用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc); | 320 | + |
| 324 | Device device = null; | 321 | Device device = null; |
| 325 | // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 | 322 | // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 |
| 326 | if (channel != null) { | 323 | if (channel != null) { |
| @@ -344,6 +341,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -344,6 +341,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 344 | } | 341 | } |
| 345 | return; | 342 | return; |
| 346 | } | 343 | } |
| 344 | + | ||
| 345 | + String ssrc; | ||
| 346 | + if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | ||
| 347 | + // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 | ||
| 348 | + ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); | ||
| 349 | + }else { | ||
| 350 | + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 351 | + } | ||
| 352 | + logger.info("[上级点播] 用户:{}, 通道:{}, 地址:{}:{}, ssrc:{}", username, channelId, addressStr, port, ssrc); | ||
| 347 | SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, | 353 | SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, |
| 348 | device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp()); | 354 | device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp()); |
| 349 | 355 | ||
| @@ -465,29 +471,23 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -465,29 +471,23 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 465 | } | 471 | } |
| 466 | } | 472 | } |
| 467 | if (playTransaction == null) { | 473 | if (playTransaction == null) { |
| 474 | + // 被点播的通道目前未被点播,则开始点播 | ||
| 468 | String streamId = null; | 475 | String streamId = null; |
| 469 | if (mediaServerItem.isRtpEnable()) { | 476 | if (mediaServerItem.isRtpEnable()) { |
| 470 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); | 477 | streamId = String.format("%s_%s", device.getDeviceId(), channelId); |
| 471 | } | 478 | } |
| 472 | - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam()); | 479 | + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam()); |
| 473 | logger.info(JSONObject.toJSONString(ssrcInfo)); | 480 | logger.info(JSONObject.toJSONString(ssrcInfo)); |
| 474 | sendRtpItem.setStreamId(ssrcInfo.getStream()); | 481 | sendRtpItem.setStreamId(ssrcInfo.getStream()); |
| 475 | - sendRtpItem.setSsrc(ssrc.equals(ssrcDefault) ? ssrcInfo.getSsrc() : ssrc); | 482 | +// sendRtpItem.setSsrc(ssrcInfo.getSsrc()); |
| 476 | 483 | ||
| 477 | // 写入redis, 超时时回复 | 484 | // 写入redis, 超时时回复 |
| 478 | redisCatchStorage.updateSendRTPSever(sendRtpItem); | 485 | redisCatchStorage.updateSendRTPSever(sendRtpItem); |
| 479 | - MediaServerItem finalMediaServerItem = mediaServerItem; | ||
| 480 | playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { | 486 | playService.play(mediaServerItem, ssrcInfo, device, channelId, hookEvent, errorEvent, (code, msg) -> { |
| 481 | logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId); | 487 | logger.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId); |
| 482 | redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); | 488 | redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); |
| 483 | }); | 489 | }); |
| 484 | } else { | 490 | } else { |
| 485 | - // 当前系统作为下级平台使用,当上级平台点播时不携带ssrc时,并且设备在当前系统中已经点播了。这个时候需要重新给生成一个ssrc,不使用默认的"0000000000"。 | ||
| 486 | - if (ssrc.equals(ssrcDefault)) { | ||
| 487 | - ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); | ||
| 488 | - ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc); | ||
| 489 | - sendRtpItem.setSsrc(ssrc); | ||
| 490 | - } | ||
| 491 | 491 | ||
| 492 | sendRtpItem.setStreamId(playTransaction.getStream()); | 492 | sendRtpItem.setStreamId(playTransaction.getStream()); |
| 493 | // 写入redis, 超时时回复 | 493 | // 写入redis, 超时时回复 |
| @@ -499,11 +499,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | @@ -499,11 +499,15 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements | ||
| 499 | } | 499 | } |
| 500 | } | 500 | } |
| 501 | } else if (gbStream != null) { | 501 | } else if (gbStream != null) { |
| 502 | - if(ssrc.equals(ssrcDefault)) | ||
| 503 | - { | ||
| 504 | - ssrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); | ||
| 505 | - ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc); | 502 | + |
| 503 | + String ssrc; | ||
| 504 | + if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | ||
| 505 | + // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 | ||
| 506 | + ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); | ||
| 507 | + }else { | ||
| 508 | + ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | ||
| 506 | } | 509 | } |
| 510 | + | ||
| 507 | if("push".equals(gbStream.getStreamType())) { | 511 | if("push".equals(gbStream.getStreamType())) { |
| 508 | if (streamPushItem != null && streamPushItem.isPushIng()) { | 512 | if (streamPushItem != null && streamPushItem.isPushIng()) { |
| 509 | // 推流状态 | 513 | // 推流状态 |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; | @@ -8,6 +8,7 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; | ||
| 8 | import com.genersoft.iot.vmp.gb28181.bean.*; | 8 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 9 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | 9 | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| 10 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; | 10 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| 11 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | ||
| 11 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 12 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 12 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 13 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 13 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 14 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| @@ -105,6 +106,9 @@ public class ZLMHttpHookListener { | @@ -105,6 +106,9 @@ public class ZLMHttpHookListener { | ||
| 105 | @Autowired | 106 | @Autowired |
| 106 | private AssistRESTfulUtils assistRESTfulUtils; | 107 | private AssistRESTfulUtils assistRESTfulUtils; |
| 107 | 108 | ||
| 109 | + @Autowired | ||
| 110 | + private SSRCFactory ssrcFactory; | ||
| 111 | + | ||
| 108 | @Qualifier("taskExecutor") | 112 | @Qualifier("taskExecutor") |
| 109 | @Autowired | 113 | @Autowired |
| 110 | private ThreadPoolTaskExecutor taskExecutor; | 114 | private ThreadPoolTaskExecutor taskExecutor; |
| @@ -666,6 +670,7 @@ public class ZLMHttpHookListener { | @@ -666,6 +670,7 @@ public class ZLMHttpHookListener { | ||
| 666 | if (sendRtpItems.size() > 0) { | 670 | if (sendRtpItems.size() > 0) { |
| 667 | for (SendRtpItem sendRtpItem : sendRtpItems) { | 671 | for (SendRtpItem sendRtpItem : sendRtpItems) { |
| 668 | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); | 672 | ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); |
| 673 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | ||
| 669 | try { | 674 | try { |
| 670 | commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); | 675 | commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); |
| 671 | } catch (SipException | InvalidArgumentException | ParseException e) { | 676 | } catch (SipException | InvalidArgumentException | ParseException e) { |
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
| @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; | @@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.conf.DynamicTask; | ||
| 4 | import com.genersoft.iot.vmp.conf.UserSetting; | 4 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | import com.genersoft.iot.vmp.gb28181.bean.*; | 5 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 6 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 6 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 7 | +import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; | ||
| 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | 8 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; |
| 8 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; | 9 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 10 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| @@ -54,6 +55,9 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -54,6 +55,9 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 54 | private IRedisCatchStorage redisCatchStorage; | 55 | private IRedisCatchStorage redisCatchStorage; |
| 55 | 56 | ||
| 56 | @Autowired | 57 | @Autowired |
| 58 | + private SSRCFactory ssrcFactory; | ||
| 59 | + | ||
| 60 | + @Autowired | ||
| 57 | private IMediaServerService mediaServerService; | 61 | private IMediaServerService mediaServerService; |
| 58 | 62 | ||
| 59 | @Autowired | 63 | @Autowired |
| @@ -328,6 +332,7 @@ public class PlatformServiceImpl implements IPlatformService { | @@ -328,6 +332,7 @@ public class PlatformServiceImpl implements IPlatformService { | ||
| 328 | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(platformId); | 332 | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(platformId); |
| 329 | if (sendRtpItems != null && sendRtpItems.size() > 0) { | 333 | if (sendRtpItems != null && sendRtpItems.size() > 0) { |
| 330 | for (SendRtpItem sendRtpItem : sendRtpItems) { | 334 | for (SendRtpItem sendRtpItem : sendRtpItems) { |
| 335 | + ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); | ||
| 331 | redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null); | 336 | redisCatchStorage.deleteSendRTPServer(platformId, sendRtpItem.getChannelId(), null, null); |
| 332 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 337 | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); |
| 333 | Map<String, Object> param = new HashMap<>(3); | 338 | Map<String, Object> param = new HashMap<>(3); |
src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
| @@ -915,7 +915,12 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | @@ -915,7 +915,12 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { | ||
| 915 | @Override | 915 | @Override |
| 916 | public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) { | 916 | public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) { |
| 917 | String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS; | 917 | String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS; |
| 918 | - logger.info("[redis通知] 推送设备/通道状态, {}/{}-{}", deviceId, channelId, online); | 918 | + if (channelId == null) { |
| 919 | + logger.info("[redis通知] 推送设备状态, {}-{}", deviceId, online); | ||
| 920 | + }else { | ||
| 921 | + logger.info("[redis通知] 推送通道状态, {}/{}-{}", deviceId, channelId, online); | ||
| 922 | + } | ||
| 923 | + | ||
| 919 | StringBuilder msg = new StringBuilder(); | 924 | StringBuilder msg = new StringBuilder(); |
| 920 | msg.append(deviceId); | 925 | msg.append(deviceId); |
| 921 | if (channelId != null) { | 926 | if (channelId != null) { |
src/main/resources/all-application.yml
| @@ -194,6 +194,8 @@ user-settings: | @@ -194,6 +194,8 @@ user-settings: | ||
| 194 | max-notify-count-queue: 10000 | 194 | max-notify-count-queue: 10000 |
| 195 | # 设备/通道状态变化时发送消息 | 195 | # 设备/通道状态变化时发送消息 |
| 196 | device-status-notify: false | 196 | device-status-notify: false |
| 197 | + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 | ||
| 198 | + use-custom-ssrc-for-parent-invite: true | ||
| 197 | # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 | 199 | # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 |
| 198 | allowed-origins: | 200 | allowed-origins: |
| 199 | - http://localhost:8008 | 201 | - http://localhost:8008 |