zhoufan 1 vuosi sitten
vanhempi
commit
eff53c0d1e

+ 81 - 35
midware-service/src/main/java/midware/service/eslclient/EslEventListener.java

@@ -15,6 +15,7 @@ import midware.service.rep.IOutPhoneService;
15 15
 import midware.service.rep.IRecordService;
16 16
 import midware.util.enums.EslAgentEnum;
17 17
 import midware.util.enums.EslEventEnum;
18
+import midware.util.helper.AsyncHelper;
18 19
 import midware.util.helper.RedisHelper;
19 20
 import midware.util.helper.SpringHelper;
20 21
 import midware.util.helper.StringHelper;
@@ -39,7 +40,7 @@ import java.util.stream.Collectors;
39 40
 public class EslEventListener implements IEslEventListener {
40 41
     @Override
41 42
     public void eventReceived(EslEvent event) {
42
-        //System.out.println(1 + "|" + JSON.toJSONString(event));
43
+        System.out.println(1 + "|" + JSON.toJSONString(event));
43 44
         //log.warn(1 + "|" + JSON.toJSONString(event));
44 45
 
45 46
         IConfigService iConfigService = SpringHelper.getBean(IConfigService.class);
@@ -120,7 +121,7 @@ public class EslEventListener implements IEslEventListener {
120 121
                                     result.put("Type", "Wait");
121 122
                                     result.put("Result", true);
122 123
                                     result.put("Count", listWait.size());
123
-                                    webSocketService.sendMessageGroupAll(queue,JSON.toJSONString(result));
124
+                                    webSocketService.sendMessageGroupAll(queue, JSON.toJSONString(result));
124 125
 
125 126
                                     //播报位置
126 127
                                     eslClientService.playPosition(listWait.indexOf(caller) + 1, uuid);
@@ -155,7 +156,7 @@ public class EslEventListener implements IEslEventListener {
155 156
                                     result.put("Type", "Wait");
156 157
                                     result.put("Result", true);
157 158
                                     result.put("Count", EslCommon.groupWaitList.get(queue).size());
158
-                                    webSocketService.sendMessageGroupAll(queue,JSON.toJSONString(result));
159
+                                    webSocketService.sendMessageGroupAll(queue, JSON.toJSONString(result));
159 160
                                 }
160 161
                             }
161 162
                             //eslClientService.playAgent(header.get("CC-Agent"), header.get("CC-Member-Session-UUID"));
@@ -171,12 +172,26 @@ public class EslEventListener implements IEslEventListener {
171 172
                                     result.put("Type", "Wait");
172 173
                                     result.put("Result", true);
173 174
                                     result.put("Count", EslCommon.groupWaitList.get(queue).size());
174
-                                    webSocketService.sendMessageGroupAll(queue,JSON.toJSONString(result));
175
+                                    webSocketService.sendMessageGroupAll(queue, JSON.toJSONString(result));
175 176
                                 }
176 177
                             }
177 178
                             break;
178 179
                     }
179 180
                     break;
181
+
182
+                case mod_funasr_json:
183
+                    // 获取通道名称
184
+                    String[] chanNames = header.get("Channel-Name").split("\\@")[0].split("\\/");
185
+                    Channel chan2 = EslCommon.getChanByNumber(chanNames[2]);
186
+                    String asrs = header.get("funasr_result").toString();
187
+                    Map asr = JSON.parseObject(asrs, Map.class);
188
+                    if (asr.containsKey("mode") && asr.get("mode").toString().equals("2pass-offline")) {
189
+                        String text = asr.get("text").toString();
190
+                        if (StringHelper.isNotEmpty(text)) {
191
+                            sendAsr(chan2,text);
192
+                        }
193
+                    }
194
+                    break;
180 195
             }
181 196
         } else {
182 197
             // 获取会话ID
@@ -338,6 +353,16 @@ public class EslEventListener implements IEslEventListener {
338 353
                                     result.put("Number", calleeNum);
339 354
                                     webSocketService.sendMessage(callerAgent.getAgent(), JSON.toJSONString(result));
340 355
                                 }
356
+                                if(chanNames[2].equals(calleeNum)){
357
+                                    if (calleeAgent1 != null) {
358
+                                        Map<String, Object> result = new HashMap<>();
359
+                                        result.put("Type", "Incoming");
360
+                                        result.put("Result", true);
361
+                                        result.put("CallID", chan.getRecordId());
362
+                                        result.put("Number", callerNum);
363
+                                        webSocketService.sendMessage(calleeAgent1.getAgent(), JSON.toJSONString(result));
364
+                                    }
365
+                                }
341 366
                             } else {
342 367
                                 chan.setRecordId(EslCommon.getChanByNumber(callerNum).getRecordId());
343 368
                                 if (calleeAgent1 != null) {
@@ -502,8 +527,9 @@ public class EslEventListener implements IEslEventListener {
502 527
                         } else {
503 528
                             //是否开启语音识别
504 529
                             if (iConfigService.getConfigValue("EnableAsr").equals("1")) {
505
-                                eslClientService.appCommand(chanId, "set", "fire_asr_events=true");
506
-                                eslClientService.appCommand(chanId, "detect_speech", "unimrcp:mrcpv2 hello hello");
530
+                                //eslClientService.appCommand(chanId, "set", "fire_asr_events=true");
531
+                                //eslClientService.appCommand(chanId, "detect_speech", "unimrcp:mrcpv2 hello hello");
532
+                                eslClientService.funasr(chanId);
507 533
                             }
508 534
                         }
509 535
                     }
@@ -531,6 +557,19 @@ public class EslEventListener implements IEslEventListener {
531 557
                             if (callerAgent != null && StringHelper.isNotEmpty(chan.getOpType())) {
532 558
                                 actionNotice(chan.getOpType(), callerAgent.getAgent(), sid, false);
533 559
                             }
560
+                            if (chan.getOpType().equals("Meeting")) {
561
+                                List<Channel> channels = EslCommon.channels.stream().filter(p ->
562
+                                        p.getSessionId().equals(sid) && !p.getChanId().equals(chanId)).collect(Collectors.toList());
563
+                                AsyncHelper.instance().execute(new TimerTask() {
564
+                                    @Override
565
+                                    public void run() {
566
+                                        for (Channel c : channels) {
567
+                                            eslClientService.playBreak(c.getChanId());
568
+                                            eslClientService.playBack("/home/website/midware/files/others/noanswer.mp3",c.getChanId());
569
+                                        }
570
+                                    }
571
+                                });
572
+                            }
534 573
                         }
535 574
 
536 575
                         boolean isupdate = true;
@@ -637,34 +676,7 @@ public class EslEventListener implements IEslEventListener {
637 676
                                 String xml = String.join("", results);
638 677
                                 xmlResult = getXmlResult(xml, true);
639 678
                                 if (StringHelper.isNotEmpty(xmlResult)) {
640
-                                    String csid = chan.getSessionId();
641
-                                    List<Channel> channels = EslCommon.channels.stream().filter(p ->
642
-                                            p.getSessionId().equals(csid) && p.getType() == 1).collect(Collectors.toList());
643
-                                    for (Channel c : channels) {
644
-                                        Agent agent1 = EslCommon.getAgentByExten(c.getNumber());
645
-                                        if (agent1 != null) {
646
-                                            Map<String, Object> result = new HashMap<>();
647
-                                            result.put("Type", "Asr");
648
-                                            result.put("Result", true);
649
-                                            result.put("Speech", xmlResult);
650
-                                            result.put("Number", chanNames[2]);
651
-                                            webSocketService.sendMessage(agent1.getAgent(), JSON.toJSONString(result));
652
-                                        }
653
-                                    }
654
-
655
-                                    Asr asr = new Asr();
656
-                                    asr.setNumber(chanNames[2]);
657
-                                    asr.setResult(xmlResult);
658
-                                    asr.setUuid(csid);
659
-                                    if (agent != null) {
660
-                                        asr.setAgent(agent.getAgent());
661
-                                        asr.setGroupNo(agent.getGroup());
662
-                                    }
663
-                                    asr.setCreateTime(new Date());
664
-
665
-                                    synchronized (EslCommon.asrs) {
666
-                                        EslCommon.asrs.add(asr);
667
-                                    }
679
+                                    sendAsr(chan,xmlResult);
668 680
                                 }
669 681
                             }
670 682
                         }
