| 
					
				 | 
			
			
				@@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.alibaba.fastjson2.JSONObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.conf.DynamicTask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.conf.UserSetting; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.genersoft.iot.vmp.gb28181.bean.Device; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -10,9 +11,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.genersoft.iot.vmp.service.IDeviceService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.service.IMediaServerService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.service.IPlayService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.genersoft.iot.vmp.service.bean.RequestPushStreamMsg; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -62,6 +62,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	@Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	private IVideoManagerStorage storager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	@Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	private IDeviceService deviceService; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	@Autowired 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	private ZLMRTPServerFactory zlmrtpServerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -87,40 +90,23 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	@Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	public void process(RequestEvent evt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		CallIdHeader callIdHeader = (CallIdHeader)evt.getRequest().getHeader(CallIdHeader.NAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		String platformGbId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		logger.info("[收到ACK]: platformGbId->{}", platformGbId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		if (userSetting.getPushStreamAfterAck()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(platformGbId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			// 取消设置的超时任务 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			dynamicTask.stop(callIdHeader.getCallId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			String channelId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (sendRtpItem == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				logger.warn("[收到ACK]:未找到通道({})的推流信息", channelId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			String isUdp = sendRtpItem.isTcp() ? "0" : "1"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			logger.info("收到ACK,rtp/{}开始级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			Map<String, Object> param = new HashMap<>(12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("vhost","__defaultVhost__"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("app",sendRtpItem.getApp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("stream",sendRtpItem.getStream()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("ssrc", sendRtpItem.getSsrc()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("dst_url",sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("src_port", sendRtpItem.getLocalPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("pt", sendRtpItem.getPt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			param.put("is_udp", isUdp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			if (!sendRtpItem.isTcp()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// udp模式下开启rtcp保活 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		String fromUserId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		String toUserId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		logger.info("[收到ACK]: 来自->{}", fromUserId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(null, null, null, callIdHeader.getCallId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (sendRtpItem == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			logger.warn("[收到ACK]:未找到来自{},目标为({})的推流信息",fromUserId, toUserId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		logger.info("[收到ACK]:rtp/{}开始级推流, 目标={}:{},SSRC={}, RTCP={}", sendRtpItem.getStream(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// 取消设置的超时任务 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dynamicTask.stop(callIdHeader.getCallId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(fromUserId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (parentPlatform != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Map<String, Object> param = getSendRtpParam(sendRtpItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if (mediaInfo == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(), 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -130,30 +116,75 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, json, param, callIdHeader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 如果是非严格模式,需要关闭端口占用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				JSONObject startSendRtpStreamResult = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				if (sendRtpItem.getLocalPort() != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (sendRtpItem.isTcpActive()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						param.put("dst_url", sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					if (sendRtpItem.isTcpActive()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						param.put("dst_url", sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (startSendRtpStreamResult != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					playService.startSendRtpStreamHand(sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Device device = deviceService.getDevice(fromUserId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (device == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				logger.warn("[收到ACK]:来自{},目标为({})的推流信息为找到流体服务[{}]信息",fromUserId, toUserId, sendRtpItem.getMediaServerId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// 设置为收到ACK后发送语音的设备已经在发送200OK开始发流了 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (!device.isBroadcastPushAfterAck()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (mediaInfo == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				logger.warn("[收到ACK]:来自{},目标为({})的推流信息为找到流体服务[{}]信息",fromUserId, toUserId, sendRtpItem.getMediaServerId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			Map<String, Object> param = getSendRtpParam(sendRtpItem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			JSONObject startSendRtpStreamResult = sendRtp(sendRtpItem, mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (startSendRtpStreamResult != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				playService.startSendRtpStreamHand(sendRtpItem, device, startSendRtpStreamResult, param, callIdHeader); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	private Map<String, Object> getSendRtpParam(SendRtpItem sendRtpItem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		String isUdp = sendRtpItem.isTcp() ? "0" : "1"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Map<String, Object> param = new HashMap<>(12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("vhost","__defaultVhost__"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("app",sendRtpItem.getApp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("stream",sendRtpItem.getStream()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("ssrc", sendRtpItem.getSsrc()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("dst_url",sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("src_port", sendRtpItem.getLocalPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("pt", sendRtpItem.getPt()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		param.put("is_udp", isUdp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (!sendRtpItem.isTcp()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// udp模式下开启rtcp保活 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return param; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	private JSONObject sendRtp(SendRtpItem sendRtpItem, MediaServerItem mediaInfo, Map<String, Object> param){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		JSONObject startSendRtpStreamResult = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (sendRtpItem.getLocalPort() != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (sendRtpItem.isTcpActive()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				param.put("dst_url", sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if (sendRtpItem.isTcpActive()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				param.put("dst_url", sendRtpItem.getIp()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				param.put("dst_port", sendRtpItem.getPort()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return startSendRtpStreamResult; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |