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 69 public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_";
70 70  
71 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 23  
24 24 public static Map<String, AudioBroadcastCatch> data = new ConcurrentHashMap<>();
25 25  
26   - public void add(AudioBroadcastCatch audioBroadcastCatch) {
27   - this.update(audioBroadcastCatch);
28   - }
29   -
30 26 public void update(AudioBroadcastCatch audioBroadcastCatch) {
31 27 if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) {
32 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 49  
50 50 public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
51 51  
52   - public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
53   -
54 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 1 package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
2 2  
3 3 import com.alibaba.fastjson2.JSONObject;
  4 +import com.genersoft.iot.vmp.common.VideoManagerConstants;
4 5 import com.genersoft.iot.vmp.conf.DynamicTask;
5 6 import com.genersoft.iot.vmp.conf.SipConfig;
6 7 import com.genersoft.iot.vmp.conf.UserSetting;
... ... @@ -914,11 +915,14 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
914 915 }
915 916 if (device != null) {
916 917 logger.info("收到设备" + requesterId + "的语音广播Invite请求");
917   -
  918 + String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + request.getCallIdHeader().getCallId();
  919 + dynamicTask.stop(key);
918 920 try {
919 921 responseAck(request, Response.TRYING);
920 922 } catch (SipException | InvalidArgumentException | ParseException e) {
921 923 logger.error("[命令发送失败] invite BAD_REQUEST: {}", e.getMessage());
  924 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  925 + return;
922 926 }
923 927 String contentString = new String(request.getRawContent());
924 928 // jainSip不支持y=字段, 移除移除以解析。
... ... @@ -973,6 +977,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
973 977 responseAck(request, Response.UNSUPPORTED_MEDIA_TYPE); // 不支持的格式,发415
974 978 } catch (SipException | InvalidArgumentException | ParseException e) {
975 979 logger.error("[命令发送失败] invite 不支持的媒体格式: {}", e.getMessage());
  980 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  981 + return;
976 982 }
977 983 return;
978 984 }
... ... @@ -987,6 +993,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
987 993 responseAck(request, Response.BUSY_HERE);
988 994 } catch (SipException | InvalidArgumentException | ParseException e) {
989 995 logger.error("[命令发送失败] invite 未找到可用的zlm: {}", e.getMessage());
  996 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
990 997 }
991 998 return;
992 999 }
... ... @@ -1000,6 +1007,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1000 1007 responseAck(request, Response.BUSY_HERE);
1001 1008 } catch (SipException | InvalidArgumentException | ParseException e) {
1002 1009 logger.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage());
  1010 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
  1011 + return;
1003 1012 }
1004 1013 return;
1005 1014 }
... ... @@ -1034,11 +1043,13 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
1034 1043 responseAck(request, Response.GONE);
1035 1044 } catch (SipException | InvalidArgumentException | ParseException e) {
1036 1045 logger.error("[命令发送失败] 语音通话 回复410失败, {}", e.getMessage());
  1046 + return;
1037 1047 }
1038 1048 playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
1039 1049 }
1040 1050 } catch (SdpException e) {
1041 1051 logger.error("[SDP解析异常]", e);
  1052 + playService.stopAudioBroadcast(device.getDeviceId(), audioBroadcastCatch.getChannelId());
1042 1053 }
1043 1054 } else {
1044 1055 logger.warn("来自无效设备/平台的请求");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
1 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 5 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
5 6 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatchStatus;
6 7 import com.genersoft.iot.vmp.gb28181.bean.Device;
7 8 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
8 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 10 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
12 11 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
13 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 14 import gov.nist.javax.sip.message.SIPRequest;
16 15 import org.dom4j.Element;
17 16 import org.slf4j.Logger;
... ... @@ -38,11 +37,14 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
38 37 private ResponseMessageHandler responseMessageHandler;
39 38  
40 39 @Autowired
41   - private DeferredResultHolder deferredResultHolder;
  40 + private DynamicTask dynamicTask;
42 41  
43 42 @Autowired
44 43 private AudioBroadcastManager audioBroadcastManager;
45 44  
  45 + @Autowired
  46 + private IPlayService playService;
  47 +
46 48 @Override
47 49 public void afterPropertiesSet() throws Exception {
48 50 responseMessageHandler.addHandler(cmdType, this);
... ... @@ -50,33 +52,33 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
50 52  
51 53 @Override
52 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 59 if (!audioBroadcastManager.exit(device.getDeviceId(), channelId)) {
70 60 // 回复410
71 61 responseAck((SIPRequest) evt.getRequest(), Response.GONE);
72 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 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 82 } catch (ParseException | SipException | InvalidArgumentException e) {
81 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 1045 event.call("语音广播已经开启");
1046 1046 return;
1047 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 1054 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
1056 1055 // 发送成功
1057 1056 AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, AudioBroadcastCatchStatus.Ready);
1058   - audioBroadcastManager.add(audioBroadcastCatch);
  1057 + audioBroadcastManager.update(audioBroadcastCatch);
1059 1058 }, eventResultForError -> {
1060 1059 // 发送失败
1061 1060 logger.error("语音广播发送失败: {}:{}", channelId, eventResultForError.msg);
... ...