@@ -704,7 +716,7 @@ public class EslEventListener implements IEslEventListener {
704 716
 
705 717
     @Override
706 718
     public void backgroundJobResultReceived(EslEvent event) {
707
-        //System.out.println(2 + "|" + JSON.toJSONString(event));
719
+        System.out.println(2 + "|" + JSON.toJSONString(event));
708 720
         //log.warn(2 + "|" + JSON.toJSONString(event));
709 721
 
710 722
         String bodys = event.getEventBodyLines().size() > 0 ? event.getEventBodyLines().get(0) : "";
@@ -830,4 +842,38 @@ public class EslEventListener implements IEslEventListener {
830 842
         }
831 843
         return result;
832 844
     }
845
+
846
+    //发送识别结果
847
+    private void sendAsr(Channel chan,String text){
848
+        WebSocketService webSocketService = SpringHelper.getBean(WebSocketService.class);
849
+        String csid = chan.getSessionId();Agent agent=null;
850
+        List<Channel> channels = EslCommon.channels.stream().filter(p ->
851
+                p.getSessionId().equals(csid) && p.getType() == 1).collect(Collectors.toList());
852
+        for (Channel c : channels) {
853
+            Agent agent1 = EslCommon.getAgentByExten(c.getNumber());
854
+            if (agent1 != null) {
855
+                Map<String, Object> result = new HashMap<>();
856
+                result.put("Type", "Asr");
857
+                result.put("Result", true);
858
+                result.put("Speech", text);
859
+                result.put("Number", chan.getNumber());
860
+                webSocketService.sendMessage(agent1.getAgent(), JSON.toJSONString(result));
861
+                if (c.getChanId().equals(chan.getChanId())) agent = agent1;
862
+            }
863
+        }
864
+
865
+        Asr asr = new Asr();
866
+        asr.setNumber(chan.getNumber());
867
+        asr.setResult(text);
868
+        asr.setUuid(csid);
869
+        if (agent != null) {
870
+            asr.setAgent(agent.getAgent());
871
+            asr.setGroupNo(agent.getGroup());
872
+        }
873
+        asr.setCreateTime(new Date());
874
+
875
+        synchronized (EslCommon.asrs) {
876
+            EslCommon.asrs.add(asr);
877
+        }
878
+    }
833 879
 }

+ 40 - 3
midware-service/src/main/java/midware/service/init/EslClientService.java

@@ -26,6 +26,8 @@ import java.io.File;
26 26
 import java.text.SimpleDateFormat;
27 27
 import java.util.ArrayList;
28 28
 import java.util.Date;
29
+import java.util.HashMap;
30
+import java.util.Map;
29 31
 import java.util.concurrent.ScheduledThreadPoolExecutor;
30 32
 import java.util.concurrent.TimeUnit;
31 33
 import java.util.stream.Stream;
@@ -487,6 +489,41 @@ public class EslClientService {
487 489
         return !result.equals("");
488 490
     }
489 491
 
492
+    //暂停播放语音
493
+    public boolean playBreak(String chanId) {
494
+        String result = "";
495
+        try {
496
+            String command = EslCommandEnum.uuid_break.name();
497
+            String arg = chanId ;
498
+            result = client.sendAsyncApiCommand(command, arg);
499
+        } catch (Exception e) {
500
+            log.error( chanId + " 暂停播放语音失败", e);
501
+        }
502
+        return !result.equals("");
503
+    }
504
+
505
+    //语音识别
506
+    public boolean funasr(String chanId) {
507
+        String result = "";
508
+        try {
509
+            String command = EslCommandEnum.uuid_audio_stream.name();
510
+            Map<String, Object> params = new HashMap<>();
511
+            params.put("chunk_size", new int[]{5, 10, 5});
512
+            params.put("wav_name", "h5");
513
+            params.put("is_speaking", true);
514
+            params.put("chunk_interval", 10);
515
+            params.put("itn", true);
516
+            params.put("mode", "offline");
517
+            params.put("hotwords", null);
518
+            String arg = chanId + " start ws://192.168.1.40:10095 mono 16k " + JSON.toJSONString(params);
519
+            result = client.sendAsyncApiCommand(command, arg);
520
+
521
+        } catch (Exception e) {
522
+            log.error(chanId + " 语音识别失败", e);
523
+        }
524
+        return !result.equals("");
525
+    }
526
+
490 527
     //会话加入会议
