瀏覽代碼

fix: 修改语音对话超时逻辑

余尚辉 5 月之前
父節點
當前提交
8f98323546
共有 4 個文件被更改,包括 59 次插入47 次删除
  1. 4 3
      src/core/callcenter/agent.py
  2. 5 2
      src/core/callcenter/views.py
  3. 7 5
      src/core/voip/asr.py
  4. 43 37
      src/core/voip/bot.py

+ 4 - 3
src/core/callcenter/agent.py

@@ -59,11 +59,8 @@ class AgentOperService:
            if not agent or agent.agent_state == AgentState.DISABLE.code:
                raise BizException(BizErrorCode.ERROR_NOT_FOLLOW_CHECK_IN)
            phone = _get_phone(req.saas_id, agent.phone_num)
-           print('debug1111111')
            agent_monitor = _get_agent_monitor(req.saas_id, agent.agent_num)
-           print('debug222222')
            agent_monitor.check_scene = req.scene
-           print('debug333333')
            self.agent_monitor_service.update_checkin(agent_monitor)
            self.agent_actionlog_service.insert_check_state(agent_monitor, AgentCheck.IN, AgentLogState.CHECKIN)
            self.agent_state_service.checkin(agent.saas_id, agent.out_id, agent.phone_num)
@@ -126,6 +123,10 @@ class AgentOperService:
 
     def idle_agent_exist(self, request: AgentActionRequest):
         pass
+    def agent_state(self,req: AgentActionRequest):
+        # agent = _get_agent(req.saas_id, req.agent_id)
+        agent_monitor = _get_agent_monitor(req.saas_id, req.agent_id)
+        return agent_monitor.service_state
 
     def turn_on(self, req: AgentActionRequest):
         agent = _get_agent(req.saas_id, req.agent_id)

+ 5 - 2
src/core/callcenter/views.py

@@ -152,8 +152,11 @@ def agent_state():
     """获取坐席状态"""
     try:
         data = request.get_json()
-        param = HumanServiceQueryRequest.from_json(data)
-        res = agent_service.watch_agent_state(param)
+        # param = HumanServiceQueryRequest.from_json(data)
+        # res = agent_service.watch_agent_state(param)
+        param = AgentActionRequest.from_json(data)
+        res = agent_oper_service.agent_state(param)
+
         return success_response(res)
     except Exception as e:
         print("Exception occurred: %s", str(e))

+ 7 - 5
src/core/voip/asr.py

@@ -67,10 +67,11 @@ class TestSt:
             print("无法获取Token")
             return None
 
-    def __init__(self, tid, message_receiver=None):
+    def __init__(self, tid, message_receiver=None, begin_callback=None):
         self.__th = threading.Thread(target=self.__test_run)
         self.__id = tid
         self.message_receiver = message_receiver
+        self.begin_callback = begin_callback
         self._Token = self.get_cached_token()
         self.sr = None
         print("开始")
@@ -99,6 +100,7 @@ class TestSt:
             on_close=self.test_on_close,
             callback_args=[self.__id]
         )
