Commit 470625e0770e27e8f20c3221b9c4096218079294

Authored by 648540858
1 parent fa13b228

支持全局固定流地址

src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
@@ -459,7 +459,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -459,7 +459,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
459 sendRtpItem.setApp("rtp"); 459 sendRtpItem.setApp("rtp");
460 if ("Playback".equalsIgnoreCase(sessionName)) { 460 if ("Playback".equalsIgnoreCase(sessionName)) {
461 sendRtpItem.setPlayType(InviteStreamType.PLAYBACK); 461 sendRtpItem.setPlayType(InviteStreamType.PLAYBACK);
462 - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam()); 462 + String startTimeStr = DateUtil.urlFormatter.format(start);
  463 + String endTimeStr = DateUtil.urlFormatter.format(end);
  464 + String stream = device.getDeviceId() + "_" + channelId + "_" + startTimeStr + "_" + endTimeStr;
  465 + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
463 sendRtpItem.setStreamId(ssrcInfo.getStream()); 466 sendRtpItem.setStreamId(ssrcInfo.getStream());
464 // 写入redis, 超时时回复 467 // 写入redis, 超时时回复
465 redisCatchStorage.updateSendRTPSever(sendRtpItem); 468 redisCatchStorage.updateSendRTPSever(sendRtpItem);
@@ -520,12 +523,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -520,12 +523,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
520 } 523 }
521 })); 524 }));
522 sendRtpItem.setPlayType(InviteStreamType.PLAY); 525 sendRtpItem.setPlayType(InviteStreamType.PLAY);
523 - String streamId = null;  
524 - if (mediaServerItem.isRtpEnable()) {  
525 - streamId = String.format("%s_%s", device.getDeviceId(), channelId);  
526 - }else {  
527 - streamId = String.format("%08x", Integer.parseInt(ssrcInfo.getSsrc())).toUpperCase();  
528 - } 526 + String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
529 sendRtpItem.setStreamId(streamId); 527 sendRtpItem.setStreamId(streamId);
530 sendRtpItem.setSsrc(ssrcInfo.getSsrc()); 528 sendRtpItem.setSsrc(ssrcInfo.getSsrc());
531 redisCatchStorage.updateSendRTPSever(sendRtpItem); 529 redisCatchStorage.updateSendRTPSever(sendRtpItem);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -193,7 +193,10 @@ public class ZLMHttpHookListener { @@ -193,7 +193,10 @@ public class ZLMHttpHookListener {
193 193
194 String mediaServerId = json.getString("mediaServerId"); 194 String mediaServerId = json.getString("mediaServerId");
195 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); 195 MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
196 - 196 + if (mediaInfo == null) {
  197 + return new HookResultForOnPublish(200, "success");
  198 + }
  199 + // 推流鉴权的处理
197 if (!"rtp".equals(param.getApp())) { 200 if (!"rtp".equals(param.getApp())) {
198 if (userSetting.getPushAuthority()) { 201 if (userSetting.getPushAuthority()) {
199 // 推流鉴权 202 // 推流鉴权
@@ -245,11 +248,21 @@ public class ZLMHttpHookListener { @@ -245,11 +248,21 @@ public class ZLMHttpHookListener {
245 } 248 }
246 }); 249 });
247 250
  251 + // 是否录像
248 if ("rtp".equals(param.getApp())) { 252 if ("rtp".equals(param.getApp())) {
249 result.setEnable_mp4(userSetting.getRecordSip()); 253 result.setEnable_mp4(userSetting.getRecordSip());
250 } else { 254 } else {
251 result.setEnable_mp4(userSetting.isRecordPushLive()); 255 result.setEnable_mp4(userSetting.isRecordPushLive());
252 } 256 }
  257 + // 替换流地址
  258 + if ("rtp".equals(param.getApp()) && !mediaInfo.isRtpEnable()) {
  259 + String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16));;
  260 + InviteInfo inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc);
  261 + if (inviteInfo != null) {
  262 + result.setStream_replace(inviteInfo.getStream());
  263 + logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream());
  264 + }
  265 + }
253 List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); 266 List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream());
254 if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { 267 if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
255 String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); 268 String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
@@ -562,7 +575,7 @@ public class ZLMHttpHookListener { @@ -562,7 +575,7 @@ public class ZLMHttpHookListener {
562 575
563 if ("rtp".equals(param.getApp())) { 576 if ("rtp".equals(param.getApp())) {
564 String[] s = param.getStream().split("_"); 577 String[] s = param.getStream().split("_");
565 - if (!mediaInfo.isRtpEnable() || (s.length != 2 && s.length != 4)) { 578 + if ((s.length != 2 && s.length != 4)) {
566 defaultResult.setResult(HookResult.SUCCESS()); 579 defaultResult.setResult(HookResult.SUCCESS());
567 return defaultResult; 580 return defaultResult;
568 } 581 }
@@ -591,7 +604,6 @@ public class ZLMHttpHookListener { @@ -591,7 +604,6 @@ public class ZLMHttpHookListener {
591 604
592 result.onTimeout(() -> { 605 result.onTimeout(() -> {
593 logger.info("[ZLM HOOK] 预览流自动点播, 等待超时"); 606 logger.info("[ZLM HOOK] 预览流自动点播, 等待超时");
594 - // 释放rtpserver  
595 msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时")); 607 msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时"));
596 resultHolder.invokeResult(msg); 608 resultHolder.invokeResult(msg);
597 }); 609 });
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java
@@ -6,6 +6,7 @@ public class HookResultForOnPublish extends HookResult{ @@ -6,6 +6,7 @@ public class HookResultForOnPublish extends HookResult{
6 private boolean enable_mp4; 6 private boolean enable_mp4;
7 private int mp4_max_second; 7 private int mp4_max_second;
8 private String mp4_save_path; 8 private String mp4_save_path;
  9 + private String stream_replace;
9 10
10 public HookResultForOnPublish() { 11 public HookResultForOnPublish() {
11 } 12 }
@@ -51,12 +52,21 @@ public class HookResultForOnPublish extends HookResult{ @@ -51,12 +52,21 @@ public class HookResultForOnPublish extends HookResult{
51 this.mp4_save_path = mp4_save_path; 52 this.mp4_save_path = mp4_save_path;
52 } 53 }
53 54
  55 + public String getStream_replace() {
  56 + return stream_replace;
  57 + }
  58 +
  59 + public void setStream_replace(String stream_replace) {
  60 + this.stream_replace = stream_replace;
  61 + }
  62 +
54 @Override 63 @Override
55 public String toString() { 64 public String toString() {
56 return "HookResultForOnPublish{" + 65 return "HookResultForOnPublish{" +
57 "enable_audio=" + enable_audio + 66 "enable_audio=" + enable_audio +
58 ", enable_mp4=" + enable_mp4 + 67 ", enable_mp4=" + enable_mp4 +
59 ", mp4_max_second=" + mp4_max_second + 68 ", mp4_max_second=" + mp4_max_second +
  69 + ", stream_replace=" + stream_replace +
60 ", mp4_save_path='" + mp4_save_path + '\'' + 70 ", mp4_save_path='" + mp4_save_path + '\'' +
61 '}'; 71 '}';
62 } 72 }
src/main/java/com/genersoft/iot/vmp/service/IInviteStreamService.java
@@ -74,5 +74,13 @@ public interface IInviteStreamService { @@ -74,5 +74,13 @@ public interface IInviteStreamService {
74 int getStreamInfoCount(String mediaServerId); 74 int getStreamInfoCount(String mediaServerId);
75 75
76 76
  77 + /**
  78 + * 获取MediaServer下的流信息
  79 + */
  80 + InviteInfo getInviteInfoBySSRC(String ssrc);
77 81
  82 + /**
  83 + * 更新ssrc
  84 + */
  85 + InviteInfo updateInviteInfoForSSRC(InviteInfo inviteInfo, String ssrcInResponse);
78 } 86 }
src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
@@ -80,7 +80,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -80,7 +80,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
80 ":" + inviteInfoForUpdate.getType() + 80 ":" + inviteInfoForUpdate.getType() +
81 ":" + inviteInfoForUpdate.getDeviceId() + 81 ":" + inviteInfoForUpdate.getDeviceId() +
82 ":" + inviteInfoForUpdate.getChannelId() + 82 ":" + inviteInfoForUpdate.getChannelId() +
83 - ":" + inviteInfoForUpdate.getStream(); 83 + ":" + inviteInfoForUpdate.getStream()+
  84 + ":" + inviteInfoForUpdate.getSsrcInfo().getSsrc();
84 redisTemplate.opsForValue().set(key, inviteInfoForUpdate); 85 redisTemplate.opsForValue().set(key, inviteInfoForUpdate);
85 } 86 }
86 87
@@ -96,7 +97,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -96,7 +97,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
96 ":" + inviteInfo.getType() + 97 ":" + inviteInfo.getType() +
97 ":" + inviteInfo.getDeviceId() + 98 ":" + inviteInfo.getDeviceId() +
98 ":" + inviteInfo.getChannelId() + 99 ":" + inviteInfo.getChannelId() +
99 - ":" + stream; 100 + ":" + stream +
  101 + ":" + inviteInfo.getSsrcInfo().getSsrc();
100 inviteInfoInDb.setStream(stream); 102 inviteInfoInDb.setStream(stream);
101 if (inviteInfoInDb.getSsrcInfo() != null) { 103 if (inviteInfoInDb.getSsrcInfo() != null) {
102 inviteInfoInDb.getSsrcInfo().setStream(stream); 104 inviteInfoInDb.getSsrcInfo().setStream(stream);
@@ -111,7 +113,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -111,7 +113,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
111 ":" + (type != null ? type : "*") + 113 ":" + (type != null ? type : "*") +
112 ":" + (deviceId != null ? deviceId : "*") + 114 ":" + (deviceId != null ? deviceId : "*") +
113 ":" + (channelId != null ? channelId : "*") + 115 ":" + (channelId != null ? channelId : "*") +
114 - ":" + (stream != null ? stream : "*"); 116 + ":" + (stream != null ? stream : "*")
  117 + + ":*";
115 List<Object> scanResult = RedisUtil.scan(redisTemplate, key); 118 List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
116 if (scanResult.size() != 1) { 119 if (scanResult.size() != 1) {
117 return null; 120 return null;
@@ -136,7 +139,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -136,7 +139,8 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
136 ":" + (type != null ? type : "*") + 139 ":" + (type != null ? type : "*") +
137 ":" + (deviceId != null ? deviceId : "*") + 140 ":" + (deviceId != null ? deviceId : "*") +
138 ":" + (channelId != null ? channelId : "*") + 141 ":" + (channelId != null ? channelId : "*") +
139 - ":" + (stream != null ? stream : "*"); 142 + ":" + (stream != null ? stream : "*") +
  143 + ":*";
140 List<Object> scanResult = RedisUtil.scan(redisTemplate, scanKey); 144 List<Object> scanResult = RedisUtil.scan(redisTemplate, scanKey);
141 if (scanResult.size() > 0) { 145 if (scanResult.size() > 0) {
142 for (Object keyObj : scanResult) { 146 for (Object keyObj : scanResult) {
@@ -191,7 +195,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -191,7 +195,7 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
191 @Override 195 @Override
192 public int getStreamInfoCount(String mediaServerId) { 196 public int getStreamInfoCount(String mediaServerId) {
193 int count = 0; 197 int count = 0;
194 - String key = VideoManagerConstants.INVITE_PREFIX + ":*:*:*:*"; 198 + String key = VideoManagerConstants.INVITE_PREFIX + ":*:*:*:*:*";
195 List<Object> scanResult = RedisUtil.scan(redisTemplate, key); 199 List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
196 if (scanResult.size() == 0) { 200 if (scanResult.size() == 0) {
197 return 0; 201 return 0;
@@ -229,4 +233,35 @@ public class InviteStreamServiceImpl implements IInviteStreamService { @@ -229,4 +233,35 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
229 } 233 }
230 return key; 234 return key;
231 } 235 }
  236 +
  237 + @Override
  238 + public InviteInfo getInviteInfoBySSRC(String ssrc) {
  239 + String key = VideoManagerConstants.INVITE_PREFIX + ":*:*:*:*:" + ssrc;
  240 + List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
  241 + if (scanResult.size() != 1) {
  242 + return null;
  243 + }
  244 +
  245 + return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
  246 + }
  247 +
  248 + @Override
  249 + public InviteInfo updateInviteInfoForSSRC(InviteInfo inviteInfo, String ssrc) {
  250 + InviteInfo inviteInfoInDb = getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
  251 + if (inviteInfoInDb == null) {
  252 + return null;
  253 + }
  254 + removeInviteInfo(inviteInfoInDb);
  255 + String key = VideoManagerConstants.INVITE_PREFIX +
  256 + ":" + inviteInfo.getType() +
  257 + ":" + inviteInfo.getDeviceId() +
  258 + ":" + inviteInfo.getChannelId() +
  259 + ":" + inviteInfo.getStream() +
  260 + ":" + inviteInfo.getSsrcInfo().getSsrc();
  261 + if (inviteInfoInDb.getSsrcInfo() != null) {
  262 + inviteInfoInDb.getSsrcInfo().setSsrc(ssrc);
  263 + }
  264 + redisTemplate.opsForValue().set(key, inviteInfoInDb);
  265 + return inviteInfoInDb;
  266 + }
232 } 267 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -158,10 +158,7 @@ public class PlayServiceImpl implements IPlayService { @@ -158,10 +158,7 @@ public class PlayServiceImpl implements IPlayService {
158 } 158 }
159 } 159 }
160 } 160 }
161 - String streamId = null;  
162 - if (mediaServerItem.isRtpEnable()) {  
163 - streamId = String.format("%s_%s", device.getDeviceId(), channelId);  
164 - } 161 + String streamId = String.format("%s_%s", device.getDeviceId(), channelId);;
165 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam()); 162 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
166 if (ssrcInfo == null) { 163 if (ssrcInfo == null) {
167 callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); 164 callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
@@ -457,16 +454,13 @@ public class PlayServiceImpl implements IPlayService { @@ -457,16 +454,13 @@ public class PlayServiceImpl implements IPlayService {
457 logger.warn("[录像回放] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId); 454 logger.warn("[录像回放] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId);
458 throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流"); 455 throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流");
459 } 456 }
460 - String stream = null;  
461 - if (newMediaServerItem.isRtpEnable()) {  
462 - String startTimeStr = startTime.replace("-", "")  
463 - .replace(":", "")  
464 - .replace(" ", "");  
465 - String endTimeTimeStr = endTime.replace("-", "")  
466 - .replace(":", "")  
467 - .replace(" ", "");  
468 - stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr;  
469 - } 457 + String startTimeStr = startTime.replace("-", "")
  458 + .replace(":", "")
  459 + .replace(" ", "");
  460 + String endTimeTimeStr = endTime.replace("-", "")
  461 + .replace(":", "")
  462 + .replace(" ", "");
  463 + String stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr;
470 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam()); 464 SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
471 playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback); 465 playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback);
472 } 466 }
@@ -628,44 +622,13 @@ public class PlayServiceImpl implements IPlayService { @@ -628,44 +622,13 @@ public class PlayServiceImpl implements IPlayService {
628 if (ssrcInResponse != null) { 622 if (ssrcInResponse != null) {
629 // 单端口 623 // 单端口
630 // 重新订阅流上线 624 // 重新订阅流上线
631 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp",  
632 - ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());  
633 - subscribe.removeSubscribe(hookSubscribe);  
634 SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(inviteInfo.getDeviceId(), 625 SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(inviteInfo.getDeviceId(),
635 inviteInfo.getChannelId(), null, inviteInfo.getStream()); 626 inviteInfo.getChannelId(), null, inviteInfo.getStream());
636 streamSession.remove(inviteInfo.getDeviceId(), 627 streamSession.remove(inviteInfo.getDeviceId(),
637 inviteInfo.getChannelId(), inviteInfo.getStream()); 628 inviteInfo.getChannelId(), inviteInfo.getStream());
638 -  
639 - String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase();  
640 - hookSubscribe.getContent().put("stream", stream);  
641 -  
642 - inviteStreamService.updateInviteInfoForStream(inviteInfo, stream); 629 + inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
643 streamSession.put(device.getDeviceId(), channelId, ssrcTransaction.getCallId(), 630 streamSession.put(device.getDeviceId(), channelId, ssrcTransaction.getCallId(),
644 - stream, ssrcInResponse, mediaServerItem.getId(), (SIPResponse) responseEvent.getResponse(), inviteSessionType);  
645 - subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {  
646 - logger.info("[Invite 200OK] ssrc修正后收到订阅消息: " + hookParam);  
647 - dynamicTask.stop(timeOutTaskKey);  
648 - subscribe.removeSubscribe(hookSubscribe);  
649 - // hook响应  
650 - StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, hookParam, device.getDeviceId(), channelId);  
651 - if (streamInfo == null){  
652 - callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),  
653 - InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);  
654 - inviteStreamService.call(inviteSessionType, device.getDeviceId(), channelId, null,  
655 - InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),  
656 - InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);  
657 - return;  
658 - }  
659 - callback.run(InviteErrorCode.SUCCESS.getCode(),  
660 - InviteErrorCode.SUCCESS.getMsg(), streamInfo);  
661 - inviteStreamService.call(inviteSessionType, device.getDeviceId(), channelId, null,  
662 - InviteErrorCode.SUCCESS.getCode(),  
663 - InviteErrorCode.SUCCESS.getMsg(),  
664 - streamInfo);  
665 - if (inviteSessionType == InviteSessionType.PLAY) {  
666 - snapOnPlay(mediaServerItemInUse, device.getDeviceId(), channelId, stream);  
667 - }  
668 - }); 631 + inviteInfo.getStream(), ssrcInResponse, mediaServerItem.getId(), (SIPResponse) responseEvent.getResponse(), inviteSessionType);
669 } 632 }
670 } 633 }
671 } 634 }