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,14 +9,15 @@ public class SipTransactionInfo { | ||
| 9 | private String toTag; | 9 | private String toTag; |
| 10 | private String viaBranch; | 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 | this.callId = response.getCallIdHeader().getCallId(); | 16 | this.callId = response.getCallIdHeader().getCallId(); |
| 16 | this.fromTag = response.getFromTag(); | 17 | this.fromTag = response.getFromTag(); |
| 17 | this.toTag = response.getToTag(); | 18 | this.toTag = response.getToTag(); |
| 18 | this.viaBranch = response.getTopmostViaHeader().getBranch(); | 19 | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| 19 | - this.fromServer = fromServer; | 20 | + this.asSender = asSender; |
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | public SipTransactionInfo(SIPResponse response) { | 23 | public SipTransactionInfo(SIPResponse response) { |
| @@ -24,7 +25,6 @@ public class SipTransactionInfo { | @@ -24,7 +25,6 @@ public class SipTransactionInfo { | ||
| 24 | this.fromTag = response.getFromTag(); | 25 | this.fromTag = response.getFromTag(); |
| 25 | this.toTag = response.getToTag(); | 26 | this.toTag = response.getToTag(); |
| 26 | this.viaBranch = response.getTopmostViaHeader().getBranch(); | 27 | this.viaBranch = response.getTopmostViaHeader().getBranch(); |
| 27 | - this.fromServer = true; | ||
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | public SipTransactionInfo() { | 30 | public SipTransactionInfo() { |
| @@ -62,11 +62,11 @@ public class SipTransactionInfo { | @@ -62,11 +62,11 @@ public class SipTransactionInfo { | ||
| 62 | this.viaBranch = viaBranch; | 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,11 +170,11 @@ public class SIPRequestHeaderProvider { | ||
| 170 | //from | 170 | //from |
| 171 | SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); | 171 | SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain()); |
| 172 | Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI); | 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 | //to | 174 | //to |
| 175 | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); | 175 | SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress()); |
| 176 | Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI); | 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 | //Forwards | 179 | //Forwards |
| 180 | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); | 180 | MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70); |
| @@ -186,11 +186,6 @@ public class SIPRequestHeaderProvider { | @@ -186,11 +186,6 @@ public class SIPRequestHeaderProvider { | ||
| 186 | 186 | ||
| 187 | request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | 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 | return request; | 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,7 +655,12 @@ public class SIPCommander implements ISIPCommander { | ||
| 655 | */ | 655 | */ |
| 656 | @Override | 656 | @Override |
| 657 | public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException { | 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 | if (ssrcTransaction == null) { | 664 | if (ssrcTransaction == null) { |
| 660 | throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream); | 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,7 +62,12 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i | ||
| 62 | return; | 62 | return; |
| 63 | } | 63 | } |
| 64 | String result = getText(rootElement, "Result"); | 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 | // 回复200 OK | 72 | // 回复200 OK |
| 68 | responseAck(request, Response.OK); | 73 | responseAck(request, Response.OK); |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| @@ -344,70 +344,34 @@ public class ZLMHttpHookListener { | @@ -344,70 +344,34 @@ public class ZLMHttpHookListener { | ||
| 344 | } | 344 | } |
| 345 | }else if ("broadcast".equals(param.getApp())){ | 345 | }else if ("broadcast".equals(param.getApp())){ |
| 346 | // 语音对讲推流 stream需要满足格式deviceId_channelId | 346 | // 语音对讲推流 stream需要满足格式deviceId_channelId |
| 347 | - if (param.isRegist() && param.getStream().indexOf("_") > 0) { | 347 | + if (param.getStream().indexOf("_") > 0) { |
| 348 | String[] streamArray = param.getStream().split("_"); | 348 | String[] streamArray = param.getStream().split("_"); |
| 349 | if (streamArray.length == 2) { | 349 | if (streamArray.length == 2) { |
| 350 | String deviceId = streamArray[0]; | 350 | String deviceId = streamArray[0]; |
| 351 | String channelId = streamArray[1]; | 351 | String channelId = streamArray[1]; |
| 352 | Device device = deviceService.getDevice(deviceId); | 352 | Device device = deviceService.getDevice(deviceId); |
| 353 | if (device != null) { | 353 | if (device != null) { |
| 354 | - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); | ||
| 355 | - if (deviceChannel != null) { | 354 | + if (param.isRegist()) { |
| 356 | if (audioBroadcastManager.exit(deviceId, channelId)) { | 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 | }else { | 366 | }else { |
| 403 | - logger.info("[语音对讲] 未找到通道:{}", channelId); | 367 | + // 流注销 |
| 368 | + playService.stopAudioBroadcast(deviceId, channelId); | ||
| 404 | } | 369 | } |
| 405 | - }else{ | 370 | + } else{ |
| 406 | logger.info("[语音对讲] 未找到设备:{}", deviceId); | 371 | logger.info("[语音对讲] 未找到设备:{}", deviceId); |
| 407 | } | 372 | } |
| 408 | } | 373 | } |
| 409 | } | 374 | } |
| 410 | - | ||
| 411 | }else if ("talk".equals(param.getApp())){ | 375 | }else if ("talk".equals(param.getApp())){ |
| 412 | // 语音对讲推流 stream需要满足格式deviceId_channelId | 376 | // 语音对讲推流 stream需要满足格式deviceId_channelId |
| 413 | if (param.isRegist() && param.getStream().indexOf("_") > 0) { | 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,6 +1085,12 @@ public class PlayServiceImpl implements IPlayService { | ||
| 1085 | param.put("app", sendRtpItem.getApp()); | 1085 | param.put("app", sendRtpItem.getApp()); |
| 1086 | param.put("stream", sendRtpItem.getStreamId()); | 1086 | param.put("stream", sendRtpItem.getStreamId()); |
| 1087 | zlmresTfulUtils.stopSendRtp(mediaInfo, param); | 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 | audioBroadcastManager.del(deviceId, channelId); | 1096 | audioBroadcastManager.del(deviceId, channelId); |