Commit 66210ec51ae0f20288585293cff5ac187a6d39da

Authored by 648540858
1 parent c8b0e66e

支持国标级联语音喊话TCP主动模式

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
... ... @@ -978,8 +978,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
978 978 return;
979 979 }
980 980 String contentString = new String(request.getRawContent());
981   - // jainSip不支持y=字段, 移除移除以解析。
982   - String ssrc = "0000000404";
983 981  
984 982 try {
985 983 Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString);
... ... @@ -1027,7 +1025,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1027 1025 return;
1028 1026 }
1029 1027 String addressStr = sdp.getOrigin().getAddress();
1030   - logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, ssrc,
  1028 + logger.info("设备{}请求语音流,地址:{}:{},ssrc:{}, {}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
1031 1029 mediaTransmissionTCP ? (tcpActive ? "TCP主动" : "TCP被动") : "UDP");
1032 1030  
1033 1031 MediaServerItem mediaServerItem = broadcastCatch.getMediaServerItem();
... ... @@ -1041,11 +1039,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1041 1039 }
1042 1040 return;
1043 1041 }
1044   - logger.info("设备{}请求语音流, 收流地址:{}:{},ssrc:{}, {}, 对讲方式:{}", requesterId, addressStr, port, ssrc,
  1042 + logger.info("设备{}请求语音流, 收流地址:{}:{},ssrc:{}, {}, 对讲方式:{}", requesterId, addressStr, port, gb28181Sdp.getSsrc(),
1045 1043 mediaTransmissionTCP ? (tcpActive ? "TCP主动" : "TCP被动") : "UDP", sdp.getSessionName().getValue());
1046 1044 CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
1047 1045  
1048   - SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
  1046 + SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, gb28181Sdp.getSsrc(), requesterId,
1049 1047 device.getDeviceId(), broadcastCatch.getChannelId(),
1050 1048 mediaTransmissionTCP, false);
1051 1049  
... ... @@ -1081,7 +1079,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1081 1079  
1082 1080 Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, broadcastCatch.getApp(), broadcastCatch.getStream());
1083 1081 if (streamReady) {
1084   - sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, ssrc);
  1082 + sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, gb28181Sdp.getSsrc());
