余尚辉 3 ماه پیش
والد
کامیت
ec7f6e638f
3فایلهای تغییر یافته به همراه33 افزوده شده و 46 حذف شده
  1. 1 1
      Dockerfile
  2. 14 4
      src/core/callcenter/esl/handler/channel_hangup_handler.py
  3. 18 41
      src/core/voip/bot.py

+ 1 - 1
Dockerfile

@@ -1,6 +1,6 @@
 FROM python:3.9
 RUN apt-get update && \
-    apt-get install -y vim wget curl sngrep tcpflow tcpdump ffmpeg&& \
+    apt-get install -y vim wget curl sngrep tcpflow tcpdump ffmpeg && \
     pip3 install swig cython pip setuptools --upgrade
 
 

+ 14 - 4
src/core/callcenter/esl/handler/channel_hangup_handler.py

@@ -6,7 +6,7 @@ import sys
 import os
 import traceback
 from pydub import AudioSegment
-
+import threading
 from src.core.callcenter.acd import AcdService
 from src.core.callcenter.call import CallService
 from src.core.callcenter.enumeration import CallType, DeviceType, AnswerFlag, NextType, CdrType, HangupDir, \
@@ -131,13 +131,21 @@ class ChannelHangupHandler(EslEventHandler):
             records.append(value.record) if value.record else None
         self.logger.info("get_call_info_record: %s", records)
         if records:
-            self.merge_audio_files(records)
+           merge_record= self.merge_audio_files(records)
+           threading.Thread(target=self._update_record_in_thread, args=(call_info.session_id, merge_record)).start()
         else:
             self.logger.warning("没有找到有效的录音文件")
 
+    def _update_record_in_thread(self, session_id, merge_record):
+        """用于在独立线程中执行 update_record"""
+        try:
+            self.dataHandleServer.update_record(session_id, record=merge_record)
+            self.logger.info("更新录音记录完成: session_id=%s", session_id)
+        except Exception as e:
+            self.logger.error("更新录音记录失败: session_id=%s, error=%s", session_id, str(e))
     def merge_audio_files(self,audio_files):
         if not audio_files:
-            print("没有可合并的音频文件")
+            self.logger.info("没有可合并的音频文件")
             return
             # 初始化第一个音频文件
         combined = AudioSegment.from_file(audio_files[0])
@@ -152,7 +160,9 @@ class ChannelHangupHandler(EslEventHandler):
         output_file = os.path.join(dir_name, f"{base_name}_merge{ext}")
         # 导出合并后的音频文件
         combined.export(output_file, format=ext.lstrip('.'))
-        print(f"音频合并完成: {output_file}")
+        self.logger.info(f"音频合并完成: {output_file}")
+        return output_file
+
     def release(self, event):
         device_id = event.getHeader("Unique-ID")
         user_part = self.cache.get_user_part(device_id)

+ 18 - 41
src/core/voip/bot.py

@@ -106,7 +106,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
 
             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):
-                print('onFrameReceived:message_queue_size=', message_queue_size, 'play_complete=', play_complete, asr_text)
+                # self.call.logger.info('onFrameReceived:message_queue_size=', message_queue_size, 'play_complete=', play_complete, asr_text)
                 self.call.cur_player_file, self.call.wait_time, self.call.inputType,self.call.action, self.call.node_id = self.get_player_file()
                 # 重置播放完成标志和超时计时器,确保新的播放从头开始计时
                 self.call.reset_wait_time()
@@ -117,7 +117,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
     def get_asr_text(self):
         try:
             asr_text = self.call.user_asr_text_queue.get(block=False)
-            print('get_asr_text:', asr_text)
+            self.call.logger.info('get_asr_text:', asr_text)
             return asr_text
         except:
             pass
@@ -126,7 +126,6 @@ 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']
-            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()
@@ -186,8 +185,8 @@ class MyCall(pj.Call):
         self.asr = None
         self.session_id = kwargs.get('variable_sip_h_P-LIBRA-CallId')
         self.device_id = kwargs.get('variable_sip_h_P-LIBRA-DeviceId')
-
-        self.logger.info("self.session_id:%s", self.session_id)
+        self.call_phone = kwargs.get("Caller-Caller-ID-Number")
+        self.logger.info("self.session_id:%s, self.call_phone:%s", self.session_id,self.call_phone)
         # self.scripts = build_demo_script()
         self.user_asr_text_queue = queue.Queue(maxsize=100)
         self.message_queue = queue.Queue(maxsize=3)
@@ -205,7 +204,6 @@ class MyCall(pj.Call):
         self.asr = TestSt(call_id, message_receiver=self.on_receiver_asr_result)  # 创建ASR实例
         self.asr.start()  # 启动ASR线程
 
-        self.call_phone, self.callIdString = self.get_phone()
 
         # 超时设置
         self.play_start_time = time.time()  # 倒计时开始时间
@@ -231,21 +229,13 @@ class MyCall(pj.Call):
                 # self.user_asr_text_queue.put("ASR408error")
                 self.chat('ASR408error')
         except ValueError as e:
-            print(f"无效的等待时间参数: {wait_time}, 错误: {e}")
+            self.logger.info(f"无效的等待时间参数: {wait_time}, 错误: {e}")
             self.reset_wait_time()
 
     def reset_wait_time(self):
         self.play_complete_flag = False  # 重置播放完成标志
         self.play_start_time = None  # 重置开始计时时间
