|
@@ -87,7 +87,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
#超时处理
|
|
|
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:
|
|
|
+ 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未输入完成执行超时操作
|
|
@@ -123,6 +123,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
def get_player_file(self):
|
|
|
try:
|
|
|
message = self.call.message_queue.get(block=False)
|
|
|
+ # player_file = [f"http://{SERVE_HOST}{item.voice_url}" for item in message.contents if item.content_type == 'voice']
|
|
|
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
|
|
@@ -182,7 +183,7 @@ class MyCall(pj.Call):
|
|
|
self.player = None
|
|
|
self.asr = None
|
|
|
|
|
|
-
|
|
|
+ print("mycall acc:", call_id)
|
|
|
# self.scripts = build_demo_script()
|
|
|
self.user_asr_text_queue = queue.Queue(maxsize=100)
|
|
|
self.message_queue = queue.Queue(maxsize=3)
|
|
@@ -200,19 +201,23 @@ 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.get_phone()
|
|
|
+ self.call_phone, self.callIdString = self.get_phone()
|
|
|
|
|
|
# 超时设置
|
|
|
self.play_start_time = time.time() # 记录播放开始时间
|
|
|
self.play_complete_flag = False # 播放完成标志
|
|
|
|
|
|
+ self.txtLock = 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'):
|
|
|
+ if not hasattr(self, 'play_complete_flag') or self.txtLock:
|
|
|
self.play_complete_flag = False
|
|
|
self.play_start_time = time.time()
|
|
|
# 播放完成后开始计时
|
|
@@ -221,14 +226,16 @@ class MyCall(pj.Call):
|
|
|
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:
|
|
|
+ elapsed_time = current_time - self.play_start_time
|
|
|
+ wait_time = int(wait_time)
|
|
|
+ if elapsed_time > wait_time:
|
|
|
+ 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")
|
|
|
+ self.play_complete_flag = False
|
|
|
|
|
|
def reset_wait_time(self):
|
|
|
self.play_complete_flag = False # 重置播放完成标志
|
|
@@ -241,33 +248,34 @@ class MyCall(pj.Call):
|
|
|
match = re.match(r'"(\d+)" <sip:(\d+)@', call_info.remoteUri)
|
|
|
if match:
|
|
|
print("Phone Number:", match.group(1))
|
|
|
- return match.group(1) # 假设显示名称部分是手机号
|
|
|
+ return match.group(1), call_info.callIdString # 假设显示名称部分是手机号
|
|
|
else:
|
|
|
- return ""
|
|
|
- print("Failed to parse the phone number from remoteUri.")
|
|
|
+ return "", call_info.callIdString
|
|
|
def is_play_complete(self): #语音机器人是否播放结束
|
|
|
if self.cur_player_file:
|
|
|
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() or self.txtLock: # 判断是否播放完成 否则不记录用户说的内容
|
|
|
+ return
|
|
|
digit = prm.digit
|
|
|
# 假设为超长类型按键 把用户输入的按键进行拼接 如果为# 则把用户输入所有按键放入队列并发送文本机器人
|
|
|
# 如果为非正常按键服务 输入以后直接发送文本机器人
|
|
|
if self.inputType == '1':
|
|
|
if digit != '#':
|
|
|
self.digit += digit
|
|
|
- print(f"Received DTMF digit12: {self.digit}")
|
|
|
+ # print(f"Received DTMF digit12: {self.digit}")
|
|
|
else:
|
|
|
self.user_asr_text_queue.put(f"DTMF({self.digit})DTMF")
|
|
|
- print(f"Received DTMF digit34: {self.digit}")
|
|
|
+ # print(f"Received DTMF digit34: {self.digit}")
|
|
|
else:
|
|
|
print(f"Received DTMF digit: {digit}")
|
|
|
self.user_asr_text_queue.put(f"DTMF({digit})DTMF")
|
|
|
|
|
|
def onCallState(self, prm):
|
|
|
call_info = self.getInfo()
|
|
|
- print("Call state text: ", dir(call_info))
|
|
|
- print("Call state: ", call_info.state)
|
|
|
+ # print("Call state text: ", dir(call_info))
|
|
|
+ print("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
|
|
@@ -282,7 +290,12 @@ class MyCall(pj.Call):
|
|
|
self.bot_say_hello()
|
|
|
|
|
|
if call_info.state == pj.PJSIP_INV_STATE_DISCONNECTED:
|
|
|
- print("通话结束")
|
|
|
+ print("通话结束", self.user_part)
|
|
|
+ sys.stdout.flush() # 强制刷新输出缓冲区
|
|
|
+ if self.audio_port:
|
|
|
+ self.audio_port = None # 或调用相关销毁方法
|
|
|
+ if self.player:
|
|
|
+ self.player = None # 或调用播放器停止方法
|
|
|
# 远程挂机之后要将分机号回收
|
|
|
self.agent.release(self.user_part)
|
|
|
|
|
@@ -311,7 +324,8 @@ class MyCall(pj.Call):
|
|
|
return
|
|
|
player_id = murmur3_32(player_file)
|
|
|
self.player_complete_dict[player_id] = False
|
|
|
- print('self.player_complete_dict[player_id]D:', player_id, player_file, self.player_complete_dict[player_id])
|
|
|
+ # print('self.player_complete_dict[player_id]D:', player_id, player_file, self.player_complete_dict[player_id])
|
|
|
+ print(f"[DEBUG] Sending bot speaker, player_file: {player_file}, player_id: {player_id}")
|
|
|
self.player = MyAudioMediaPlayer(player_id, self.aud_med, on_complete=self.on_media_player_complete)
|
|
|
# self.player.createPlayer(player_file[0], pj.PJMEDIA_FILE_NO_LOOP)
|
|
|
self.player.createPlaylist(player_file, f'my_hello_playlist{player_id}', pj.PJMEDIA_FILE_NO_LOOP)
|
|
@@ -319,6 +333,8 @@ class MyCall(pj.Call):
|
|
|
|
|
|
def on_receiver_asr_result(self, message, *args):
|
|
|
# print('asr返回内容:',message)
|
|
|
+ if not self.is_play_complete() or self.txtLock: # 判断是否播放完成 否则不记录用户说的内容
|
|
|
+ return
|
|
|
message = json.loads(message)
|
|
|
if message["header"]["status"] == 20000000:
|
|
|
# 获取 result 内容
|
|
@@ -364,8 +380,8 @@ class ToTextBotAgent:
|
|
|
self.request_data = BotChatRequest(
|
|
|
nodeId=self.call_agent.node_id,
|
|
|
userId=self.call_agent.call_phone,
|
|
|
- # sessionId=self.call_agent.call_id,
|
|
|
- sessionId="23",
|
|
|
+ sessionId= self.call_agent.callIdString,
|
|
|
+ # sessionId="23",
|
|
|
recordId="",
|
|
|
taskId="10001",
|
|
|
asrText=user_asr_text,
|
|
@@ -378,18 +394,18 @@ class ToTextBotAgent:
|
|
|
|
|
|
|
|
|
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}")
|
|
|
try:
|
|
|
- print(f"发送请求之前2334")
|
|
|
response = requests.post(url=url, json=json.loads(request_data), headers=headers, timeout=10) # 使用占位URL
|
|
|
print(f"原始响应内容:{response.text}")
|
|
|
- print(f"响应内容:{response.content}") # 查看原始响应内容
|
|
|
- print(f"响应状态码:{response.status_code}") # 查看状态码
|
|
|
if response.status_code == 200:
|
|
|
response_data = response.json()
|
|
|
if "data" in response_data and response_data["code"]==0:
|
|
@@ -403,8 +419,10 @@ class ToTextBotAgent:
|
|
|
else:
|
|
|
# 错误处理
|
|
|
print(f"请求失败,状态码: {response.status_code}, 响应内容: {response.text}")
|
|
|
+ self.call_agent.txtLock = False
|
|
|
except requests.RequestException as e:
|
|
|
print(f"请求发生异常: {e}")
|
|
|
+ self.call_agent.txtLock = False
|
|
|
|
|
|
# 模拟接口请求返回
|
|
|
def test_request(self, params: BotChatRequest):
|
|
@@ -527,7 +545,7 @@ class BotAgent:
|
|
|
# acfg.natConfig.turnPassword = "password"
|
|
|
|
|
|
# Create the account
|
|
|
- acc = Account(self, user_part)
|
|
|
+ acc = Account(self, user_part=user_part)
|
|
|
acc.create(acfg)
|
|
|
|
|
|
self.user_part_pool.put(user_part)
|