+        self.sr.__setattr__("max_sentence_silence", 2000)
         self.sr.start(
             aformat="pcm",
             enable_intermediate_result=True,
@@ -108,10 +110,10 @@ class TestSt:
         print("ASR session started.")
 
     def test_on_sentence_begin(self, message, *args):
-        pass
-        # print("test_on_sentence_begin:{}".format(message))
-        # if self.message_receiver:
-        #     self.message_receiver(message, *args)
+        # pass
+        print("test_on_sentence_begin:{}".format(message))
+        if self.begin_callback:
+            self.begin_callback(message, *args)
 
     def test_on_sentence_end(self, message, *args):
         # print("test_on_sentence_end:{}".format(message))

+ 43 - 37
src/core/voip/bot.py

@@ -60,8 +60,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
 
         self.user_asr_texts = []
 
-        self.play_start_time = None  # 记录播放开始时间
-        self.play_complete_flag = False  # 播放完成标志
+
 
     def onFrameRequested(self, frame):
         print("Request audio frame:", frame)
@@ -84,16 +83,16 @@ class MyAudioMediaPort(pj.AudioMediaPort):
                 self.user_asr_texts.clear()
                 self.call.chat(user_asr_text)
 
+
             #超时处理
+            current_time = time.time()
             # print(f'onFrameReceived:self.wait_time={self.call.wait_time}, self.call.digit ={self.call.digit},asr_text:{asr_text},play_complete:{play_complete},self.call.inputType:{self.call.inputType}')
-            if self.call.wait_time and self.call.wait_time != "0" and play_complete and not asr_text and not self.call.digit :
-                current_time = time.time()
-                self.wait_time_check(current_time, self.call.wait_time)
+            if self.call.wait_time and self.call.wait_time != "0" and play_complete and not asr_text and not self.call.digit:
+                self.call.wait_time_check(current_time, self.call.wait_time)
 
             # 如果为超长类型的按键服务 超过30s未输入完成执行超时操作
             if self.call.inputType == '1' and play_complete and not asr_text:
-                current_time = time.time()
-                self.wait_time_check(current_time, 30)
+                self.call.wait_time_check(current_time, 30)
 
             message_queue_size = self.call.message_queue.qsize()
             if (message_queue_size > 0 and not self.call.cur_player_file) or (message_queue_size > 0 and play_complete):
@@ -102,10 +101,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
                 self.call.send_bot_speaker(self.call.cur_player_file)
 
                 # 重置播放完成标志和超时计时器,确保新的播放从头开始计时
-                self.play_complete_flag = False  # 重置播放完成标志
-                self.play_start_time = time.time()  # 重新开始计时
-                self.call.digit = ""   #重新把超长类型按键内容digit置为空
-
+                self.call.reset_wait_time()
                 #播放完毕执行的动作
                 self.call.say_end_action(self.call.action)
         except:
@@ -128,33 +124,11 @@ class MyAudioMediaPort(pj.AudioMediaPort):
         try:
             message = self.call.message_queue.get(block=False)
             player_file = [item.voice_url for item in message.contents if item.content_type == 'voice']
-            # self.call.wait_time = message.waitTime
-            # self.call.inputType = message.inputType
-            # self.call.action = message.action
-            # self.call.nodeId = message.nodeId
             print('get_player_file:', player_file,message.wait_time, message.inputType, message.action, message.node_id)
             return player_file, message.wait_time, message.inputType, message.action, message.node_id
         except Exception as e:
             traceback.print_exc()
 
-    def wait_time_check(self,current_time,wait_time):
-        if not hasattr(self, 'play_complete_flag'):
-            self.play_complete_flag = False
-            self.play_start_time = 0
-        # 播放完成后开始计时
-        if not self.play_complete_flag:
-            self.play_complete_flag = True
-            self.play_start_time = current_time
-        # 检查超时时间是否已到
-        if current_time - self.play_start_time > int(wait_time):
-            self.play_complete_flag = False  # 重置标志位,避免重复超时
-            if wait_time == 30:
-                print("DTMF:超时",self.call.digit)
-                self.call.user_asr_text_queue.put(f"DTMF({self.call.digit})DTMF")
-            else:
-                print("DTMF:超时6shehehehehehhehhehehe")
-                self.call.user_asr_text_queue.put("ASR408error")
-
 
 
 class MyAudioMediaPlayer(pj.AudioMediaPlayer):
@@ -228,6 +202,39 @@ class MyCall(pj.Call):
 
         self.call_phone = self.get_phone()
 
+        # 超时设置
+        self.play_start_time = time.time()  # 记录播放开始时间
+        self.play_complete_flag = False  # 播放完成标志
+
+    # 开始说话
+    def begin_callback(self, message, *args):
+        self.reset_wait_time()
+        print("开始说话")
+
+    def wait_time_check(self, current_time, wait_time):
+        if not hasattr(self, 'play_complete_flag'):
+            self.play_complete_flag = False
+            self.play_start_time = time.time()
+        # 播放完成后开始计时
+        if not self.play_complete_flag:
+            self.play_complete_flag = True
+            self.play_start_time = current_time
+        # 检查超时时间是否已到
+        print("current_time:", current_time, self.play_start_time)
+        if current_time - self.play_start_time > int(wait_time):
+            # self.play_complete_flag = False  # 重置标志位,避免重复超时
+            if wait_time == 30:
+                print("DTMF:超时", self.digit)
+                self.user_asr_text_queue.put(f"DTMF({self.digit})DTMF")
+            else:
+                print("DTMF:超时6shehehehehehhehhehehe")
+                self.user_asr_text_queue.put("ASR408error")
+
+    def reset_wait_time(self):
+        self.play_complete_flag = False  # 重置播放完成标志
+        # self.play_start_time = time.time()  # 重新开始计时
+        self.digit = ""  # 重新把超长类型按键内容digit置为空
+
     def get_phone(self):
         import re
         call_info = self.getInfo()
@@ -243,8 +250,6 @@ class MyCall(pj.Call):
             player_id = murmur3_32(self.cur_player_file)
             return self.player_complete_dict.get(player_id)
     def onDtmfDigit(self, prm):
-        if not self.is_play_complete():   # 判断是否播放完成 否则不记录用户说的内容
-            return
         digit = prm.digit
         # 假设为超长类型按键 把用户输入的按键进行拼接 如果为# 则把用户输入所有按键放入队列并发送文本机器人
         # 如果为非正常按键服务 输入以后直接发送文本机器人
@@ -363,9 +368,10 @@ class ToTextBotAgent:
             asrText=user_asr_text,
             ext= None
         )
+        print("user_asr_text发送结果:", user_asr_text)
         # 发送请求并处理响应
-        # self.test_request(self.request_data)
-        self.to_quest(self.request_data)
+        self.test_request(self.request_data)
+        # self.to_quest(self.request_data)
 
 
     def to_quest(self, request: BotChatRequest):