| 
						
						
							
								
							
						
						
					 | 
					@ -5,13 +5,13 @@ import com.alibaba.fastjson.JSONArray; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.alibaba.fastjson.JSONObject; | 
					 | 
					 | 
					import com.alibaba.fastjson.JSONObject; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.common.StreamInfo; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.common.StreamInfo; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.conf.UserSetup; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.conf.UserSetup; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.bean.Device; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.bean.*; | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookSubscribe; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 
					 | 
					 | 
					import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -37,8 +37,7 @@ import org.springframework.util.ResourceUtils; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import org.springframework.web.context.request.async.DeferredResult; | 
					 | 
					 | 
					import org.springframework.web.context.request.async.DeferredResult; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import java.io.FileNotFoundException; | 
					 | 
					 | 
					import java.io.FileNotFoundException; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					import java.util.Objects; | 
					 | 
					 | 
					import java.util.*; | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					import java.util.UUID; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					@SuppressWarnings(value = {"rawtypes", "unchecked"}) | 
					 | 
					 | 
					@SuppressWarnings(value = {"rawtypes", "unchecked"}) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					@Service | 
					 | 
					 | 
					@Service | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -52,6 +51,9 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    @Autowired | 
					 | 
					 | 
					    @Autowired | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    private SIPCommander cmder; | 
					 | 
					 | 
					    private SIPCommander cmder; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    @Autowired | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    private SIPCommanderFroPlatform sipCommanderFroPlatform; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    @Autowired | 
					 | 
					 | 
					    @Autowired | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    private IRedisCatchStorage redisCatchStorage; | 
					 | 
					 | 
					    private IRedisCatchStorage redisCatchStorage; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -78,7 +80,9 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    @Override | 
					 | 
					 | 
					    @Override | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent) { | 
					 | 
					 | 
					    public PlayResult play(MediaServerItem mediaServerItem, String deviceId, String channelId, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                           ZLMHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                           Runnable timeoutCallback) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        PlayResult playResult = new PlayResult(); | 
					 | 
					 | 
					        PlayResult playResult = new PlayResult(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        RequestMessage msg = new RequestMessage(); | 
					 | 
					 | 
					        RequestMessage msg = new RequestMessage(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; | 
					 | 
					 | 
					        String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -101,29 +105,10 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        Device device = redisCatchStorage.getDevice(deviceId); | 
					 | 
					 | 
					        Device device = redisCatchStorage.getDevice(deviceId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); | 
					 | 
					 | 
					        StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        playResult.setDevice(device); | 
					 | 
					 | 
					        playResult.setDevice(device); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        // 超时处理
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        result.onTimeout(()->{ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            WVPResult wvpResult = new WVPResult(); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            wvpResult.setCode(-1); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, streamInfo.getStream()); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (dialog != null) { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                wvpResult.setMsg("收流超时,请稍候重试"); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            }else { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                wvpResult.setMsg("点播超时,请稍候重试"); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            msg.setData(wvpResult); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // 点播超时回复BYE
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            cmder.streamByeCmd(device.getDeviceId(), channelId, streamInfo.getStream()); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // 释放rtpserver
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, streamInfo.getStream()); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // 回复之前所有的点播请求
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            resultHolder.invokeAllResult(msg); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // TODO 释放ssrc
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        }); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        result.onCompletion(()->{ | 
					 | 
					 | 
					        result.onCompletion(()->{ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // 点播结束时调用截图接口
 | 
					 | 
					 | 
					            // 点播结束时调用截图接口
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // TODO 应该在上流时调用更好,结束也可能是错误结束
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            try { | 
					 | 
					 | 
					            try { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                String classPath = ResourceUtils.getURL("classpath:").getPath(); | 
					 | 
					 | 
					                String classPath = ResourceUtils.getURL("classpath:").getPath(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                // 兼容打包为jar的class路径
 | 
					 | 
					 | 
					                // 兼容打包为jar的class路径
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -161,31 +146,60 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (mediaServerItem.isRtpEnable()) { | 
					 | 
					 | 
					            if (mediaServerItem.isRtpEnable()) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                streamId = String.format("%s_%s", device.getDeviceId(), channelId); | 
					 | 
					 | 
					                streamId = String.format("%s_%s", device.getDeviceId(), channelId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            } | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); | 
					 | 
					 | 
					            SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            // 超时处理
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            Timer timer = new Timer(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            timer.schedule(new TimerTask() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                @Override | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                public void run() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    if (timeoutCallback != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        timeoutCallback.run(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    WVPResult wvpResult = new WVPResult(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    wvpResult.setCode(-1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    if (dialog != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        wvpResult.setMsg("收流超时,请稍候重试"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    }else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        wvpResult.setMsg("点播超时,请稍候重试"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    msg.setData(wvpResult); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    // 回复之前所有的点播请求
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    resultHolder.invokeAllResult(msg); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            }, userSetup.getPlayTimeout()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            // 发送点播消息
 | 
					 | 
					 | 
					            // 发送点播消息
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { | 
					 | 
					 | 
					            cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                logger.info("收到订阅消息: " + response.toJSONString()); | 
					 | 
					 | 
					                logger.info("收到订阅消息: " + response.toJSONString()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                timer.cancel(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid); | 
					 | 
					 | 
					                onPublishHandlerForPlay(mediaServerItemInUse, response, deviceId, channelId, uuid); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                if (hookEvent != null) { | 
					 | 
					 | 
					                if (hookEvent != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    hookEvent.response(mediaServerItem, response); | 
					 | 
					 | 
					                    hookEvent.response(mediaServerItem, response); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                } | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            }, (event) -> { | 
					 | 
					 | 
					            }, (event) -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                timer.cancel(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                WVPResult wvpResult = new WVPResult(); | 
					 | 
					 | 
					                WVPResult wvpResult = new WVPResult(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                wvpResult.setCode(-1); | 
					 | 
					 | 
					                wvpResult.setCode(-1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                // 点播返回sip错误
 | 
					 | 
					 | 
					                // 点播返回sip错误
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); | 
					 | 
					 | 
					                mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                // 释放ssrc
 | 
					 | 
					 | 
					                // 释放ssrc
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); | 
					 | 
					 | 
					                mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
					 | 
					 | 
					                streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); | 
					 | 
					 | 
					                wvpResult.setMsg(String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                msg.setData(wvpResult); | 
					 | 
					 | 
					                msg.setData(wvpResult); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                resultHolder.invokeAllResult(msg); | 
					 | 
					 | 
					                resultHolder.invokeAllResult(msg); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                if (errorEvent != null) { | 
					 | 
					 | 
					                if (errorEvent != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    errorEvent.response(event); | 
					 | 
					 | 
					                    errorEvent.response(event); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                } | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            }); | 
					 | 
					 | 
					            }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } else { | 
					 | 
					 | 
					        } else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            String streamId = streamInfo.getStream(); | 
					 | 
					 | 
					            String streamId = streamInfo.getStream(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -222,13 +236,41 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); | 
					 | 
					 | 
					                    streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                } | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); | 
					 | 
					 | 
					                SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId2); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                // 超时处理
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                Timer timer = new Timer(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                timer.schedule(new TimerTask() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    @Override | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    public void run() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        if (timeoutCallback != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            timeoutCallback.run(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        WVPResult wvpResult = new WVPResult(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        wvpResult.setCode(-1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        if (dialog != null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            wvpResult.setMsg("收流超时,请稍候重试"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        }else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            wvpResult.setMsg("点播超时,请稍候重试"); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            mediaServerService.closeRTPServer(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                            streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        msg.setData(wvpResult); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        // 回复之前所有的点播请求
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        resultHolder.invokeAllResult(msg); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                }, userSetup.getPlayTimeout()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { | 
					 | 
					 | 
					                cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    logger.info("收到订阅消息: " + response.toJSONString()); | 
					 | 
					 | 
					                    logger.info("收到订阅消息: " + response.toJSONString()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); | 
					 | 
					 | 
					                    onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                }, (event) -> { | 
					 | 
					 | 
					                }, (event) -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); | 
					 | 
					 | 
					                    mediaServerService.closeRTPServer(playResult.getDevice().getDeviceId(), channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    // 释放ssrc
 | 
					 | 
					 | 
					                    // 释放ssrc
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    mediaServerService.releaseSsrc(mediaServerItem, ssrcInfo.getSsrc()); | 
					 | 
					 | 
					                    mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                    streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
					 | 
					 | 
					                    streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    WVPResult wvpResult = new WVPResult(); | 
					 | 
					 | 
					                    WVPResult wvpResult = new WVPResult(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    wvpResult.setCode(-1); | 
					 | 
					 | 
					                    wvpResult.setCode(-1); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -306,14 +348,23 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        msg.setId(uuid); | 
					 | 
					 | 
					        msg.setId(uuid); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        msg.setKey(key); | 
					 | 
					 | 
					        msg.setKey(key); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); | 
					 | 
					 | 
					        PlayBackResult<RequestMessage> playBackResult = new PlayBackResult<>(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        result.onTimeout(()->{ | 
					 | 
					 | 
					        Timer timer = new Timer(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					            msg.setData("回放超时"); | 
					 | 
					 | 
					        timer.schedule(new TimerTask() { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            @Override | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            public void run() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                logger.warn(String.format("设备回放超时,deviceId:%s ,channelId:%s", deviceId, channelId)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                playBackResult.setCode(-1); | 
					 | 
					 | 
					                playBackResult.setCode(-1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                playBackResult.setData(msg); | 
					 | 
					 | 
					                playBackResult.setData(msg); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                callback.call(playBackResult); | 
					 | 
					 | 
					                callback.call(playBackResult); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        }); | 
					 | 
					 | 
					                // 点播超时回复BYE 同时释放ssrc以及此次点播的资源
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                // 回复之前所有的点播请求
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                callback.call(playBackResult); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        }, userSetup.getPlayTimeout()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { | 
					 | 
					 | 
					        cmder.playbackStreamCmd(newMediaServerItem, ssrcInfo, device, channelId, startTime, endTime, (MediaServerItem mediaServerItem, JSONObject response) -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            logger.info("收到订阅消息: " + response.toJSONString()); | 
					 | 
					 | 
					            logger.info("收到订阅消息: " + response.toJSONString()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            timer.cancel(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); | 
					 | 
					 | 
					            StreamInfo streamInfo = onPublishHandler(mediaServerItem, response, deviceId, channelId); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if (streamInfo == null) { | 
					 | 
					 | 
					            if (streamInfo == null) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                logger.warn("设备回放API调用失败!"); | 
					 | 
					 | 
					                logger.warn("设备回放API调用失败!"); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -331,6 +382,7 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            playBackResult.setResponse(response); | 
					 | 
					 | 
					            playBackResult.setResponse(response); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            callback.call(playBackResult); | 
					 | 
					 | 
					            callback.call(playBackResult); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        }, event -> { | 
					 | 
					 | 
					        }, event -> { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            timer.cancel(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); | 
					 | 
					 | 
					            msg.setData(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            playBackResult.setCode(-1); | 
					 | 
					 | 
					            playBackResult.setCode(-1); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            playBackResult.setData(msg); | 
					 | 
					 | 
					            playBackResult.setData(msg); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -370,4 +422,26 @@ public class PlayServiceImpl implements IPlayService { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        return streamInfo; | 
					 | 
					 | 
					        return streamInfo; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    @Override | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    public void zlmServerOffline(String mediaServerId) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        // 处理正在向上推流的上级平台
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServer(null); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (sendRtpItems.size() > 0) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            for (SendRtpItem sendRtpItem : sendRtpItems) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if (sendRtpItem.getMediaServerId().equals(mediaServerId)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        // 处理正在观看的国标设备
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        List<SsrcTransaction> allSsrc = streamSession.getAllSsrc(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (allSsrc.size() > 0) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            for (SsrcTransaction ssrcTransaction : allSsrc) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream()); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |