更新
authorp15692025051 <846603105@qq.com>
Thu, 6 Jun 2024 03:43:12 +0000 (11:43 +0800)
committerp15692025051 <846603105@qq.com>
Thu, 6 Jun 2024 03:43:12 +0000 (11:43 +0800)
2.sdk/project/W8/sdk/services/microPython/ports/quectel/core/ai.py

index f34bae6..c55ee10 100644 (file)
@@ -163,11 +163,15 @@ class AIScreen(Screen):#AI_GUI
         self.AI_client_chat_isconnect = 0 #是否连接成功
         self.AI_client_chat_num = 1
         self.AI_client_chat_play_str = ""
+        self.AI_client_chat_end_flag = 0
         self.AI_client_tts = None
         self.AI_client_tts_isconnect = 0 #是否连接成功
         self.AI_client_tts_num = 2
         self.AI_client_tts_timer = osTimer()
         self.AI_client_tts_data_len = 0
+        self.AI_client_tts_tra_flag = 0
+        self.tts_time_count = 0
+        self.tts_data_tmp = bytes()
         self.press_state = 0
         self.AI_label_str = ""
         # AI_press_btn.add_event_cb(lambda e: EventMesh.callback_wrapper(self.talking_cb(e)),
@@ -315,7 +319,12 @@ class AIScreen(Screen):#AI_GUI
             try:
                 # 死循环接收数据
                 recv_data = cli.recv()
-                self.AI_client_chat_isconnect = 1
+                if not recv_data:
+                    # 服务器关闭连接或客户端关闭连接
+                    print("AI_client_chat_recv close")
+                    #self.AI_client_chat_isconnect = 0
+                    #self.websocket_deconnect_chat()
+                    break
                 try:
                     #print("AI_client_chat_recv recv_data = {}".format(recv_data))
                     jsload_data =  ujson.loads(recv_data)
@@ -329,17 +338,16 @@ class AIScreen(Screen):#AI_GUI
                     else:
                         # if self.AI_label_str:
                         #     self.AI_client_tts_send(self.AI_label_str)#TTS语音播放AI结果
-                        self.AI_label_str = ""
+                        
                         if jsload_data['type']=='start':
+                            self.AI_label_str = ""
+                            self.AI_client_chat_end_flag = 0
                             self.AI_client_tts_start()
+                        elif jsload_data['type']=='end':
+                            self.AI_client_chat_end_flag = 1
                 except Exception as e:
                     usys.print_exception(e)
-                if not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_chat_recv close")
-                    #self.AI_client_chat_isconnect = 0
-                    #self.websocket_deconnect_chat()
-                    break
+                
             except Exception as e:
                     usys.print_exception(e)
                     break
@@ -358,73 +366,110 @@ class AIScreen(Screen):#AI_GUI
             except Exception as e:
                 usys.print_exception(e)
             self.AI_client_tts_recv_id = 0
-        _thread.stack_size(20*1024)
+        #_thread.stack_size(20*1024)
         self.AI_client_tts_recv_id = _thread.start_new_thread(self.AI_client_tts_recv, (self.AI_client_tts,))
-        _thread.stack_size(8*1024)
+        #_thread.stack_size(8*1024)
         self.AI_client_tts_isconnect = 1
     def websocket_deconnect_tts(self):
         if self.AI_client_tts_isconnect == 1:
             self.AI_client_tts_isconnect = 0
             self.AI_client_tts.close()
     def AI_client_tts_timer_cb(self,*argc):
-        if len(self.AI_client_chat_play_str) >0 and self.AI_client_tts_data_len < 50*1024:
-            play_str = sub_utf8_String(self.AI_client_chat_play_str,30)#按中文切割字符串
+        self.tts_time_count+=1
+        #tts数据入队
+        #self.AI_client_tts_put_data()
+        #字符串分段发送,等待播放缓存变小
+        if len(self.AI_client_chat_play_str) >0  and self.AI_client_tts_data_len < 50*1024:
+            play_str = sub_utf8_String(self.AI_client_chat_play_str,40)#按中文切割字符串
             self.AI_client_tts_send(play_str)#TTS语音播放AI结果
             self.AI_client_chat_play_str = self.AI_client_chat_play_str[len(play_str):]
-            print("TTS play:{}!!!!!!".format(play_str))
+            self.AI_client_tts_tra_flag = 1
+            print("TTS play:{}".format(play_str))
+        if len(self.AI_client_chat_play_str) <=0 and self.AI_client_chat_end_flag ==1:
+            self.AI_client_tts_end()
+        EventMesh.publish("system_sleep_rest")#防止黑屏
     def AI_client_tts_send(self,data_str):
-        data_l ={"header": {"event": "RunSynthesis","trace_id": "3fa6b9e6a30b407ea38ad7ae69e6c291"},"payload": {"text":"%s"%(data_str)}}        
+        #data_l ={"header": {"event": "RunSynthesis","trace_id": "3fa6b9e6a30b407ea38ad7ae69e6c291"},"payload": {"text":"%s"%(data_str)}}        
+        data_l ={
+            "header": {
+                "event": "LongTextStream",
+                "trace_id": "3fa6b9e6a30b407ea38ad7ae69e6c291"
+            },
+            "payload": {
+                "voice":"xiaoyun",
+                "format":"mp3",
+                "sample_rate":8000,
+                "volume":100,
+                "speech_rate":0,
+                "text":"%s"%(data_str)
+            }
+        }
         json_data = ujson.dumps(data_l)
-        #print("AI_client_tts_send:{}".format(json_data))
-        # self.record.stop()#关闭录音
-        # self.record_timer.stop()#关闭定时器
-        #self.AI_client_tts.send(json_data)
         self.AI_send_data_queue.put([self.AI_client_tts_num,json_data]) 
     def AI_client_tts_start(self):
         data_l ={"header": {"event": "StartSynthesis","trace_id": "3fa6b9e6a30b407ea38ad7ae69e6c291"},
-            "payload": {"voice":"xiaoyun","format":"mp3","sample_rate":8000,"volume":50,"speech_rate":0,}}
+            "payload": {"voice":"xiaoyun","format":"mp3","sample_rate":8000,"volume":80,"speech_rate":1,}}
         print("\r\nAI_client_tts_start!!!!!!!!!!!!\r\n")
         json_data = ujson.dumps(data_l)
         #print("AI_client_tts_send:{}".format(json_data))
         self.record.stop()#关闭录音
         self.record_timer.stop()#关闭定时器
+        self.tts_time_count = 0
+        self.tts_data_tmp = b''
+        self.AI_client_tts_data_len = 0
+        self.AI_audio_queue.clear()
         #self.AI_client_tts.send(json_data)
-        self.AI_send_data_queue.put([self.AI_client_tts_num,json_data]) 
+        #self.AI_send_data_queue.put([self.AI_client_tts_num,json_data]) 
+    def AI_client_tts_end(self):
+        data_l ={"header": {"event": "StopSynthesis","trace_id": "3fa6b9e6a30b407ea38ad7ae69e6c291"}}
+        json_data = ujson.dumps(data_l)
+        #self.AI_send_data_queue.put([self.AI_client_tts_num,json_data]) 
+    #TTS数据入队
+    def AI_client_tts_put_data(self):
+        #存够5k数据或者3秒超时
+        #if len(self.tts_data_tmp) >20*1024 or self.tts_time_count >= 3:
+            #self.AI_client_tts_data_len +=len(self.tts_data_tmp)
+            if len(self.tts_data_tmp)>0:
+                self.AI_audio_queue.put(self.tts_data_tmp)
+                print("入:{},{}".format(len(self.tts_data_tmp),self.AI_client_tts_data_len))
+            self.tts_time_count = 0
+            self.tts_data_tmp = b''
+            self.AI_client_tts_tra_flag = 0
     #文字转语音链路读数据       
     def AI_client_tts_recv(self,cli):
-        tts_data = bytes()
-        
+        self.AI_client_tts_start()
         while True:
             try:
                 # 死循环接收数据
-                recv_data = cli.recv()
                 
