|  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) { | 
|---|
|  |  |  | // 排除api文档的接口,这个接口不需要统一 | 
|---|
|  |  |  | String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook"}; | 
|---|
|  |  |  | String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook","/api/video-"}; | 
|---|
|  |  |  | for (String path : excludePath) { | 
|---|
|  |  |  | if (request.getURI().getPath().startsWith(path)) { | 
|---|
|  |  |  | return body; | 
|---|
|  |  |  | 
|---|
|  |  |  | * 防止返回string时出错 | 
|---|
|  |  |  | * @return | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Bean | 
|---|
|  |  |  | /*@Bean | 
|---|
|  |  |  | public HttpMessageConverters custHttpMessageConverter() { | 
|---|
|  |  |  | return new HttpMessageConverters(new FastJsonHttpMessageConverter()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }*/ | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public String getHookIp() { | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(hookIp)){ | 
|---|
|  |  |  | return sipIp.split(",")[0]; | 
|---|
|  |  |  | return sipIp; | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | return hookIp; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | package com.genersoft.iot.vmp.gb28181.bean; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import gov.nist.javax.sip.message.SIPRequest; | 
|---|
|  |  |  | import gov.nist.javax.sip.message.SIPResponse; | 
|---|
|  |  |  | import gov.nist.javax.sip.stack.SIPDialog; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.sip.Dialog; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 缓存语音广播的状态 | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setSipTransactionInfoByRequset(SIPResponse response) { | 
|---|
|  |  |  | this.sipTransactionInfo = new SipTransactionInfo(response); | 
|---|
|  |  |  | this.sipTransactionInfo = new SipTransactionInfo(response, false); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | package com.genersoft.iot.vmp.gb28181.bean; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import gov.nist.javax.sip.message.SIPRequest; | 
|---|
|  |  |  | import gov.nist.javax.sip.message.SIPResponse; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public class SipTransactionInfo { | 
|---|
|  |  |  | 
|---|
|  |  |  | private String toTag; | 
|---|
|  |  |  | private String viaBranch; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private boolean fromServer; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public SipTransactionInfo(SIPResponse response, boolean fromServer) { | 
|---|
|  |  |  | this.callId = response.getCallIdHeader().getCallId(); | 
|---|
|  |  |  | this.fromTag = response.getFromTag(); | 
|---|
|  |  |  | this.toTag = response.getToTag(); | 
|---|
|  |  |  | this.viaBranch = response.getTopmostViaHeader().getBranch(); | 
|---|
|  |  |  | this.fromServer = fromServer; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public SipTransactionInfo(SIPResponse response) { | 
|---|
|  |  |  | this.callId = response.getCallIdHeader().getCallId(); | 
|---|
|  |  |  | this.fromTag = response.getFromTag(); | 
|---|
|  |  |  | this.toTag = response.getToTag(); | 
|---|
|  |  |  | this.viaBranch = response.getTopmostViaHeader().getBranch(); | 
|---|
|  |  |  | this.fromServer = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public SipTransactionInfo() { | 
|---|
|  |  |  | 
|---|
|  |  |  | public void setViaBranch(String viaBranch) { | 
|---|
|  |  |  | this.viaBranch = viaBranch; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public boolean isFromServer() { | 
|---|
|  |  |  | return fromServer; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public void setFromServer(boolean fromServer) { | 
|---|
|  |  |  | this.fromServer = fromServer; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | package com.genersoft.iot.vmp.gb28181.session; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson2.JSON; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.common.VideoManagerConstants; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.conf.UserSetting; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | 
|---|
|  |  |  | 
|---|
|  |  |  | ssrcTransaction.setSsrc(ssrc); | 
|---|
|  |  |  | ssrcTransaction.setMediaServerId(mediaServerId); | 
|---|
|  |  |  | ssrcTransaction.setType(type); | 
|---|
|  |  |  | System.out.println(22222); | 
|---|
|  |  |  | System.out.println(JSON.toJSONString(ssrcTransaction)); | 
|---|
|  |  |  | RedisUtil.set(VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() | 
|---|
|  |  |  | + "_" +  deviceId + "_" + channelId + "_" + callId + "_" + stream, ssrcTransaction); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.Device; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | 
|---|
|  |  |  | 
|---|
|  |  |  | import javax.sip.InvalidArgumentException; | 
|---|
|  |  |  | import javax.sip.SipException; | 
|---|
|  |  |  | import java.text.ParseException; | 
|---|
|  |  |  | import javax.sip.message.Message; | 
|---|
|  |  |  | import javax.sip.message.Request; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * @description:设备能力接口,用于定义设备的控制、查询能力 | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public Request createByteRequest(Device device, String channelId, SipTransactionInfo transactionInfo) throws ParseException, InvalidArgumentException, PeerUnavailableException { | 
|---|
|  |  |  | Request request = null; | 
|---|
|  |  |  | //请求行 | 
|---|
|  |  |  | SipURI requestLine = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId, device.getHostAddress()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // via | 
|---|
|  |  |  | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); | 
|---|
|  |  |  | ViaHeader viaHeader = sipLayer.getSipFactory().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(device.getLocalIp()), sipConfig.getPort(), device.getTransport(), SipUtils.getNewViaTag()); | 
|---|
|  |  |  | 
|---|
|  |  |  | //from | 
|---|
|  |  |  | SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | 
|---|
|  |  |  | Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | 
|---|
|  |  |  | FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.getFromTag()); | 
|---|
|  |  |  | FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isFromServer()?transactionInfo.getFromTag():transactionInfo.getToTag()); | 
|---|
|  |  |  | //to | 
|---|
|  |  |  | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | 
|---|
|  |  |  | Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | 
|---|
|  |  |  | ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,    transactionInfo.getToTag()); | 
|---|
|  |  |  | ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,transactionInfo.isFromServer()?transactionInfo.getToTag():transactionInfo.getFromTag()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //Forwards | 
|---|
|  |  |  | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | 
|---|
|  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void streamByeCmd(Device device, String channelId, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException { | 
|---|
|  |  |  | Request byteRequest = headerProvider.createByteRequest(device, channelId, sipTransactionInfo); | 
|---|
|  |  |  | sipSender.transmitRequest(device.getTransport(), byteRequest, null, okEvent); | 
|---|
|  |  |  | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), byteRequest, null, okEvent); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 语音广播 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param device 视频设备 | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson2.JSONObject; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.conf.DynamicTask; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.Device; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; | 
|---|
|  |  |  | 
|---|
|  |  |  | param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | JSONObject jsonObject; | 
|---|
|  |  |  | if (sendRtpItem.isTcpActive()) { | 
|---|
|  |  |  | jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); | 
|---|
|  |  |  | if (mediaInfo == null) { | 
|---|
|  |  |  | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( | 
|---|
|  |  |  | sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(), | 
|---|
|  |  |  | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(), | 
|---|
|  |  |  | sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio()); | 
|---|
|  |  |  | redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> { | 
|---|
|  |  |  | startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, json, param, callIdHeader); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | param.put("is_udp", is_Udp); | 
|---|
|  |  |  | param.put("dst_url", sendRtpItem.getIp()); | 
|---|
|  |  |  | param.put("dst_port", sendRtpItem.getPort()); | 
|---|
|  |  |  | jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); | 
|---|
|  |  |  | System.out.println(JSON.toJSONString(param)); | 
|---|
|  |  |  | System.out.println(); | 
|---|
|  |  |  | System.out.println(jsonObject); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (jsonObject == null) { | 
|---|
|  |  |  | logger.error("RTP推流失败: 请检查ZLM服务"); | 
|---|
|  |  |  | } else if (jsonObject.getInteger("code") == 0) { | 
|---|
|  |  |  | logger.info("RTP推流成功[ {}/{} ],{}->{}:{}, ", param.get("app"), param.get("stream"), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port")); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | logger.error("RTP推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSON.toJSON(param)); | 
|---|
|  |  |  | if (sendRtpItem.isOnlyAudio()) { | 
|---|
|  |  |  | // 语音对讲 | 
|---|
|  |  |  | Device device = deviceService.getDevice(platformGbId); | 
|---|
|  |  |  | if (device != null) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | cmder.streamByeCmd(device, sendRtpItem.getChannelId(), sendRtpItem.getStreamId(), null); | 
|---|
|  |  |  | } catch (SipException | ParseException | InvalidArgumentException | | 
|---|
|  |  |  | SsrcTransactionNotFoundException e) { | 
|---|
|  |  |  | logger.error("[命令发送失败] 停止语音对讲: {}", e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // 向上级平台 | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId()); | 
|---|
|  |  |  | } catch (SipException | InvalidArgumentException | ParseException e) { | 
|---|
|  |  |  | logger.error("[命令发送失败] 国标级联, 回复BYE: {}", e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (mediaInfo == null) { | 
|---|
|  |  |  | RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( | 
|---|
|  |  |  | sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(), | 
|---|
|  |  |  | sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(), | 
|---|
|  |  |  | sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio()); | 
|---|
|  |  |  | redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> { | 
|---|
|  |  |  | startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, json, param, callIdHeader); | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | // 如果是非严格模式,需要关闭端口占用 | 
|---|
|  |  |  | JSONObject startSendRtpStreamResult = null; | 
|---|
|  |  |  | if (sendRtpItem.getLocalPort() != 0) { | 
|---|
|  |  |  | if (zlmrtpServerFactory.releasePort(mediaInfo, sendRtpItem.getSsrc())) { | 
|---|
|  |  |  | startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // 如果是非严格模式,需要关闭端口占用 | 
|---|
|  |  |  | JSONObject startSendRtpStreamResult = null; | 
|---|
|  |  |  | if (sendRtpItem.getLocalPort() != 0) { | 
|---|
|  |  |  | if (zlmrtpServerFactory.releasePort(mediaInfo, sendRtpItem.getSsrc())) { | 
|---|
|  |  |  | if (sendRtpItem.isTcpActive()) { | 
|---|
|  |  |  | startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | param.put("is_udp", is_Udp); | 
|---|
|  |  |  | param.put("dst_url", sendRtpItem.getIp()); | 
|---|
|  |  |  | param.put("dst_port", sendRtpItem.getPort()); | 
|---|
|  |  |  | startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (startSendRtpStreamResult != null) { | 
|---|
|  |  |  | startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | if (sendRtpItem.isTcpActive()) { | 
|---|
|  |  |  | startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | param.put("is_udp", is_Udp); | 
|---|
|  |  |  | param.put("dst_url", sendRtpItem.getIp()); | 
|---|
|  |  |  | param.put("dst_port", sendRtpItem.getPort()); | 
|---|
|  |  |  | startSendRtpStreamResult = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if (startSendRtpStreamResult != null) { | 
|---|
|  |  |  | startSendRtpStreamHand(evt, sendRtpItem, parentPlatform, startSendRtpStreamResult, param, callIdHeader); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | private void startSendRtpStreamHand(RequestEvent evt, SendRtpItem sendRtpItem, ParentPlatform parentPlatform, | 
|---|
|  |  |  | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | logger.error("RTP推流失败: {}, 参数:{}",jsonObject.getString("msg"), JSON.toJSONString(param)); | 
|---|
|  |  |  | if (sendRtpItem.isOnlyAudio()) { | 
|---|
|  |  |  | // TODO 可能是语音对讲 | 
|---|
|  |  |  | Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); | 
|---|
|  |  |  | AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | 
|---|
|  |  |  | if (audioBroadcastCatch != null) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); | 
|---|
|  |  |  | } catch (SipException | ParseException | InvalidArgumentException | | 
|---|
|  |  |  | SsrcTransactionNotFoundException e) { | 
|---|
|  |  |  | logger.error("[命令发送失败] 停止语音对讲: {}", e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | // 向上级平台 | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | 
|---|
|  |  |  | if (sendRtpItem != null){ | 
|---|
|  |  |  | logger.info("[收到bye] {}/{}", sendRtpItem.getPlatformId(), sendRtpItem.getChannelId()); | 
|---|
|  |  |  | String streamId = sendRtpItem.getStreamId(); | 
|---|
|  |  |  | MediaServerItem mediaServerItem = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 
|---|
|  |  |  | if (mediaServerItem == null) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), streamId); | 
|---|
|  |  |  | if (!ready) { | 
|---|
|  |  |  | logger.info("[收到bye] 发现流{}/{}已经结束,不需处理", sendRtpItem.getApp(), sendRtpItem.getStreamId()); | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Map<String, Object> param = new HashMap<>(); | 
|---|
|  |  |  | param.put("vhost","__defaultVhost__"); | 
|---|
|  |  |  | param.put("app",sendRtpItem.getApp()); | 
|---|
|  |  |  | 
|---|
|  |  |  | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | 
|---|
|  |  |  | redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), callIdHeader.getCallId(), null); | 
|---|
|  |  |  | zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); | 
|---|
|  |  |  | if (totalReaderCount <= 0) { | 
|---|
|  |  |  | logger.info("[收到bye] {} 无其它观看者,通知设备停止推流", streamId); | 
|---|
|  |  |  | 
|---|
|  |  |  | redisCatchStorage.sendStreamPushRequestedMsg(messageForPushChannel); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | playService.stopAudioBroadcast(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; | 
|---|
|  |  |  | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; | 
|---|
|  |  |  | 
|---|
|  |  |  | private IMediaServerService mediaServerService; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private IMediaService mediaService; | 
|---|
|  |  |  | private ISIPCommander commander; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private ZLMRESTfulUtils zlmresTfulUtils; | 
|---|
|  |  |  | 
|---|
|  |  |  | String stream = device.getDeviceId() + "_" + audioBroadcastCatch.getChannelId(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME); | 
|---|
|  |  |  | sendRtpItem.setPlayType(InviteStreamType.PLAY); | 
|---|
|  |  |  | sendRtpItem.setPlayType(InviteStreamType.TALK); | 
|---|
|  |  |  | sendRtpItem.setCallId(callIdHeader.getCallId()); | 
|---|
|  |  |  | sendRtpItem.setPlatformId(requesterId); | 
|---|
|  |  |  | sendRtpItem.setStatus(1); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, app, stream); | 
|---|
|  |  |  | if (streamReady) { | 
|---|
|  |  |  | SIPResponse sipResponse = sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, ssrc); | 
|---|
|  |  |  | // 添加事务信息 | 
|---|
|  |  |  | streamSession.put(device.getDeviceId(), audioBroadcastCatch.getChannelId(), request.getCallIdHeader().getCallId() | 
|---|
|  |  |  | , stream,  sendRtpItem.getSsrc(), mediaServerItem.getId(), sipResponse, VideoStreamSessionManager.SessionType.broadcast ); | 
|---|
|  |  |  | sendOk(device, sendRtpItem, sdp, request, mediaServerItem, mediaTransmissionTCP, ssrc); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | logger.warn("[语音通话], 未发现待推送的流,app={},stream={}", app, stream); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | responseAck(request, Response.GONE); | 
|---|
|  |  |  | } catch (SipException | InvalidArgumentException | ParseException e) { | 
|---|
|  |  |  | logger.error("[命令发送失败] 语音通话 回复410失败, {}", e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (SdpException e) { | 
|---|
|  |  |  | 
|---|
|  |  |  | if (platform != null) { | 
|---|
|  |  |  | commanderFroPlatform.streamByeCmd(platform, sendRtpItem); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | if ("talk".equals(param.getApp()) && sendRtpItem.isOnlyAudio()) { | 
|---|
|  |  |  | if (sendRtpItem.isOnlyAudio()) { | 
|---|
|  |  |  | AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); | 
|---|
|  |  |  | if (device != null && audioBroadcastCatch != null) { | 
|---|
|  |  |  | //                                            cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); | 
|---|
|  |  |  | if (audioBroadcastCatch != null) { | 
|---|
|  |  |  | //                                            playService.stopAudioBroadcast(device.getDeviceId(), sendRtpItem.getChannelId()); | 
|---|
|  |  |  | if ("talk".equals(param.getApp())) { | 
|---|
|  |  |  | //                                                cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | //                                                cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | cmder.streamByeCmd(device, null, null, sendRtpItem.getCallId()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (SipException | InvalidArgumentException | ParseException | SsrcTransactionNotFoundException e) { | 
|---|
|  |  |  | } catch (SipException | InvalidArgumentException | ParseException e) { | 
|---|
|  |  |  | logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 
|---|
|  |  |  | if (device == null) { | 
|---|
|  |  |  | return; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //            if (audioBroadcastCatch.getStatus() == AudioBroadcastCatchStatus.Ok) { | 
|---|
|  |  |  | //                cmder.streamByeCmd(device, audioBroadcastCatch.getChannelId(), null, audioBroadcastCatch.getSipTransactionInfo().getCallId()); | 
|---|
|  |  |  | //            } | 
|---|
|  |  |  | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null); | 
|---|
|  |  |  | if (sendRtpItem != null) { | 
|---|
|  |  |  | redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null); | 
|---|
|  |  |  | 
|---|
|  |  |  | deviceAlarm.setAlarmPriority("1"); | 
|---|
|  |  |  | deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); | 
|---|
|  |  |  | deviceAlarm.setAlarmType("1"); | 
|---|
|  |  |  | deviceAlarm.setLongitude(0); | 
|---|
|  |  |  | deviceAlarm.setLatitude(0); | 
|---|
|  |  |  | deviceAlarm.setLongitude(0D); | 
|---|
|  |  |  | deviceAlarm.setLatitude(0D); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (ObjectUtils.isEmpty(gbId)) { | 
|---|
|  |  |  | // 发送给所有的上级 | 
|---|