Commit e14cef80624602d873b1062aed93022b8ad13182
1 parent
16f3b055
优化语音对讲
Showing
6 changed files
with
42 additions
and
67 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java
| ... | ... | @@ -9,14 +9,15 @@ public class SipTransactionInfo { |
| 9 | 9 | private String toTag; |
| 10 | 10 | private String viaBranch; |
| 11 | 11 | |
| 12 | - private boolean fromServer; | |
| 12 | + // 自己是否媒体流发送者 | |
| 13 | + private boolean asSender; | |
| 13 | 14 | |
| 14 | - public SipTransactionInfo(SIPResponse response, boolean fromServer) { | |
| 15 | + public SipTransactionInfo(SIPResponse response, boolean asSender) { | |
| 15 | 16 | this.callId = response.getCallIdHeader().getCallId(); |
| 16 | 17 | this.fromTag = response.getFromTag(); |
| 17 | 18 | this.toTag = response.getToTag(); |
| 18 | 19 | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| 19 | - this.fromServer = fromServer; | |
| 20 | + this.asSender = asSender; | |
| 20 | 21 | } |
| 21 | 22 | |
| 22 | 23 | public SipTransactionInfo(SIPResponse response) { |
| ... | ... | @@ -24,7 +25,6 @@ public class SipTransactionInfo { |
| 24 | 25 | this.fromTag = response.getFromTag(); |
| 25 | 26 | this.toTag = response.getToTag(); |
| 26 | 27 | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| 27 | - this.fromServer = true; | |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | 30 | public SipTransactionInfo() { |
| ... | ... | @@ -62,11 +62,11 @@ public class SipTransactionInfo { |
| 62 | 62 | this.viaBranch = viaBranch; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | - public boolean isFromServer() { | |
| 66 | - return fromServer; | |
| 65 | + public boolean isAsSender() { | |
| 66 | + return asSender; | |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | - public void setFromServer(boolean fromServer) { | |
| 70 | - this.fromServer = fromServer; | |
| 69 | + public void setAsSender(boolean asSender) { | |
| 70 | + this.asSender = asSender; | |
| 71 | 71 | } |
| 72 | 72 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
| ... | ... | @@ -170,11 +170,11 @@ public class SIPRequestHeaderProvider { |
| 170 | 170 | //from |
| 171 | 171 | SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); |
| 172 | 172 | Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); |
| 173 | - FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isFromServer()?transactionInfo.getFromTag():transactionInfo.getToTag()); | |
| 173 | + FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isAsSender()? transactionInfo.getFromTag():transactionInfo.getToTag()); | |
| 174 | 174 | //to |
| 175 | 175 | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); |
| 176 | 176 | Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); |
| 177 | - ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,transactionInfo.isFromServer()?transactionInfo.getToTag():transactionInfo.getFromTag()); | |
| 177 | + ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, transactionInfo.isAsSender()?transactionInfo.getToTag():transactionInfo.getFromTag()); | |
| 178 | 178 | |
| 179 | 179 | //Forwards |
| 180 | 180 | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); |
| ... | ... | @@ -186,11 +186,6 @@ public class SIPRequestHeaderProvider { |
| 186 | 186 | |
| 187 | 187 | request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); |
| 188 | 188 | |
| 189 | - Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort())); | |
| 190 | - request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress)); | |
| 191 | - | |
| 192 | - request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 193 | - | |
| 194 | 189 | return request; |
| 195 | 190 | } |
| 196 | 191 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -655,7 +655,12 @@ public class SIPCommander implements ISIPCommander { |
| 655 | 655 | */ |
| 656 | 656 | @Override |
| 657 | 657 | public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException { |
| 658 | - SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callId, stream); | |
| 658 | + SsrcTransaction ssrcTransaction; | |
| 659 | + if (callId != null) { | |
| 660 | + ssrcTransaction = streamSession.getSsrcTransaction(null, null, callId, null); | |
| 661 | + }else { | |
| 662 | + ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, null, stream); | |
| 663 | + } | |
| 659 | 664 | if (ssrcTransaction == null) { |
| 660 | 665 | throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream); |
| 661 | 666 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
| ... | ... | @@ -62,7 +62,12 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i |
| 62 | 62 | return; |
| 63 | 63 | } |
| 64 | 64 | String result = getText(rootElement, "Result"); |
| 65 | - logger.info("[语音广播]回复:{}, {}/{}", result, device.getDeviceId(), channelId ); | |
| 65 | + Element infoElement = rootElement.element("Info"); | |
| 66 | + String reason = null; | |
| 67 | + if (infoElement != null) { | |
| 68 | + reason = getText(infoElement, "Reason"); | |
| 69 | + } | |
| 70 | + logger.info("[语音广播]回复:{}, {}/{}", reason == null? result : result + ": " + reason, device.getDeviceId(), channelId ); | |
| 66 | 71 | |
| 67 | 72 | // 回复200 OK |
| 68 | 73 | responseAck(request, Response.OK); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| ... | ... | @@ -344,70 +344,34 @@ public class ZLMHttpHookListener { |
| 344 | 344 | } |
| 345 | 345 | }else if ("broadcast".equals(param.getApp())){ |
| 346 | 346 | // 语音对讲推流 stream需要满足格式deviceId_channelId |
| 347 | - if (param.isRegist() && param.getStream().indexOf("_") > 0) { | |
| 347 | + if (param.getStream().indexOf("_") > 0) { | |
| 348 | 348 | String[] streamArray = param.getStream().split("_"); |
| 349 | 349 | if (streamArray.length == 2) { |
| 350 | 350 | String deviceId = streamArray[0]; |
| 351 | 351 | String channelId = streamArray[1]; |
| 352 | 352 | Device device = deviceService.getDevice(deviceId); |
| 353 | 353 | if (device != null) { |
| 354 | - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); | |
| 355 | - if (deviceChannel != null) { | |
| 354 | + if (param.isRegist()) { | |
| 356 | 355 | if (audioBroadcastManager.exit(deviceId, channelId)) { |
| 357 | - // 直接推流 | |
| 358 | - SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null); | |
| 359 | - if (sendRtpItem == null) { | |
| 360 | - // TODO 可能数据错误,重新开启语音通道 | |
| 361 | - }else { | |
| 362 | - String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; | |
| 363 | - MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); | |
| 364 | - logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc()); | |
| 365 | - Map<String, Object> sendParam = new HashMap<>(12); | |
| 366 | - sendParam.put("vhost","__defaultVhost__"); | |
| 367 | - sendParam.put("app",sendRtpItem.getApp()); | |
| 368 | - sendParam.put("stream",sendRtpItem.getStreamId()); | |
| 369 | - sendParam.put("ssrc", sendRtpItem.getSsrc()); | |
| 370 | - sendParam.put("src_port", sendRtpItem.getLocalPort()); | |
| 371 | - sendParam.put("pt", sendRtpItem.getPt()); | |
| 372 | - sendParam.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); | |
| 373 | - sendParam.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); | |
| 374 | - | |
| 375 | - JSONObject jsonObject; | |
| 376 | - if (sendRtpItem.isTcpActive()) { | |
| 377 | - jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, sendParam); | |
| 378 | - } else { | |
| 379 | - sendParam.put("is_udp", is_Udp); | |
| 380 | - sendParam.put("dst_url", sendRtpItem.getIp()); | |
| 381 | - sendParam.put("dst_port", sendRtpItem.getPort()); | |
| 382 | - jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, sendParam); | |
| 383 | - } | |
| 384 | - if (jsonObject != null && jsonObject.getInteger("code") == 0) { | |
| 385 | - logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId); | |
| 386 | - }else { | |
| 387 | - logger.info("[语音对讲] 推流失败, 结果: {}", jsonObject); | |
| 388 | - } | |
| 389 | - | |
| 390 | - } | |
| 391 | - }else { | |
| 392 | - // 开启语音对讲通道 | |
| 393 | - try { | |
| 394 | - playService.audioBroadcastCmd(device, channelId, 60, (msg)->{ | |
| 395 | - logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); | |
| 396 | - }); | |
| 397 | - } catch (InvalidArgumentException | ParseException | SipException e) { | |
| 398 | - logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); | |
| 399 | - } | |
| 356 | + playService.stopAudioBroadcast(deviceId, channelId); | |
| 357 | + } | |
| 358 | + // 开启语音对讲通道 | |
| 359 | + try { | |
| 360 | + playService.audioBroadcastCmd(device, channelId, 60, (msg)->{ | |
| 361 | + logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId); | |
| 362 | + }); | |
| 363 | + } catch (InvalidArgumentException | ParseException | SipException e) { | |
| 364 | + logger.error("[命令发送失败] 语音对讲: {}", e.getMessage()); | |
| 400 | 365 | } |
| 401 | - | |
| 402 | 366 | }else { |
| 403 | - logger.info("[语音对讲] 未找到通道:{}", channelId); | |
| 367 | + // 流注销 | |
| 368 | + playService.stopAudioBroadcast(deviceId, channelId); | |
| 404 | 369 | } |
| 405 | - }else{ | |
| 370 | + } else{ | |
| 406 | 371 | logger.info("[语音对讲] 未找到设备:{}", deviceId); |
| 407 | 372 | } |
| 408 | 373 | } |
| 409 | 374 | } |
| 410 | - | |
| 411 | 375 | }else if ("talk".equals(param.getApp())){ |
| 412 | 376 | // 语音对讲推流 stream需要满足格式deviceId_channelId |
| 413 | 377 | if (param.isRegist() && param.getStream().indexOf("_") > 0) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
| ... | ... | @@ -1085,6 +1085,12 @@ public class PlayServiceImpl implements IPlayService { |
| 1085 | 1085 | param.put("app", sendRtpItem.getApp()); |
| 1086 | 1086 | param.put("stream", sendRtpItem.getStreamId()); |
| 1087 | 1087 | zlmresTfulUtils.stopSendRtp(mediaInfo, param); |
| 1088 | + try { | |
| 1089 | + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); | |
| 1090 | + } catch (InvalidArgumentException | ParseException | SipException | | |
| 1091 | + SsrcTransactionNotFoundException e) { | |
| 1092 | + logger.error("[消息发送失败] 发送语音喊话BYE失败"); | |
| 1093 | + } | |
| 1088 | 1094 | } |
| 1089 | 1095 | |
| 1090 | 1096 | audioBroadcastManager.del(deviceId, channelId); | ... | ... |