| | |
| | | private String toTag; |
| | | private String viaBranch; |
| | | |
| | | private boolean fromServer; |
| | | // 自己是否媒体流发送者 |
| | | private boolean asSender; |
| | | |
| | | public SipTransactionInfo(SIPResponse response, boolean fromServer) { |
| | | public SipTransactionInfo(SIPResponse response, boolean asSender) { |
| | | this.callId = response.getCallIdHeader().getCallId(); |
| | | this.fromTag = response.getFromTag(); |
| | | this.toTag = response.getToTag(); |
| | | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| | | this.fromServer = fromServer; |
| | | this.asSender = asSender; |
| | | } |
| | | |
| | | public SipTransactionInfo(SIPResponse response) { |
| | |
| | | this.fromTag = response.getFromTag(); |
| | | this.toTag = response.getToTag(); |
| | | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| | | this.fromServer = true; |
| | | } |
| | | |
| | | public SipTransactionInfo() { |
| | |
| | | this.viaBranch = viaBranch; |
| | | } |
| | | |
| | | public boolean isFromServer() { |
| | | return fromServer; |
| | | public boolean isAsSender() { |
| | | return asSender; |
| | | } |
| | | |
| | | public void setFromServer(boolean fromServer) { |
| | | this.fromServer = fromServer; |
| | | public void setAsSender(boolean asSender) { |
| | | this.asSender = asSender; |
| | | } |
| | | } |
| | |
| | | //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.isFromServer()?transactionInfo.getFromTag():transactionInfo.getToTag());
|
| | | FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isAsSender()? 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.isFromServer()?transactionInfo.getToTag():transactionInfo.getFromTag());
|
| | | ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, transactionInfo.isAsSender()?transactionInfo.getToTag():transactionInfo.getFromTag());
|
| | |
|
| | | //Forwards
|
| | | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
|
| | |
| | | CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
|
| | | CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
|
| | | request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
|
| | |
|
| | | request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
|
| | |
|
| | | Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort()));
|
| | | request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
|
| | |
|
| | | request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
|
| | |
|
| | |
| | | */
|
| | | @Override
|
| | | public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
|
| | | SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callId, stream);
|
| | | SsrcTransaction ssrcTransaction;
|
| | | if (callId != null) {
|
| | | ssrcTransaction = streamSession.getSsrcTransaction(null, null, callId, null);
|
| | | }else {
|
| | | ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, null, stream);
|
| | | }
|
| | | if (ssrcTransaction == null) {
|
| | | throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream);
|
| | | }
|
| | |
| | | return; |
| | | } |
| | | String result = getText(rootElement, "Result"); |
| | | logger.info("[语音广播]回复:{}, {}/{}", result, device.getDeviceId(), channelId ); |
| | | Element infoElement = rootElement.element("Info"); |
| | | String reason = null; |
| | | if (infoElement != null) { |
| | | reason = getText(infoElement, "Reason"); |
| | | } |
| | | logger.info("[语音广播]回复:{}, {}/{}", reason == null? result : result + ": " + reason, device.getDeviceId(), channelId ); |
| | | |
| | | // 回复200 OK |
| | | responseAck(request, Response.OK); |
| | |
| | | }
|
| | | }else if ("broadcast".equals(param.getApp())){
|
| | | // 语音对讲推流 stream需要满足格式deviceId_channelId
|
| | | if (param.isRegist() && param.getStream().indexOf("_") > 0) {
|
| | | if (param.getStream().indexOf("_") > 0) {
|
| | | String[] streamArray = param.getStream().split("_");
|
| | | if (streamArray.length == 2) {
|
| | | String deviceId = streamArray[0];
|
| | | String channelId = streamArray[1];
|
| | | Device device = deviceService.getDevice(deviceId);
|
| | | if (device != null) {
|
| | | DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
| | | if (deviceChannel != null) {
|
| | | if (param.isRegist()) {
|
| | | if (audioBroadcastManager.exit(deviceId, channelId)) {
|
| | | // 直接推流
|
| | | SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null);
|
| | | if (sendRtpItem == null) {
|
| | | // TODO 可能数据错误,重新开启语音通道
|
| | | }else {
|
| | | String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
|
| | | MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
| | | logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
|
| | | Map<String, Object> sendParam = new HashMap<>(12);
|
| | | sendParam.put("vhost","__defaultVhost__");
|
| | | sendParam.put("app",sendRtpItem.getApp());
|
| | | sendParam.put("stream",sendRtpItem.getStreamId());
|
| | | sendParam.put("ssrc", sendRtpItem.getSsrc());
|
| | | sendParam.put("src_port", sendRtpItem.getLocalPort());
|
| | | sendParam.put("pt", sendRtpItem.getPt());
|
| | | sendParam.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
|
| | | sendParam.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
|
| | |
|
| | | JSONObject jsonObject;
|
| | | if (sendRtpItem.isTcpActive()) {
|
| | | jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, sendParam);
|
| | | } else {
|
| | | sendParam.put("is_udp", is_Udp);
|
| | | sendParam.put("dst_url", sendRtpItem.getIp());
|
| | | sendParam.put("dst_port", sendRtpItem.getPort());
|
| | | jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, sendParam);
|
| | | }
|
| | | if (jsonObject != null && jsonObject.getInteger("code") == 0) {
|
| | | logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
|
| | | }else {
|
| | | logger.info("[语音对讲] 推流失败, 结果: {}", jsonObject);
|
| | | }
|
| | |
|
| | | }
|
| | | }else {
|
| | | // 开启语音对讲通道
|
| | | try {
|
| | | playService.audioBroadcastCmd(device, channelId, 60, (msg)->{
|
| | | logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
| | | });
|
| | | } catch (InvalidArgumentException | ParseException | SipException e) {
|
| | | logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
|
| | | }
|
| | | playService.stopAudioBroadcast(deviceId, channelId);
|
| | | }
|
| | |
|
| | | // 开启语音对讲通道
|
| | | try {
|
| | | playService.audioBroadcastCmd(device, channelId, 60, (msg)->{
|
| | | logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
| | | });
|
| | | } catch (InvalidArgumentException | ParseException | SipException e) {
|
| | | logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
|
| | | }
|
| | | }else {
|
| | | logger.info("[语音对讲] 未找到通道:{}", channelId);
|
| | | // 流注销
|
| | | playService.stopAudioBroadcast(deviceId, channelId);
|
| | | }
|
| | | }else{
|
| | | } else{
|
| | | logger.info("[语音对讲] 未找到设备:{}", deviceId);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | }else if ("talk".equals(param.getApp())){
|
| | | // 语音对讲推流 stream需要满足格式deviceId_channelId
|
| | | if (param.isRegist() && param.getStream().indexOf("_") > 0) {
|
| | |
| | | param.put("app", sendRtpItem.getApp()); |
| | | param.put("stream", sendRtpItem.getStreamId()); |
| | | zlmresTfulUtils.stopSendRtp(mediaInfo, param); |
| | | try { |
| | | cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); |
| | | } catch (InvalidArgumentException | ParseException | SipException | |
| | | SsrcTransactionNotFoundException e) { |
| | | logger.error("[消息发送失败] 发送语音喊话BYE失败"); |
| | | } |
| | | } |
| | | |
| | | audioBroadcastManager.del(deviceId, channelId); |