1085 1083 } else {
1086 1084 logger.warn("[语音通话], 未发现待推送的流,app={},stream={}", broadcastCatch.getApp(), broadcastCatch.getStream());
1087 1085 try {
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
... ... @@ -206,7 +206,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
206 206 @Override
207 207 public void closeRTPServer(String mediaServerId, String streamId) {
208 208 MediaServerItem mediaServerItem = this.getOne(mediaServerId);
209   - if (mediaServerItem.isRtpEnable()) {
  209 + if (mediaServerItem != null && mediaServerItem.isRtpEnable()) {
210 210 closeRTPServer(mediaServerItem, streamId);
211 211 }
212 212 zlmresTfulUtils.closeStreams(mediaServerItem, "rtp", streamId);
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
1 1 package com.genersoft.iot.vmp.service.impl;
2 2  
  3 +import com.alibaba.fastjson2.JSONObject;
3 4 import com.genersoft.iot.vmp.common.InviteInfo;
  5 +import com.genersoft.iot.vmp.common.InviteSessionStatus;
4 6 import com.genersoft.iot.vmp.common.InviteSessionType;
5 7 import com.baomidou.dynamic.datasource.annotation.DS;
6 8 import com.genersoft.iot.vmp.conf.DynamicTask;
... ... @@ -11,6 +13,7 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
11 13 import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
12 14 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
13 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
  16 +import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
14 17 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
15 18 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
16 19 import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
... ... @@ -22,20 +25,20 @@ import com.genersoft.iot.vmp.service.IInviteStreamService;
22 25 import com.genersoft.iot.vmp.service.IMediaServerService;
23 26 import com.genersoft.iot.vmp.service.IPlatformService;
24 27 import com.genersoft.iot.vmp.service.IPlayService;
25   -import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
26   -import com.genersoft.iot.vmp.service.bean.InviteTimeOutCallback;
27   -import com.genersoft.iot.vmp.service.bean.SSRCInfo;
  28 +import com.genersoft.iot.vmp.service.bean.*;
28 29 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
29 30 import com.genersoft.iot.vmp.storager.dao.*;
30 31 import com.genersoft.iot.vmp.utils.DateUtil;
31 32 import com.github.pagehelper.PageHelper;
32 33 import com.github.pagehelper.PageInfo;
33 34 import gov.nist.javax.sip.message.SIPRequest;
  35 +import gov.nist.javax.sip.message.SIPResponse;
34 36 import org.slf4j.Logger;
35 37 import org.slf4j.LoggerFactory;
36 38 import org.springframework.beans.factory.annotation.Autowired;
37 39 import org.springframework.stereotype.Service;
38 40  
  41 +import javax.sdp.*;
39 42 import javax.sip.InvalidArgumentException;
40 43 import javax.sip.ResponseEvent;
41 44 import javax.sip.PeerUnavailableException;
... ... @@ -109,6 +112,9 @@ public class PlatformServiceImpl implements IPlatformService {
109 112 @Autowired
110 113 private IInviteStreamService inviteStreamService;
111 114  
  115 + @Autowired
  116 + private ZLMRESTfulUtils zlmresTfulUtils;
  117 +
112 118  
113 119 @Override
114 120 public ParentPlatform queryPlatformByServerGBId(String platformGbId) {
... ... @@ -466,21 +472,21 @@ public class PlatformServiceImpl implements IPlatformService {
466 472 logger.info("[国标级联] 语音喊话未找到可用的zlm. platform: {}", platform.getServerGBId());
467 473 return;
468 474 }
469   - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, platform.getServerGBId(), channelId);
  475 + InviteInfo inviteInfoForOld = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, platform.getServerGBId(), channelId);
470 476  
471   - if (inviteInfo != null && inviteInfo.getStreamInfo() != null) {
  477 + if (inviteInfoForOld != null && inviteInfoForOld.getStreamInfo() != null) {
472 478 // 如果zlm不存在这个流,则删除数据即可
473   - MediaServerItem mediaServerItemForStreamInfo = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
  479 + MediaServerItem mediaServerItemForStreamInfo = mediaServerService.getOne(inviteInfoForOld.getStreamInfo().getMediaServerId());
474 480 if (mediaServerItemForStreamInfo != null) {
475   - Boolean ready = zlmServerFactory.isStreamReady(mediaServerItemForStreamInfo, inviteInfo.getStreamInfo().getApp(), inviteInfo.getStreamInfo().getStream());
  481 + Boolean ready = zlmServerFactory.isStreamReady(mediaServerItemForStreamInfo, inviteInfoForOld.getStreamInfo().getApp(), inviteInfoForOld.getStreamInfo().getStream());
476 482 if (!ready) {
477 483 // 错误存在于redis中的数据
478   - inviteStreamService.removeInviteInfo(inviteInfo);
  484 + inviteStreamService.removeInviteInfo(inviteInfoForOld);
479 485 }else {
480 486 // 流确实尚在推流,直接回调结果
481 487 OnStreamChangedHookParam hookParam = new OnStreamChangedHookParam();
482   - hookParam.setApp(inviteInfo.getStreamInfo().getApp());
483   - hookParam.setStream(inviteInfo.getStreamInfo().getStream());
  488 + hookParam.setApp(inviteInfoForOld.getStreamInfo().getApp());
  489 + hookParam.setStream(inviteInfoForOld.getStreamInfo().getStream());
484 490  
485 491 hookEvent.response(mediaServerItemForStreamInfo, hookParam);
486 492 return;
... ... @@ -515,6 +521,11 @@ public class PlatformServiceImpl implements IPlatformService {
515 521 logger.info("[国标级联] 语音喊话,发起Invite消息 deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}",
516 522 platform.getServerGBId(), channelId, ssrcInfo.getPort(), userSetting.getBroadcastForPlatform(), ssrcInfo.getSsrc(), ssrcCheck);
517 523  
  524 + // 初始化redis中的invite消息状态
  525 + InviteInfo inviteInfo = InviteInfo.getInviteInfo(platform.getServerGBId(), channelId, ssrcInfo.getStream(), ssrcInfo,
  526 + mediaServerItem.getSdpIp(), ssrcInfo.getPort(), userSetting.getBroadcastForPlatform(), InviteSessionType.BROADCAST,
  527 + InviteSessionStatus.ready);
  528 + inviteStreamService.updateInviteInfo(inviteInfo);
518 529 String timeOutTaskKey = UUID.randomUUID().toString();
519 530 dynamicTask.startDelay(timeOutTaskKey, () -> {
520 531 // 执行超时任务时查询是否已经成功,成功了则不执行超时任务,防止超时任务取消失败的情况
... ... @@ -545,50 +556,206 @@ public class PlatformServiceImpl implements IPlatformService {
545 556 hookEvent.response(mediaServerItem, hookParam);
546 557 }
547 558 }, event -> {
548   - // 收到200OK 检测ssrc是否有变化,防止上级自定义了ssrc
549   - ResponseEvent responseEvent = (ResponseEvent) event.event;
550   - String contentString = new String(responseEvent.getResponse().getRawContent());
551   - // 获取ssrc
552   - int ssrcIndex = contentString.indexOf("y=");
553   - // 检查是否有y字段
554   - if (ssrcIndex >= 0) {
555   - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
556   - String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
557   - // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
558   - if (ssrcInfo.getSsrc().equals(ssrcInResponse) || ssrcCheck) {
559   - return;
  559 +
  560 + inviteOKHandler(event, ssrcInfo, tcpMode, ssrcCheck, mediaServerItem, platform, channelId, timeOutTaskKey,
  561 + null, inviteInfo, InviteSessionType.BROADCAST);
  562 +// // 收到200OK 检测ssrc是否有变化,防止上级自定义了ssrc
  563 +// ResponseEvent responseEvent = (ResponseEvent) event.event;
  564 +// String contentString = new String(responseEvent.getResponse().getRawContent());
  565 +// // 获取ssrc
  566 +// int ssrcIndex = contentString.indexOf("y=");
  567 +// // 检查是否有y字段
  568 +// if (ssrcIndex >= 0) {
  569 +// //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
  570 +// String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
  571 +// // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
  572 +// if (ssrcInfo.getSsrc().equals(ssrcInResponse) || ssrcCheck) {
  573 +// tcpActiveHandler(platform, )
  574 +// return;
  575 +// }
  576 +// logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
  577 +// if (!mediaServerItem.isRtpEnable()) {
  578 +// logger.info("[点播消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
  579 +// // 释放ssrc
  580 +// mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  581 +// // 单端口模式streamId也有变化,需要重新设置监听
  582 +// if (!mediaServerItem.isRtpEnable()) {
  583 +// // 添加订阅
  584 +// HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
  585 +// subscribe.removeSubscribe(hookSubscribe);
  586 +// hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
  587 +// subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
  588 +// logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam);
  589 +// dynamicTask.stop(timeOutTaskKey);
  590 +// // hook响应
  591 +// playService.onPublishHandlerForPlay(mediaServerItemInUse, hookParam, platform.getServerGBId(), channelId);
  592 +// hookEvent.response(mediaServerItemInUse, hookParam);
  593 +// });
  594 +// }
  595 +// // 关闭rtp server
  596 +// mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
  597 +// // 重新开启ssrc server
  598 +// mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, false, false, ssrcInfo.getPort(), true, false, tcpMode);
  599 +// }
  600 +// }
  601 + }, eventResult -> {
  602 + // 收到错误回复
  603 + if (errorEvent != null) {
  604 + errorEvent.response(eventResult);
  605 + }
  606 + });
  607 + }
  608 +
  609 + private void inviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, int tcpMode, boolean ssrcCheck, MediaServerItem mediaServerItem,
  610 + ParentPlatform platform, String channelId, String timeOutTaskKey, ErrorCallback<Object> callback,
  611 + InviteInfo inviteInfo, InviteSessionType inviteSessionType){
  612 + inviteInfo.setStatus(InviteSessionStatus.ok);
  613 + ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
  614 + String contentString = new String(responseEvent.getResponse().getRawContent());
  615 + System.out.println(1111);
  616 + System.out.println(contentString);
  617 + String ssrcInResponse = SipUtils.getSsrcFromSdp(contentString);
  618 + // 兼容回复的消息中缺少ssrc(y字段)的情况
  619 + if (ssrcInResponse == null) {
  620 + ssrcInResponse = ssrcInfo.getSsrc();
  621 + }
  622 + if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
  623 + // ssrc 一致
  624 + if (mediaServerItem.isRtpEnable()) {
  625 + // 多端口
  626 + if (tcpMode == 2) {
  627 + tcpActiveHandler(platform, channelId, contentString, mediaServerItem, tcpMode, ssrcCheck,
  628 + timeOutTaskKey, ssrcInfo, callback);
  629 + }
  630 + }else {
  631 + // 单端口
  632 + if (tcpMode == 2) {
  633 + logger.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
560 634 }
561   - logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
562   - if (!mediaServerItem.isRtpEnable()) {
563   - logger.info("[点播消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
  635 + }
  636 + }else {
  637 + logger.info("[Invite 200OK] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
  638 + // ssrc 不一致
  639 + if (mediaServerItem.isRtpEnable()) {
  640 + // 多端口
  641 + if (ssrcCheck) {
  642 + // ssrc检验
  643 + // 更新ssrc
  644 + logger.info("[Invite 200OK] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
564 645 // 释放ssrc
565 646 mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
566   - // 单端口模式streamId也有变化,需要重新设置监听
567   - if (!mediaServerItem.isRtpEnable()) {
568   - // 添加订阅
569   - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
570   - subscribe.removeSubscribe(hookSubscribe);
571   - hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
572   - subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
573   - logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam);
574   - dynamicTask.stop(timeOutTaskKey);
575   - // hook响应
576   - playService.onPublishHandlerForPlay(mediaServerItemInUse, hookParam, platform.getServerGBId(), channelId);
577   - hookEvent.response(mediaServerItemInUse, hookParam);
578   - });
  647 + Boolean result = mediaServerService.updateRtpServerSSRC(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse);
  648 + if (!result) {
  649 + try {
  650 + logger.warn("[Invite 200OK] 更新ssrc失败,停止喊话 {}/{}", platform.getServerGBId(), channelId);
  651 + commanderForPlatform.streamByeCmd(platform, channelId, ssrcInfo.getStream(), null, null);
  652 + } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
  653 + logger.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
  654 + }
  655 +
  656 + dynamicTask.stop(timeOutTaskKey);
  657 + // 释放ssrc
  658 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  659 +
  660 + streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream());
  661 +
  662 + callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
  663 + "下级自定义了ssrc,重新设置收流信息失败", null);
  664 + inviteStreamService.call(inviteSessionType, platform.getServerGBId(), channelId, null,
  665 + InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
  666 + "下级自定义了ssrc,重新设置收流信息失败", null);
  667 +
  668 + }else {
  669 + ssrcInfo.setSsrc(ssrcInResponse);
  670 + inviteInfo.setSsrcInfo(ssrcInfo);
  671 + inviteInfo.setStream(ssrcInfo.getStream());
  672 + if (tcpMode == 2) {
  673 + if (mediaServerItem.isRtpEnable()) {
  674 + tcpActiveHandler(platform, channelId, contentString, mediaServerItem, tcpMode, ssrcCheck,
  675 + timeOutTaskKey, ssrcInfo, callback);
  676 + }else {
  677 + logger.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
  678 + }
  679 + }
  680 + inviteStreamService.updateInviteInfo(inviteInfo);
579 681 }
580   - // 关闭rtp server
581   - mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
582   - // 重新开启ssrc server
583   - mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, false, false, ssrcInfo.getPort(), true, false, tcpMode);
  682 + }else {
  683 + ssrcInfo.setSsrc(ssrcInResponse);
  684 + inviteInfo.setSsrcInfo(ssrcInfo);
  685 + inviteInfo.setStream(ssrcInfo.getStream());
  686 + if (tcpMode == 2) {
  687 + if (mediaServerItem.isRtpEnable()) {
  688 + tcpActiveHandler(platform, channelId, contentString, mediaServerItem, tcpMode, ssrcCheck,
  689 + timeOutTaskKey, ssrcInfo, callback);
  690 + }else {
  691 + logger.warn("[Invite 200OK] 单端口收流模式不支持tcp主动模式收流");
  692 + }
  693 + }
  694 + inviteStreamService.updateInviteInfo(inviteInfo);
  695 + }
  696 + }else {
  697 + if (ssrcInResponse != null) {
  698 + // 单端口
  699 + // 重新订阅流上线
  700 + SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(inviteInfo.getDeviceId(),
  701 + inviteInfo.getChannelId(), null, inviteInfo.getStream());
  702 + streamSession.remove(inviteInfo.getDeviceId(),
  703 + inviteInfo.getChannelId(), inviteInfo.getStream());
  704 + inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
  705 + streamSession.put(platform.getServerGBId(), channelId, ssrcTransaction.getCallId(),
  706 + inviteInfo.getStream(), ssrcInResponse, mediaServerItem.getId(), (SIPResponse) responseEvent.getResponse(), inviteSessionType);
584 707 }
585 708 }
586   - }, eventResult -> {
587   - // 收到错误回复
588   - if (errorEvent != null) {
589   - errorEvent.response(eventResult);
  709 + }
  710 + }
  711 +
  712 +
  713 + private void tcpActiveHandler(ParentPlatform platform, String channelId, String contentString,
  714 + MediaServerItem mediaServerItem, int tcpMode, boolean ssrcCheck,
  715 + String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback<Object> callback){
  716 + if (tcpMode != 2) {
  717 + return;
  718 + }
  719 +
  720 + String substring;
  721 + if (contentString.indexOf("y=") > 0) {
  722 + substring = contentString.substring(0, contentString.indexOf("y="));
  723 + }else {
  724 + substring = contentString;
  725 + }
  726 + try {
  727 + SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring);
  728 + int port = -1;
  729 + Vector mediaDescriptions = sdp.getMediaDescriptions(true);
  730 + for (Object description : mediaDescriptions) {
  731 + MediaDescription mediaDescription = (MediaDescription) description;
  732 + Media media = mediaDescription.getMedia();
  733 +
  734 + Vector mediaFormats = media.getMediaFormats(false);
  735 + if (mediaFormats.contains("8") || mediaFormats.contains("0")) {
  736 + port = media.getMediaPort();
  737 + break;
  738 + }
590 739 }
591   - });
  740 + logger.info("[TCP主动连接对方] serverGbId: {}, channelId: {}, 连接对方的地址:{}:{}, SSRC: {}, SSRC校验:{}",
  741 + platform.getServerGBId(), channelId, sdp.getConnection().getAddress(), port, ssrcInfo.getSsrc(), ssrcCheck);
  742 + JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
  743 + logger.info("[TCP主动连接对方] 结果: {}", jsonObject);
  744 + } catch (SdpException e) {
  745 + logger.error("[TCP主动连接对方] serverGbId: {}, channelId: {}, 解析200OK的SDP信息失败", platform.getServerGBId(), channelId, e);
  746 + dynamicTask.stop(timeOutTaskKey);
  747 + mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
  748 + // 释放ssrc
  749 + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
  750 +
  751 + streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream());
  752 +
  753 + callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
  754 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
  755 + inviteStreamService.call(InviteSessionType.PLAY, platform.getServerGBId(), channelId, null,
  756 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
  757 + InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
  758 + }
592 759 }
593 760  
594 761 @Override
... ...
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java
... ... @@ -18,7 +18,6 @@ import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
18 18 import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
19 19 import com.github.pagehelper.PageHelper;
20 20 import com.github.pagehelper.PageInfo;
21   -import com.sun.org.apache.xml.internal.resolver.Catalog;
22 21 import org.slf4j.Logger;
23 22 import org.slf4j.LoggerFactory;
24 23 import org.springframework.beans.factory.annotation.Autowired;
... ...