| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.ParseException; |
| | | import java.util.*; |
| | | |
| | | import javax.sip.InvalidArgumentException; |
| | | import javax.sip.ResponseEvent; |
| | | import javax.sip.SipException; |
| | | |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.service.IDeviceService; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | 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.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; |
| | | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamInfo; |
| | | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; |
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| | | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| | |
| | | |
| | | @Autowired |
| | | private VideoStreamSessionManager streamSession; |
| | | |
| | | |
| | | @Autowired |
| | | private IDeviceService deviceService; |
| | | |
| | | @Autowired |
| | | private UserSetting userSetting; |
| | |
| | | System.out.println("设置超时任务: " + timeOutTaskKey); |
| | | dynamicTask.startDelay( timeOutTaskKey,()->{ |
| | | |
| | | SIPDialog dialog = streamSession.getDialogByStream(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | if (dialog != null) { |
| | | logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc()); |
| | | timeoutCallback.run(1, "收流超时"); |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, finalSsrcInfo.getStream(), null); |
| | | }else { |
| | | logger.info("[点播超时] 消息未响应 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, finalSsrcInfo.getPort(), finalSsrcInfo.getSsrc()); |
| | | try { |
| | | cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null); |
| | | } catch (InvalidArgumentException | ParseException | SipException e) { |
| | | logger.error("[点播超时], 发送BYE失败 {}", e.getMessage()); |
| | | } catch (SsrcTransactionNotFoundException e) { |
| | | timeoutCallback.run(0, "点播超时"); |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream()); |
| | |
| | | logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo); |
| | | return; |
| | | } |
| | | try { |
| | | cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { |
| | | logger.info("收到订阅消息: " + response.toJSONString()); |
| | | System.out.println("停止超时任务: " + timeOutTaskKey); |
| | |
| | | streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | errorEvent.response(event); |
| | | }); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | |
| | | logger.error("[命令发送失败] 点播消息: {}", e.getMessage()); |
| | | dynamicTask.stop(timeOutTaskKey); |
| | | mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream()); |
| | | // 释放ssrc |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc()); |
| | | |
| | | streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream()); |
| | | SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null)); |
| | | eventResult.msg = "命令发送失败"; |
| | | errorEvent.response(eventResult); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | playBackResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | playBackResult.setMsg("回放超时"); |
| | | playBackResult.setData(requestMessage); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | |
| | | try { |
| | | cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null); |
| | | } catch (InvalidArgumentException | ParseException | SipException e) { |
| | | logger.error("[录像流]回放超时 发送BYE失败 {}", e.getMessage()); |
| | | } catch (SsrcTransactionNotFoundException e) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | }else { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | |
| | | // 回复之前所有的点播请求 |
| | | playBackCallback.call(playBackResult); |
| | | result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "回放超时")); |
| | |
| | | playBackCallback.call(playBackResult); |
| | | }; |
| | | |
| | | try { |
| | | cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack, |
| | | hookEvent, eventResult -> { |
| | | if (eventResult.type == SipSubscribe.EventResultType.response) { |
| | |
| | | } |
| | | |
| | | }, errorEvent); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | logger.error("[命令发送失败] 回放: {}", e.getMessage()); |
| | | |
| | | SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null)); |
| | | eventResult.msg = "命令发送失败"; |
| | | errorEvent.response(eventResult); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | |
| | | downloadResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | downloadResult.setMsg("录像下载请求超时"); |
| | | hookCallBack.call(downloadResult); |
| | | SIPDialog dialog = streamSession.getDialogByStream(deviceId, channelId, ssrcInfo.getStream()); |
| | | |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | if (dialog != null) { |
| | | // 点播超时回复BYE 同时释放ssrc以及此次点播的资源 |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | }else { |
| | | try { |
| | | cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null); |
| | | } catch (InvalidArgumentException | ParseException | SipException e) { |
| | | logger.error("[录像流]录像下载请求超时, 发送BYE失败 {}", e.getMessage()); |
| | | } catch (SsrcTransactionNotFoundException e) { |
| | | mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); |
| | | mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); |
| | | streamSession.remove(deviceId, channelId, ssrcInfo.getStream()); |
| | | } |
| | | cmder.streamByeCmd(device.getDeviceId(), channelId, ssrcInfo.getStream(), null); |
| | | // 回复之前所有的点播请求 |
| | | hookCallBack.call(downloadResult); |
| | | }, userSetting.getPlayTimeout()); |
| | | |
| | | SipSubscribe.Event errorEvent = event -> { |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | downloadResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | wvpResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | downloadResult.setEvent(event); |
| | | hookCallBack.call(downloadResult); |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | }; |
| | | |
| | | try { |
| | | cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack, |
| | | inviteStreamInfo -> { |
| | | logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString()); |
| | |
| | | downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); |
| | | downloadResult.setResponse(inviteStreamInfo.getResponse()); |
| | | hookCallBack.call(downloadResult); |
| | | }, event -> { |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | downloadResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | downloadResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | wvpResult.setCode(ErrorCode.ERROR100.getCode()); |
| | | wvpResult.setMsg(String.format("录像下载失败, 错误码: %s, %s", event.statusCode, event.msg)); |
| | | downloadResult.setEvent(event); |
| | | hookCallBack.call(downloadResult); |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | }); |
| | | }, errorEvent); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); |
| | | |
| | | SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null)); |
| | | eventResult.msg = "命令发送失败"; |
| | | errorEvent.response(eventResult); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | |
| | | for (SendRtpItem sendRtpItem : sendRtpItems) { |
| | | if (sendRtpItem.getMediaServerId().equals(mediaServerId)) { |
| | | ParentPlatform platform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); |
| | | try { |
| | | sipCommanderFroPlatform.streamByeCmd(platform, sendRtpItem.getCallId()); |
| | | } catch (SipException | InvalidArgumentException | ParseException e) { |
| | | logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | if (allSsrc.size() > 0) { |
| | | for (SsrcTransaction ssrcTransaction : allSsrc) { |
| | | if(ssrcTransaction.getMediaServerId().equals(mediaServerId)) { |
| | | cmder.streamByeCmd(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), |
| | | Device device = deviceService.queryDevice(ssrcTransaction.getDeviceId()); |
| | | if (device == null) { |
| | | continue; |
| | | } |
| | | try { |
| | | cmder.streamByeCmd(device, ssrcTransaction.getChannelId(), |
| | | ssrcTransaction.getStream(), null); |
| | | } catch (InvalidArgumentException | ParseException | SipException | |
| | | SsrcTransactionNotFoundException e) { |
| | | logger.error("[zlm离线]为正在使用此zlm的设备, 发送BYE失败 {}", e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | } |