Commit 28f4f688dd37cbce7f7e2ff4a939d0701f2a8bbe

Authored by 648540858
1 parent fc90cd79

优化语音遇到错误时主动终止对讲流程

src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
@@ -69,6 +69,7 @@ public class VideoManagerConstants { @@ -69,6 +69,7 @@ public class VideoManagerConstants {
69 public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_"; 69 public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_";
70 70
71 public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_"; 71 public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
  72 + public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
72 73
73 74
74 75
src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
@@ -23,10 +23,6 @@ public class AudioBroadcastManager { @@ -23,10 +23,6 @@ public class AudioBroadcastManager {
23 23
24 public static Map<String, AudioBroadcastCatch> data = new ConcurrentHashMap<>(); 24 public static Map<String, AudioBroadcastCatch> data = new ConcurrentHashMap<>();
25 25
26 - public void add(AudioBroadcastCatch audioBroadcastCatch) {  
27 - this.update(audioBroadcastCatch);  
28 - }  
29 -  
30 public void update(AudioBroadcastCatch audioBroadcastCatch) { 26 public void update(AudioBroadcastCatch audioBroadcastCatch) {
31 if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) { 27 if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) {
32 data.put(audioBroadcastCatch.getDeviceId(), audioBroadcastCatch); 28 data.put(audioBroadcastCatch.getDeviceId(), audioBroadcastCatch);
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
@@ -49,8 +49,6 @@ public class DeferredResultHolder { @@ -49,8 +49,6 @@ public class DeferredResultHolder {
49 49
50 public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; 50 public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
51 51
52 - public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";  
53 -  
54 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>(); 52 private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>();
55 53
56 54
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2
3 import com.alibaba.fastjson2.JSONObject; 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
4 import com.genersoft.iot.vmp.conf.DynamicTask; 5 import com.genersoft.iot.vmp.conf.DynamicTask;
5 import com.genersoft.iot.vmp.conf.SipConfig; 6 import com.genersoft.iot.vmp.conf.SipConfig;
6 import com.genersoft.iot.vmp.conf.UserSetting; 7 import com.genersoft.iot.vmp.conf.UserSetting;
@@ -914,11 +915,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -914,11 +915,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
914 } 915 }
915 if (device != null) { 916 if (device != null) {
916 logger.info("收到设备" + requesterId + "的语音广播Invite请求"); 917 logger.info("收到设备" + requesterId + "的语音广播Invite请求");
917 - 918 + String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + request.getCallIdHeader().getCallId();
  919 + dynamicTask.stop(key);
918 try { 920 try {
919 responseAck(request, Response.TRYING); 921 responseAck(request, Response.TRYING);
920 } catch (SipException | InvalidArgumentException | ParseException e) { 922 } catch (SipException | InvalidArgumentException | ParseException e) {
921 logger.error("[命令发送失败] invite BAD_REQUEST: {}", e.getMessage()); 923 logger.error("[命令发送失败] invite BAD_REQUEST: {}", e.getMessage());
  924 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  925 + return;
922 } 926 }
923 String contentString = new String(request.getRawContent()); 927 String contentString = new String(request.getRawContent());
924 // jainSip不支持y=字段, 移除移除以解析。 928 // jainSip不支持y=字段, 移除移除以解析。
@@ -973,6 +977,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -973,6 +977,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
973 responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415 977 responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
974 } catch (SipException | InvalidArgumentException | ParseException e) { 978 } catch (SipException | InvalidArgumentException | ParseException e) {
975 logger.error("[命令发送失败] invite 不支持的媒体格式: {}", e.getMessage()); 979 logger.error("[命令发送失败] invite 不支持的媒体格式: {}", e.getMessage());
  980 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  981 + return;
976 } 982 }
977 return; 983 return;
978 } 984 }
@@ -987,6 +993,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -987,6 +993,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
987 responseAck(request, Response.BUSY_HERE); 993 responseAck(request, Response.BUSY_HERE);
988 } catch (SipException | InvalidArgumentException | ParseException e) { 994 } catch (SipException | InvalidArgumentException | ParseException e) {
989 logger.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage()); 995 logger.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage());
  996 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
990 } 997 }
991 return; 998 return;
992 } 999 }
@@ -1000,6 +1007,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -1000,6 +1007,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1000 responseAck(request, Response.BUSY_HERE); 1007 responseAck(request, Response.BUSY_HERE);
1001 } catch (SipException | InvalidArgumentException | ParseException e) { 1008 } catch (SipException | InvalidArgumentException | ParseException e) {
1002 logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage()); 1009 logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage());
  1010 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  1011 + return;
1003 } 1012 }
1004 return; 1013 return;
1005 } 1014 }
@@ -1034,11 +1043,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements @@ -1034,11 +1043,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1034 responseAck(request, Response.GONE); 1043 responseAck(request, Response.GONE);
1035 } catch (SipException | InvalidArgumentException | ParseException e) { 1044 } catch (SipException | InvalidArgumentException | ParseException e) {
1036 logger.error("[命令发送失败] 语音通话 回复410失败, {}", e.getMessage()); 1045 logger.error("[命令发送失败] 语音通话 回复410失败, {}", e.getMessage());
  1046 + return;
1037 } 1047 }
1038 playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId()); 1048 playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
1039 } 1049 }
1040 } catch (SdpException e) { 1050 } catch (SdpException e) {
1041 logger.error("[SDP解析异常]", e); 1051 logger.error("[SDP解析异常]", e);
  1052 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
1042 } 1053 }
1043 } else { 1054 } else {
1044 logger.warn("来自无效设备/平台的请求"); 1055 logger.warn("来自无效设备/平台的请求");
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd;
2 2
3 -import com.alibaba.fastjson2.JSONObject; 3 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
  4 +import com.genersoft.iot.vmp.conf.DynamicTask;
4 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch; 5 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
5 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatchStatus; 6 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatchStatus;
6 import com.genersoft.iot.vmp.gb28181.bean.Device; 7 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
8 import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; 9 import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
9 -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;  
10 -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;  
11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
13 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; 12 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
14 -import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; 13 +import com.genersoft.iot.vmp.service.IPlayService;
15 import gov.nist.javax.sip.message.SIPRequest; 14 import gov.nist.javax.sip.message.SIPRequest;
16 import org.dom4j.Element; 15 import org.dom4j.Element;
17 import org.slf4j.Logger; 16 import org.slf4j.Logger;
@@ -38,11 +37,14 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i @@ -38,11 +37,14 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
38 private ResponseMessageHandler responseMessageHandler; 37 private ResponseMessageHandler responseMessageHandler;
39 38
40 @Autowired 39 @Autowired
41 - private DeferredResultHolder deferredResultHolder; 40 + private DynamicTask dynamicTask;
42 41
43 @Autowired 42 @Autowired
44 private AudioBroadcastManager audioBroadcastManager; 43 private AudioBroadcastManager audioBroadcastManager;
45 44
  45 + @Autowired
  46 + private IPlayService playService;
  47 +
46 @Override 48 @Override
47 public void afterPropertiesSet() throws Exception { 49 public void afterPropertiesSet() throws Exception {
48 responseMessageHandler.addHandler(cmdType, this); 50 responseMessageHandler.addHandler(cmdType, this);
@@ -50,33 +52,33 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i @@ -50,33 +52,33 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
50 52
51 @Override 53 @Override
52 public void handForDevice(RequestEvent evt, Device device, Element rootElement) { 54 public void handForDevice(RequestEvent evt, Device device, Element rootElement) {
53 - try {  
54 - String channelId = getText(rootElement, "DeviceID");  
55 - String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST + device.getDeviceId() + channelId;  
56 -  
57 - // 此处是对本平台发出Broadcast指令的应答  
58 - JSONObject json = new JSONObject();  
59 - XmlUtil.node2Json(rootElement, json);  
60 - if (logger.isDebugEnabled()) {  
61 - logger.debug(json.toJSONString());  
62 - }  
63 - RequestMessage msg = new RequestMessage();  
64 - msg.setKey(key);  
65 - msg.setData(json);  
66 - deferredResultHolder.invokeAllResult(msg);  
67 -  
68 55
  56 + String channelId = getText(rootElement, "DeviceID");
  57 + SIPRequest request = (SIPRequest) evt.getRequest();
  58 + try {
69 if (!audioBroadcastManager.exit(device.getDeviceId(), channelId)) { 59 if (!audioBroadcastManager.exit(device.getDeviceId(), channelId)) {
70 // 回复410 60 // 回复410
71 responseAck((SIPRequest) evt.getRequest(), Response.GONE); 61 responseAck((SIPRequest) evt.getRequest(), Response.GONE);
72 return; 62 return;
73 } 63 }
74 - logger.info("收到语音广播的回复:{}/{}", device.getDeviceId(), channelId );  
75 - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);  
76 - audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);  
77 - audioBroadcastManager.update(audioBroadcastCatch); 64 + String result = getText(rootElement, "Result");
  65 + logger.info("[语音广播]回复:{}, {}/{}", result, device.getDeviceId(), channelId );
  66 +
78 // 回复200 OK 67 // 回复200 OK
79 - responseAck((SIPRequest) evt.getRequest(), Response.OK); 68 + responseAck(request, Response.OK);
  69 + if (result.equalsIgnoreCase("OK")) {
  70 + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(device.getDeviceId(), channelId);
  71 + audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);
  72 + audioBroadcastManager.update(audioBroadcastCatch);
  73 + // 等待invite消息, 超时则结束
  74 + String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + request.getCallIdHeader().getCallId();
  75 + dynamicTask.startDelay(key, ()->{
  76 + logger.info("[语音广播]等待invite消息超时:{}/{}", device.getDeviceId(), channelId);
  77 + playService.stopAudioBroadcast(device.getDeviceId(), channelId);
  78 + }, 2000);
  79 + }else {
  80 + playService.stopAudioBroadcast(device.getDeviceId(), channelId);
  81 + }
80 } catch (ParseException | SipException | InvalidArgumentException e) { 82 } catch (ParseException | SipException | InvalidArgumentException e) {
81 logger.error("[命令发送失败] 国标级联 语音喊话: {}", e.getMessage()); 83 logger.error("[命令发送失败] 国标级联 语音喊话: {}", e.getMessage());
82 } 84 }
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -1045,8 +1045,7 @@ public class PlayServiceImpl implements IPlayService { @@ -1045,8 +1045,7 @@ public class PlayServiceImpl implements IPlayService {
1045 event.call("语音广播已经开启"); 1045 event.call("语音广播已经开启");
1046 return; 1046 return;
1047 } else { 1047 } else {
1048 - audioBroadcastManager.del(deviceChannel.getDeviceId(), channelId);  
1049 - redisCatchStorage.deleteSendRTPServer(device.getDeviceId(), channelId, sendRtpItem.getCallId(), sendRtpItem.getStreamId()); 1048 + stopAudioBroadcast(device.getDeviceId(), channelId);
1050 } 1049 }
1051 } 1050 }
1052 } 1051 }
@@ -1055,7 +1054,7 @@ public class PlayServiceImpl implements IPlayService { @@ -1055,7 +1054,7 @@ public class PlayServiceImpl implements IPlayService {
1055 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> { 1054 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
1056 // 发送成功 1055 // 发送成功
1057 AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, AudioBroadcastCatchStatus.Ready); 1056 AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, AudioBroadcastCatchStatus.Ready);
1058 - audioBroadcastManager.add(audioBroadcastCatch); 1057 + audioBroadcastManager.update(audioBroadcastCatch);
1059 }, eventResultForError -> { 1058 }, eventResultForError -> {
1060 // 发送失败 1059 // 发送失败
1061 logger.error("语音广播发送失败: {}:{}", channelId, eventResultForError.msg); 1060 logger.error("语音广播发送失败: {}:{}", channelId, eventResultForError.msg);