-                self.AI_client_tts_isconnect = 1
+                recv_data = cli.recv()
+                if not recv_data:
+                    # 服务器关闭连接或客户端关闭连接
+                    print("AI_client_tts_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+                    print("AI_client_tts_recv close!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n")
+                    break
                 try:
                     print("AI_client_tts_recv :{}".format(len(recv_data)))
-                    # #结束标志{"header":{"event":"EndSynthesis","msg":"success","status":20000000,"task_id":"ffd727e620000803280c5a6498d0e321"}}
-                    # if isinstance(recv_data, str):
-                    #     print("AI_client_tts_recv:str recv_data:{}".format(recv_data))
-                    #     if recv_data.find('\"event\":\"EndSynthesis\"') != -1:
-                    #         tts_data = tts_data[9:]
-                    #         self.AI_audio_queue.put(tts_data)
-                    #         print("tts_data:{}".format(len(tts_data)))
-                    #         self.AI_client_tts_data_len +=len(tts_data)
-                    #         tts_data = b''
-                    # else:
-                    #     tts_data+=recv_data
-                    self.AI_client_tts_data_len +=len(recv_data)
-                    self.AI_audio_queue.put(recv_data)
+                    #结束标志{"header":{"event":"EndSynthesis","msg":"success","status":20000000,"task_id":"ffd727e620000803280c5a6498d0e321"}}
+                    if isinstance(recv_data, str):
+                        print("AI_client_tts_recv:str recv_data:{}".format(recv_data))
+                        if recv_data.find('\"event\":\"EndSynthesis\"') != -1:
+                            print("EndSynthesis!!!!!!!!!!!!!!!!!\r\n")
+                            print("EndSynthesis!!!!!!!!!!!!!!!!!!\r\n")
+                            self.tts_time_count = 60#立即发送剩余数据
+                            self.tts_data_tmp=self.tts_data_tmp[9:-100]
+                            self.AI_client_tts_put_data()
+                            self.AI_client_tts_tra_flag = 0
+                    else:
+                        self.tts_data_tmp+=recv_data
+                        self.AI_client_tts_data_len+=len(recv_data)
+                        #self.AI_client_tts_put_data()
                     #utime.sleep_ms(1000)
                 except Exception as e:
                     usys.print_exception(e)
                     # print(recv_data)
                     # print(type(recv_data))
-                if not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_tts_recv close")
-                    #self.AI_client_tts_isconnect = 0
-                    break
+                
             except Exception as e:
                     usys.print_exception(e)
                     break
@@ -434,7 +479,10 @@ class AIScreen(Screen):#AI_GUI
     #语音转文字链路
     def websocket_connect_asr(self):
         print("websocket_connect_asr:{}".format(self.AI_client_asr_isconnect))
-        #if self.AI_client_asr_isconnect == 0:
+        try:
+            self.websocket_deconnect_asr()#先断一次,预防出错
+        except Exception as e:
+            usys.print_exception(e)   
         self.AI_client_asr = uwebsocket.Client.connect('ws://121.40.67.151:9099/asr/ws', debug=True)
         # 线程接收数据
         if self.AI_client_asr_recv_id != 0:
@@ -453,6 +501,7 @@ class AIScreen(Screen):#AI_GUI
         #self.AI_client_asr.send(data_bytes)
         self.AI_send_data_queue.put([self.AI_client_asr_num,data_bytes]) 
     def AI_client_asr_start(self):
+        
         self.AI_send_data_queue.put([self.AI_client_asr_num,"{\"header\":{\"event\":\"StartTranscription\",\"trace_id\":\"3fa6b9e6a30b407ea38ad7ae69e6c291\"},\"payload\":{\"format\":\"amr\",\"sample_rate\":8000}}"]) 
     #语音转文字链路读数据       
     def AI_client_asr_recv(self,cli):
@@ -461,33 +510,39 @@ class AIScreen(Screen):#AI_GUI
             try:
                 # 死循环接收数据
                 recv_data = cli.recv()
+                if not recv_data:
+                    # 服务器关闭连接或客户端关闭连接
+                    print("AI_client_asr_recv close")
+                    #self.AI_client_asr_isconnect = 0
+                    #self.websocket_deconnect_asr()
+                    break
                 try:
                     if isinstance(recv_data, str):
                         jsload_data =  ujson.loads(recv_data)
                         print("jsload_data = {}".format(jsload_data))
+                        if jsload_data["result"] == None:
+                            continue 
                         if jsload_data["result"]["result"]:
                             AI_press_label_countdown.set_text(str(jsload_data["result"]["result"]))
                             if jsload_data["result"]["is_end"] == True:  #{"type":"chat","content":"你好"}
-                                
                                 #chat_data = bytearray(chat_data_str)
                                 AI_label.set_text("思考中...")
                                 self.AI_client_chat_send(str(jsload_data["result"]["result"]))
                                 print("chat_data:{}".format(str(jsload_data["result"]["result"])))
                                 self.record.stop()#关闭录音
                                 self.record_timer.stop()#关闭定时器
+                                try:
+                                    self.websocket_deconnect_asr()
+                                    break
+                                except Exception as e:
+                                    usys.print_exception(e)
                             elif jsload_data["result"]["is_end"] == False:
                                 AI_label.set_text("语音识别中...")
                 except Exception as e:
+                    print("error recv_data:{}".format(recv_data))
                     usys.print_exception(e)
-                if not recv_data:
-                    # 服务器关闭连接或客户端关闭连接
-                    print("AI_client_asr_recv close")
-                    #self.AI_client_asr_isconnect = 0
-                    #self.websocket_deconnect_asr()
-                    break
+                
             except Exception as e:
-
-                    
                     usys.print_exception(e)
                     break
         self.AI_client_asr_isconnect = 0
@@ -498,12 +553,9 @@ class AIScreen(Screen):#AI_GUI
         while True:
             #data[0]是websocket连接对象编号,data[1]是数据
             data = self.AI_send_data_queue.get()
-            if self.AI_client_asr_isconnect == 0:
-                self.websocket_connect_asr()
-            if self.AI_client_tts_isconnect == 0:
-                self.websocket_connect_tts()
-            if self.AI_client_chat_isconnect == 0:
-                self.websocket_connect_chat() 
+            
+            
+            
             
             if data != None:
                 try:
@@ -515,12 +567,18 @@ class AIScreen(Screen):#AI_GUI
                     #bytes_data = bytes(data[1])
                     #data[0].send(data[1])
                     if data[0] == self.AI_client_chat_num:
+                        if self.AI_client_chat_isconnect == 0:
+                            self.websocket_connect_chat()
                         self.AI_client_chat.send(data[1])
                         print("chat send_data:{}".format(len(data[1])))
                     if data[0] == self.AI_client_asr_num:
+                        if self.AI_client_asr_isconnect == 0:
+                            self.websocket_connect_asr()
                         print("asr send_data:{}".format(len(data[1])))
                         self.AI_client_asr.send(data[1])
                     if data[0] == self.AI_client_tts_num:
+                        if self.AI_client_tts_isconnect == 0:
+                            self.websocket_connect_tts() 
                         print("tts send_data:{}".format(len(data[1])))
                         self.AI_client_tts.send(data[1])
                 except Exception as e:
@@ -540,6 +598,7 @@ class AIScreen(Screen):#AI_GUI
                                 break
                             self.AI_client_tts_isconnect = 0
                             self.websocket_connect_tts()
+                            #self.AI_client_tts_start()
                             if self.AI_client_tts_isconnect == 1:
                                 self.AI_client_tts.send(data[1])
     ############################################
@@ -555,12 +614,16 @@ class AIScreen(Screen):#AI_GUI
                     # f.write(data)
                     try:
                         # while self.audio_play_state:
-                        #     utime.sleep_ms(1)
+                        #     pass
                         print("1playStream!!!!!!!")
                         #data = data[9:]
                         tmp=self.aud.playStream(3, data)#播放音频流
-                        print("2playStream:tmp:{} data len:{}".format(tmp,len(data)))
-                        EventMesh.publish("system_sleep_rest")#防止黑屏
+                        print("出:{},{}!!!".format(len(data),self.AI_client_tts_data_len))
+                        if tmp != 0:
+                            print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data)))
+                            print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data)))
+                            print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data)))
+                            print("2playStream:error tmp:{} data len:{}!!!!!!!!!!!!".format(tmp,len(data)))
                         self.AI_client_tts_data_len -=len(data)
                     except Exception as e:
                         print("AI_audio_queue_thread:ERROR:")
@@ -602,6 +665,7 @@ class AIScreen(Screen):#AI_GUI
         except Exception as e:
             usys.print_exception(e)
         self.AI_send_data_queue.clear()
+        self.AI_audio_queue.clear()
         self.record_timer.stop()
         self. AI_client_tts_timer.stop()
         self.aud.stopAll()