|
@@ -56,11 +56,13 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
|
|
|
self.user_asr_texts = []
|
|
|
self.cur_player_file = None
|
|
|
- self.wait_time = None
|
|
|
+
|
|
|
|
|
|
self.play_start_time = None # 记录播放开始时间
|
|
|
self.play_complete_flag = False # 播放完成标志
|
|
|
|
|
|
+
|
|
|
+ #self.dtmf_type = None #记录按键类型 1为长按键类型
|
|
|
def onFrameRequested(self, frame):
|
|
|
print("Request audio frame:", frame)
|
|
|
|
|
@@ -84,19 +86,24 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
|
|
|
#超时处理
|
|
|
current_time = time.time()
|
|
|
- if self.wait_time and self.wait_time != "0" and play_complete and not asr_text:
|
|
|
- print('ssdsdsd',play_complete,asr_text)
|
|
|
- self.wait_time_check(current_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}')
|
|
|
+ if self.call.wait_time and self.call.wait_time != "0" and play_complete and not asr_text and self.call.digit == '':
|
|
|
+ self.wait_time_check(current_time, self.call.wait_time)
|
|
|
+
|
|
|
+ # 如果为超长类型的按键服务 超过30s未输入完成执行超时操作
|
|
|
+ if self.call.dtmf_type=='1' and play_complete and not asr_text:
|
|
|
+ self.wait_time_check(current_time, 30)
|
|
|
|
|
|
message_queue_size = self.call.message_queue.qsize()
|
|
|
if (message_queue_size > 0 and not self.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.cur_player_file, self.wait_time= self.get_player_file()
|
|
|
+ self.cur_player_file, self.call.wait_time, self.call.dtmf_type= self.get_player_file()
|
|
|
self.call.send_bot_speaker(self.cur_player_file)
|
|
|
|
|
|
# 重置播放完成标志和超时计时器,确保新的播放从头开始计时
|
|
|
self.play_complete_flag = False # 重置播放完成标志
|
|
|
self.play_start_time = time.time() # 重新开始计时
|
|
|
+ self.call.digit = "" #重新把超长类型按键内容digit置为空
|
|
|
except:
|
|
|
pass
|
|
|
|
|
@@ -118,24 +125,29 @@ class MyAudioMediaPort(pj.AudioMediaPort):
|
|
|
message = self.call.message_queue.get(block=False)
|
|
|
player_file = [item.voice_url for item in message.contents if item.content_type == 'voice']
|
|
|
wait_time = message.wait_time
|
|
|
- return player_file, wait_time
|
|
|
+ dtmf_type = message.dtmf_type
|
|
|
+ print('get_player_file:', player_file, wait_time,dtmf_type)
|
|
|
+ return player_file, wait_time, dtmf_type
|
|
|
except Exception as e:
|
|
|
- print(f"sdsd: {e}")
|
|
|
traceback.print_exc()
|
|
|
|
|
|
- def wait_time_check(self,current_time):
|
|
|
+ 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
|
|
|
+ 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(self.wait_time):
|
|
|
- self.play_complete_flag = False # 重置标志位,避免重复超时
|
|
|
+ if current_time - self.play_start_time > int(wait_time):
|
|
|
+ self.play_complete_flag = False # 重置标志位,避免重复超时
|
|
|
+ if wait_time == 30:
|
|
|
+ self.call.chat("7", "重新请求文本机器人")
|
|
|
+ else:
|
|
|
self.call.chat("6", "重新请求文本机器人")
|
|
|
|
|
|
+
|
|
|
class MyAudioMediaPlayer(pj.AudioMediaPlayer):
|
|
|
|
|
|
def __init__(self, player_id, sink, on_complete=None):
|
|
@@ -193,6 +205,10 @@ class MyCall(pj.Call):
|
|
|
self.message_queue = queue.Queue(maxsize=3)
|
|
|
self.player_complete_dict = {}
|
|
|
|
|
|
+ self.wait_time = None
|
|
|
+ self.dtmf_type = None #记录按键类型 1为长按键类型
|
|
|
+ self.digit = '' # 存储长按键内容
|
|
|
+
|
|
|
from src.core.voip.asr import TestSt
|
|
|
self.asr = TestSt(call_id, message_receiver=self.on_receiver_asr_result) # 创建ASR实例
|
|
|
self.asr.start() # 启动ASR线程
|
|
@@ -200,8 +216,20 @@ class MyCall(pj.Call):
|
|
|
|
|
|
def onDtmfDigit(self, prm):
|
|
|
digit = prm.digit
|
|
|
- print(f"Received DTMF digit: {digit}")
|
|
|
- self.user_asr_text_queue.put(f"DTMF({digit})DTMF")
|
|
|
+ # 假设为超长类型按键 把用户输入的按键进行拼接 如果为# 则把用户输入所有按键放入队列并发送文本机器人
|
|
|
+ # 如果为非正常按键服务 输入以后直接发送文本机器人
|
|
|
+ if self.dtmf_type == '1':
|
|
|
+ if digit != '#':
|
|
|
+ self.digit += digit
|
|
|
+ print(f"Received DTMF digit12: {self.digit}")
|
|
|
+ else:
|
|
|
+ self.user_asr_text_queue.put(f"DTMF({self.digit})DTMF")
|
|
|
+ self.chat('3', 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")
|
|
|
+ # self.chat('3', digit)
|
|
|
|
|
|
def onCallState(self, prm):
|
|
|
call_info = self.getInfo()
|
|
@@ -339,7 +367,8 @@ class ToTextBotAgent:
|
|
|
"action_code": "normal",
|
|
|
"action_content": "正常通话"
|
|
|
},
|
|
|
- "talk_time_out": ""
|
|
|
+ "talk_time_out": "",
|
|
|
+ "dtmf_type": '0'
|
|
|
}
|
|
|
|
|
|
print("event_type:", event_type)
|
|
@@ -350,6 +379,7 @@ class ToTextBotAgent:
|
|
|
"voice_url": '/code/src/core/voip/scripts/1_00.wav',
|
|
|
"voice_content": "五一北京到上海的高铁票还有吗?"
|
|
|
})
|
|
|
+ response_data['dtmf_type']= '1'
|
|
|
elif event_type == '2':
|
|
|
new_contents = [
|
|
|
{
|
|
@@ -373,6 +403,13 @@ class ToTextBotAgent:
|
|
|
"voice_url": '/code/src/core/voip/scripts/4_00.wav',
|
|
|
"voice_content": "sds"
|
|
|
})
|
|
|
+ elif event_type == '7':
|
|
|
+ response_data['contents'].append({
|
|
|
+ "content_type": "voice",
|
|
|
+ "content": "",
|
|
|
+ "voice_url": '/code/src/core/voip/scripts/2_00.wav',
|
|
|
+ "voice_content": "sds"
|
|
|
+ })
|
|
|
try:
|
|
|
print(json.dumps(response_data['contents']))
|
|
|
parsed_response = ChatMessage.from_json(response_data)
|
|
@@ -402,8 +439,8 @@ class BotAgent:
|
|
|
ep_cfg.uaConfig.maxCalls = 20
|
|
|
ep_cfg.uaConfig.maxAccounts = 20
|
|
|
ep_cfg.medConfig.noVad = True
|
|
|
- ep_cfg.logConfig.level = 5
|
|
|
- ep_cfg.logConfig.consoleLevel = 5
|
|
|
+ ep_cfg.logConfig.level = 4
|
|
|
+ ep_cfg.logConfig.consoleLevel = 4
|
|
|
self.ep.libCreate()
|
|
|
self.ep.libInit(ep_cfg)
|
|
|
|