491 528
     public boolean talkJoinMeeting(String sessionId) {
492 529
         String result = "";
@@ -522,13 +559,13 @@ public class EslClientService {
522 559
                 argstr = ",record_concat_video=true,conference_auto_record=" + path;
523 560
             }
524 561
 
525
-            String arg = " {instant_ringback=true,origination_caller_id_number=" + callerNum
526
-                    + ",cc_member_session_uuid=" + meetingId + ",call_called=" + calleeNum.substring(fix.length())
527
-                    + argstr + ",transfer_ringback=local_stream://moh,ignore_early_media=true}"
562
+            String arg = " {origination_caller_id_number=" + callerNum + ",cc_member_session_uuid=" + meetingId
563
+                    + ",call_called=" + calleeNum.substring(fix.length()) + argstr + "}"
528 564
                     //+ getCallString(calleeNum) + " " + meetingId + " xml ExtenMeeting";
529 565
                     + getCallString(calleeNum) + " &conference(" + meetingId + "@" + at + ")"
530 566
                     + "\r\nJob-UUID: " + action + "|" + System.currentTimeMillis();
531 567
             result = client.sendAsyncApiCommand(command, arg);
568
+            playBack("local_stream://moh",meetingId);
532 569
 
533 570
         } catch (Exception e) {
534 571
             log.error(callerNum + "|" + calleeNum + "|" + meetingId + " 呼叫加入会议失败", e);

+ 14 - 10
midware-service/src/main/java/midware/service/init/WebSocketService.java

@@ -104,7 +104,7 @@ public class WebSocketService {
104 104
                     String AgentId = map.get("AgentId").toString();
105 105
                     String AgentExten = map.get("AgentExten").toString();
106 106
                     String AgentGroup = map.get("AgentGroup").toString();
107
-                    param = AgentExten + "|" + AgentGroup;
107
+                    param =  AgentGroup;
108 108
                     //String AgentType = map.get("AgentType").toString();
109 109
 
110 110
                     if (StringHelper.isNotEmpty(AgentId) && StringHelper.isNotEmpty(AgentExten) && StringHelper.isNotEmpty(AgentGroup)) {
@@ -140,7 +140,7 @@ public class WebSocketService {
140 140
 
141 141
                             EslCommon.agents.add(agent);
142 142
                             chan = EslCommon.getChanByExten(AgentExten);
143
-                            isExec = eslClientService.login(AgentId, AgentExten, AgentGroup, type + "|" + AgentId);
143
+                            isExec = eslClientService.login(AgentId, AgentExten, AgentGroup, type + "|" + AgentId + "|" + AgentExten + "|" + AgentGroup);
144 144
                             if (!isExec) {
145 145
                                 EslCommon.agents.remove(agent);
146 146
                             }
@@ -171,14 +171,14 @@ public class WebSocketService {
171 171
                     if (map.get("DestinationNumber") != null && Arrays.asList(EslAgentEnum.free, EslAgentEnum.busy, EslAgentEnum.aftertalk).contains(state)) {
172 172
                         String DestinationNumber = map.get("DestinationNumber").toString();
173 173
                         String Fix = map.get("Fix") != null ? map.get("Fix").toString() : "";
174
-                        param = DestinationNumber + "|" + Fix;
174
+                        param = DestinationNumber + (Fix.equals("") ? "" : "|" + Fix);
175 175
                         if (StringHelper.isNotEmpty(DestinationNumber)) {
176 176
                             Agent tAgent = EslCommon.getAgentByExten(DestinationNumber);
177 177
                             if (tAgent != null && tAgent.getAgentState() != EslAgentEnum.free.ordinal()) {
178 178
                                 result.put("Result", "目标坐席忙碌中");
179 179
                             } else {
180 180
                                 agent.setOpType(type);
181
-                                isExec = eslClientService.extenCall(agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + param + "|" + Fix);
181
+                                isExec = eslClientService.extenCall(agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + DestinationNumber + "|" + Fix);
182 182
                             }
183 183
                         }
184 184
                     }
@@ -212,7 +212,7 @@ public class WebSocketService {
212 212
                     if (map.get("DestinationNumber") != null && Objects.equals(state, EslAgentEnum.talking)) {
213 213
                         String DestinationNumber = map.get("DestinationNumber").toString();
214 214
                         String Fix = map.get("Fix") != null ? map.get("Fix").toString() : "";
215
-                        param = DestinationNumber+ "|" + Fix;
215
+                        param = DestinationNumber + (Fix.equals("") ? "" : "|" + Fix);
216 216
                         if (StringHelper.isNotEmpty(DestinationNumber)) {
217 217
                             if (DestinationNumber.equals(agent.getExten())) {
218 218
                                 result.put("Result", "目标不能是自己");
@@ -226,7 +226,7 @@ public class WebSocketService {
226 226
                                     result.put("Result", "主叫不能此操作");
227 227
                                 } else {
228 228
                                     agent.setOpType(type);
229
-                                    isExec = eslClientService.transfer(chan.getSessionId(), agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + param+ "|" + Fix);
229
+                                    isExec = eslClientService.transfer(chan.getSessionId(), agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + DestinationNumber+ "|" + Fix);
230 230
                                 }
231 231
                             }
232 232
                         }
@@ -237,7 +237,7 @@ public class WebSocketService {
237 237
                     if (map.get("DestinationNumber") != null && Objects.equals(state, EslAgentEnum.talking)) {
238 238
                         String DestinationNumber = map.get("DestinationNumber").toString();
239 239
                         String Fix = map.get("Fix") != null ? map.get("Fix").toString() : "";
240
-                        param = DestinationNumber+ "|" + Fix;
240
+                        param = DestinationNumber + (Fix.equals("") ? "" : "|" + Fix);
241 241
                         if (StringHelper.isNotEmpty(DestinationNumber)) {
242 242
                             if (DestinationNumber.equals(agent.getExten())) {
243 243
                                 result.put("Result", "目标不能是自己");
@@ -251,7 +251,7 @@ public class WebSocketService {
251 251
                                     result.put("Result", "主叫不能此操作");
252 252
                                 } else {
253 253
                                     agent.setOpType(type);
254
-                                    isExec = eslClientService.consult(chan.getSessionId(), agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + param+ "|" + Fix);
254
+                                    isExec = eslClientService.consult(chan.getSessionId(), agent.getExten(), DestinationNumber, type + "|" + agentId + "|" + DestinationNumber+ "|" + Fix);
255 255
                                 }
256 256
                             }
257 257
                         }
@@ -271,7 +271,7 @@ public class WebSocketService {
271 271
                     if (map.get("DestinationNumber") != null && Objects.equals(state, EslAgentEnum.talking)) {
272 272
                         String DestinationNumber = map.get("DestinationNumber").toString();
273 273
                         String Fix = map.get("Fix") != null ? map.get("Fix").toString() : "";
274
-                        param = DestinationNumber+ "|" + Fix;
274
+                        param = DestinationNumber + (Fix.equals("") ? "" : "|" + Fix);
275 275
                         if (StringHelper.isNotEmpty(DestinationNumber)) {
276 276
                             if (DestinationNumber.equals(agent.getExten())) {
277 277
                                 result.put("Result", "目标不能是自己");
@@ -283,7 +283,7 @@ public class WebSocketService {
283 283
                                     result.put("Result", "目标号码忙碌中");
284 284
                                 } else {
285 285
                                     agent.setOpType(type);
286
-                                    isExec = eslClientService.callJoinMeeting(agent.getExten(), DestinationNumber, chan.getSessionId(), type + "|" + agentId + "|" + param+ "|" + Fix);
286
+                                    isExec = eslClientService.callJoinMeeting(agent.getExten(), DestinationNumber, chan.getSessionId(), type + "|" + agentId + "|" + DestinationNumber+ "|" + Fix);
287 287
                                 }
288 288
                             }
289 289
                         }
@@ -494,6 +494,10 @@ public class WebSocketService {
494 494
                     result1.put("Result", true);
495 495
                     List<Agent> agents = new ArrayList<>(EslCommon.agents);
496 496
                     for (Agent agent1 : agents) {
497
+                        result1.put("State", agent1.getAgentState());
498
+                        result1.put("AgentId", agent1.getAgent());
499
+                        result1.put("Exten", agent1.getExten());
500
+                        result1.put("Monitor", agent1.getIsMonitor());
497 501
                         sendText(session,JSON.toJSONString(result1));
498 502
                     }
499 503
                     //通知其他监控

+ 2 - 0
midware-util/src/main/java/midware/util/enums/EslCommandEnum.java

@@ -57,6 +57,8 @@ public enum EslCommandEnum {
57 57
     //uuid_transfer <uuid> [-bleg|-both] <dest-exten> [<dialplan>] [<context>]
58 58
     uuid_transfer("将现有呼叫转移到和中的特定分机。拨号计划可以是“xml”或“directory”。"),
59 59
 
60
+    uuid_audio_stream("asr"),
61
+
60 62
     callcenter_config("配置"),
61 63
     uuid_send_dtmf("按键"),
62 64
     conference("会议"),

+ 1 - 0
midware-util/src/main/java/midware/util/enums/EslEventEnum.java

@@ -22,6 +22,7 @@ public enum EslEventEnum {
22 22
 
23 23
     conference_maintenance("会议","conference::maintenance","custom"),
24 24
 
25
+    mod_funasr_json("识别结果","mod_funasr::json","custom"),
25 26
     ;
26 27
 
27 28