-    def get_phone(self):
-        import re
-        call_info = self.getInfo()
-        match = re.match(r'"(\d+)" <sip:(\d+)@', call_info.remoteUri)
-        if match:
-            self.logger.info("Phone Number:%s", match.group(1))
-            return match.group(1), call_info.callIdString  # 假设显示名称部分是手机号
-        else:
-            return "", call_info.callIdString
+
     def is_play_complete(self):    #语音机器人是否播放结束
         if self.cur_player_file:
             player_id = murmur3_32(self.cur_player_file)
@@ -269,7 +259,6 @@ class MyCall(pj.Call):
 
     def onCallState(self, prm):
         call_info = self.getInfo()
-        self.logger.info("Call state: %s, call id: %s, callcallIdString: %s ", call_info.state, call_info.id, call_info.callIdString)
 
         # pj.PJSIP_INV_STATE_NULL
         # pj.PJSIP_INV_STATE_CALLING
@@ -361,11 +350,8 @@ class MyCall(pj.Call):
         self.logger.info('handling_release %s', action.action_code)
         action_code = action.action_code
         if action_code == 'hang':  # 挂断
-            action_content = action.action_content
-            self.logger.info(f'todo 挂电话:{action_content}')
             self.agent.hangup(self.user_part)
         elif action_code == 'transfer':  # 转人工
-            self.logger.info('todo 转人工')
             self.agent.transfer(user_part=self.user_part, call_id=self.session_id, device_id=self.device_id)
             #更新通话记录
             self.agent.dataHandleServer.update_record(self.session_id, service_category=2)
@@ -385,47 +371,39 @@ class ToTextBotAgent:
             asrText=user_asr_text,
             ext= None
         )
-        print("user_asr_text发送结果:", user_asr_text)
+        self.call_agent.logger.info("user_asr_text发送结果:", user_asr_text)
         # 发送请求并处理响应
         # self.test_request(self.request_data)
         self.to_quest(self.request_data)
 
 
     def to_quest(self, request: BotChatRequest):
-        # if self.call_agent.txtLock:
-        #     return
-        # 将实体类转换为JSON字符串
         headers = {'Content-Type': 'application/json'}
         request_data = request.to_json_string()
         url = f"http://{SERVE_HOST}:40072/botservice"
-        # self.call_agent.txtLock = True
-        # 发送POST请求
-        print(f"请求数据:{request_data},url:{url}")
+
+        self.call_agent.logger.info(f"请求数据:{request_data},url:{url}")
         try:
             response = requests.post(url=url,  json=json.loads(request_data), headers=headers, timeout=10)  # 使用占位URL
-            print(f"原始响应内容:{response.text}")
+            self.call_agent.logger.info(f"原始响应内容:{response.text}")
             if response.status_code == 200:
                 response_data = response.json()
                 if "data" in response_data and response_data["code"]==0:
                     data = response_data["data"]
                     parsed_response = ChatMessage.from_json(data)
                     self.call_agent.message_queue.put(parsed_response)
-                    sys.stdout.flush()  # 强制刷新输出缓冲区
                 else:
-                    print("响应中没有 'data' 字段")
+                    self.call_agent.logger.info("响应中没有 'data' 字段")
             else:
                 # 错误处理
-                print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
+                self.call_agent.logger.info(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
         except requests.RequestException as e:
-            print(f"请求发生异常: {e}")
+            self.call_agent.logger.info(f"请求发生异常: {e}")
 
 
 # 模拟接口请求返回
     def test_request(self, params: BotChatRequest):
-        # if self.call_agent.txtLock:
-        #     return
-        print("test_request::params=", params)
-        # self.call_agent.txtLock = True
+        self.call_agent.logger.info("test_request::params=", params)
         response_data = {
             "node_id": "1.0",
             "contents": [],
@@ -437,7 +415,7 @@ class ToTextBotAgent:
             "inputType": "0"
         }
 
-        print("asrText:", params.asrText)
+        self.call_agent.logger.info("asrText:", params.asrText)
         if params.asrText == 'start':                              #欢迎语
             response_data['contents'].append({
                 "content_type": "voice",
@@ -476,11 +454,10 @@ class ToTextBotAgent:
                 }
             ]
         try:
-            print(json.dumps(response_data['contents']))
+            self.call_agent.logger.info(json.dumps(response_data['contents']))
             parsed_response = ChatMessage.from_json(response_data)
             self.call_agent.message_queue.put(parsed_response)
         except Exception as e:
-            print(f"Error in test_request: {e}")
             traceback.print_exc()  # 打印完整的错误信息
             return None
 
@@ -579,7 +556,7 @@ class BotAgent:
             _sip_header = pj.SipHeader()
             _sip_header.hName = str(k)
             _sip_header.hValue = str(v)
-            print('hangup, header_name=%s, header_value=%s'%(k, v))
+            self.logger.info('hangup, header_name=%s, header_value=%s'%(k, v))
             sip_header_vector.push_back(_sip_header)
         call_op_param.txOption.headers = sip_header_vector
 
@@ -595,7 +572,7 @@ class BotAgent:
         acc = self.accounts.get(user_part)
         self.logger.info('register, user_part :%d, pool.size :%d', user_part, self.user_part_pool.qsize())
         if acc:
-            print('register==========>', acc.getId())
+            self.logger.info('register==========>', acc.getId())
             # ps = pj.PresenceStatus()
             # ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
             # ps.activity = pj.PJRPID_ACTIVITY_AWAY