新增音乐播放功能,NLP识别后设备播放“下面为你播放歌曲XX”
authorazao <821478748@qq.com>
Wed, 22 Oct 2025 03:48:01 +0000 (11:48 +0800)
committerazao <821478748@qq.com>
Wed, 22 Oct 2025 03:48:01 +0000 (11:48 +0800)
后播放音乐

2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ai_VC.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/ai_VC_coze.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/main_init.py
2.sdk/project/7PIN_1_5/sdk/services/microPython/ports/quectel/core/protocol.py

index c0c3c4d..629fffa 100644 (file)
@@ -1174,7 +1174,16 @@ class AI_dev(Abstract):
         return self.usb_status
     
     def set_speech_rate(self,event,msg):
-        self.speech_rate = msg
+        #msg的取值是0.5,1.0,1.5,2.0
+        #而语速初始值是0,范围是-50~50
+        if msg == 0.5:
+            self.speech_rate = -50
+        elif msg == 1.0:
+            self.speech_rate = 0
+        elif msg == 1.5:
+            self.speech_rate = 25
+        elif msg == 2.0:
+            self.speech_rate = 50
         EventMesh.publish("set_storage_config",["speech_rate",self.speech_rate])
         print("set_speech_rate:{}".format(self.speech_rate))
     def btnInfo_queue_thread(self):
@@ -1924,7 +1933,7 @@ class device_res_author(Abstract):
                     url = "http://dmp-global.raisound.com/bz-api/dev/auth/active"
                 else:
                     url = "http://dmp.qipai.com.cn:30461/dev/auth/active"
-                    #url = "http://dmp.raisound.com/bz-api/dev/auth/active"
+                    # url = "http://dmp-dev.raisound.com/bz-api/dev/auth/active"
                 data =ujson.dumps(data)
                 response = None
                 response_result = 0
@@ -2037,7 +2046,13 @@ class device_res_author(Abstract):
                     sign_url = "http://dmp-global.raisound.com/bz-api/dev/auth/sign_in" #登入地址
                 else:
                     sign_url = "http://dmp.qipai.com.cn:30461/dev/auth/sign_in" #登入地址
-                    #sign_url = "http://dmp.raisound.com/bz-api/dev/auth/sign_in" #登入地址
+                    # sign_url = "http://dmp-dev.raisound.com/bz-api/dev/auth/sign_in" #登入地址
+                #获取验证码
+                #url = "http://dmp.qipai.com.cn:30461/dev/device/bind-code/860132066060377"
+                # token = EventMesh.publish("get_dev_token")
+                # headers_T = {"Content-Type":"application/x-www-form-urlencoded","Accept":"*/*","bz-dt":"{}".format(token)}
+                # response = request.get(url,headers = headers_T,timeout=5)
+                # data = response.json()
                 headers_T ={"Content-Type":"application/json"}
                 response_result = 0
                 response = 0
@@ -2141,7 +2156,7 @@ class device_res_author(Abstract):
             if dev_type == "7PIN_BK_EU":#英文小瑞
                 dev_tokenip = "http://dmp-global.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
             else:
-                dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
+                dev_tokenip = "http://dmp-dev.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
                 dev_tokenip = "http://dmp.qipai.com.cn:30461/dev/auth/token" #设备新令牌更新地址
                 
             token = self.dev_token
@@ -2498,6 +2513,7 @@ class AI_VC(Abstract):
         self.play_new_voice_flag =0 #播放文字留言flag
         EventMesh.subscribe("play_tts",self.play_tts)
         EventMesh.subscribe("play_new_voice",self.play_new_voice)
+        EventMesh.subscribe("play_music",self.play_music)
         EventMesh.subscribe("set_vad_silence",self.set_vad_silence)
         EventMesh.subscribe("kws_even",self.kws_even)
             
@@ -2507,6 +2523,9 @@ class AI_VC(Abstract):
         self.recv_voice = 0 #是否收到留言
         self.voice_choose_flag = 0#当tts和语音留言冲突时,为了防止语音地址被误清,做标志位在close做判断
 
+        self.music_timer = osTimer()#音乐播放定时器,等待tts播完才放音乐
+        self.music_cnt = 0 #留言定时器计数
+
         self.error_data = []
         self.asr_taskid  = ""
         self.VC_taskid  = ""
@@ -2862,7 +2881,8 @@ class AI_VC(Abstract):
         self.VC_record_state_flag = 0
         self.AI_key_long_press_flag = 0
         self.websocket_error_count = 0
-        self.AI_new_voice_url = "" #未读语音地址
+        self.AI_new_voice_url = "" #未读语音地址/音乐播放地址
+        self.music_play_flag = 0 #音乐播放标志
         self.tts_in_data_len = 0
         self.tts_out_data_len = 0
         self.VC_satrt_flag = 0
@@ -3939,15 +3959,22 @@ class AI_VC(Abstract):
                             
                             print("VC:Started!!!!!!!!\r\n")
                             print("TTS音频为:{},语音下发地址为:{}".format(self.AI_TTS_str,self.AI_new_voice_url))
-                            if self.AI_TTS_str == "" and  self.AI_new_voice_url != "":
+                            if self.AI_TTS_str == "" and  self.AI_new_voice_url != "" and self.music_play_flag == 0:
+                                self.voice_cnt = 0
                                 self.voice_timer.start(1000,1,self.voice_judge)
                             elif  self.AI_TTS_str != "" and  self.AI_new_voice_url == "":
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
-                            elif self.AI_TTS_str != "" and  self.AI_new_voice_url != "":#遇到tts和语音留言冲突时
+                            elif self.AI_TTS_str != "" and  self.AI_new_voice_url != "" and self.music_play_flag == 0:#遇到tts和语音留言冲突时(并且没有音乐播放)
                                 EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                                self.voice_cnt = 0
                                 self.voice_timer.start(1000,1,self.voice_judge) 
                                 self.voice_choose_flag = 1
                                 # self.AI_TTS_str = ""    
+                            elif self.AI_TTS_str != "" and  self.AI_new_voice_url != "" and self.music_play_flag == 1:#遇到tts和语音留言冲突时(并且有音乐播放)
+                                self.music_play_flag = 0
+                                EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_VC_synthesis})
+                                self.music_timer.start(1000,1,self.music_play) 
+                                self.voice_choose_flag = 1
                             else:
                                 #开始上传语音
                                 if dev_type != "7PIN_coze" and dev_type != "7PIN" and  dev_type != "7PIN_1_5":
@@ -4169,19 +4196,32 @@ class AI_VC(Abstract):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.voice_judger_cb})  
     def voice_judger_cb(self):
         self.voice_cnt += 1
+        print("语音留言定时器cnt = {}".format(self.voice_cnt))
         if self.voicerupt_flag == 1:#按键被按下
            self.AI_VC_start()
            EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
            self.voicerupt_flag = 0 #标志位置0
-           self.voice_timer.stop()
+           self.voice_cnt = 0
            self.recv_voice = 0#进入留言定时器,留言清空
            print("进入留言定时器1,留言清空!!!!!")
-        if self.voice_cnt == 10:#10S后退出播放
            self.voice_timer.stop()
+        if self.voice_cnt > 15:#10S后退出播放,4S是为了给语音提示留时间
+           self.voice_cnt = 0
            self.recv_voice = 0#进入留言定时器,留言清空
            if self.voice_choose_flag == 1:#播放完语音后,有冲突的时候关闭
               self.voice_choose_flag = 0
            print("进入留言定时器2,留言清空!!!!!")
+           self.voice_timer.stop()
+    #音乐播放定时器
+    def music_play(self, *args, **kwargs):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.music_play_cb})  
+    def music_play_cb(self):
+        self.music_cnt += 1
+        if self.music_cnt > 4:#4S后播放音乐,4S是为了给语音提示留时间
+           self.AI_VC_start()
+           EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_client_new_voice})#播放留言
+           self.music_cnt = 0
+           self.music_timer.stop() 
     def set_voicerupt_flag(self,event,msg):#按键控制留言播放
         self.voicerupt_flag = msg
     def get_voicerupt_flag(self,event,msg):#获取按键控制留言播放状态
@@ -5167,8 +5207,8 @@ class AI_VC(Abstract):
             json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]=""
             #json_data["payload"]["inbound_attributes"]["vad_silence"] = 1000
         elif dev_type == "7PIN_coze":
-            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]=""#
-            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]=""
+            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["bot_id"]="7550138354483298347"#
+            json_data["payload"]["dialog_attributes"]["cfg"]["bot_option"]["workflow_id"]="7549142130376671267"
             json_data["payload"]["dialog_attributes"]["provider"]="qipai"
         #
         elif dev_type == 'momo':#食梦貘
@@ -5329,6 +5369,7 @@ class AI_VC(Abstract):
         EventMesh.publish("set_storage_config",["VC_TTS_voice_key",self.VC_TTS_voice_key])
         print("VC_TTS_voice_type:{}".format(self.VC_TTS_voice_type))
         print("VC_TTS_voice_key:{}".format(self.VC_TTS_voice_key))
+    #语音留言
     def play_new_voice(self,event = None,msg= None):
         EventMesh.publish("publish_AI_btnInfo",{"func":self.play_new_voice_cb,"data":msg}) 
     def play_new_voice_cb(self,data):
@@ -5339,7 +5380,7 @@ class AI_VC(Abstract):
                 self.recv_voice = 1#收到留言
                 print("已收到最新留言!!!!!")
                 # EventMesh.publish("set_motor_time",[1,1,5,8,4])#设置马达参数
-                EventMesh.publish("play_tts",["您有一条语音留言,按下中间键可以收听",1])
+                EventMesh.publish("play_tts",["您有一条语音留言,10秒内按下中间键可以收听",1])
                 self.AI_new_voice_url = new_voice_url
             if is_close_VC != None:
                 self.Close_flag = is_close_VC
@@ -5359,7 +5400,36 @@ class AI_VC(Abstract):
         except Exception as e:
                 usys.print_exception(e)   
         pass
-    def AI_client_new_voice(self): #上传未读的语音地址
+    #音乐播放
+    def play_music(self,event = None,msg= None):
+        EventMesh.publish("publish_AI_btnInfo",{"func":self.play_music_cb,"data":msg}) 
+    def play_music_cb(self,data):
+        try:
+            music_name = data[0]
+            new_voice_url = data[1] #音频地址
+            is_close_VC = data[2]
+            if new_voice_url != "":
+                self.AI_new_voice_url = new_voice_url
+                self.music_play_flag = 1#表示音乐播放开启
+                EventMesh.publish("play_tts",["下面为您播放歌曲{}".format(music_name),1])
+            if is_close_VC != None:
+                self.Close_flag = is_close_VC
+            if self.AI_VC_send_data_queue.empty()!=True:
+                self.AI_VC_send_data_queue.clear()
+            if self.AI_ASR_send_data_queue.empty()!=True:
+                self.AI_ASR_send_data_queue.clear()
+            EventMesh.publish("open_led_all")
+            self.AI_ASR_send_buf_len = 0
+            self.VC_Speech_End()
+            self.websocket_deconnect_VC()
+            self.AI_VC_start()
+            self.play_new_voice_flag = 1
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.VC_Speech_End})
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.websocket_deconnect_VC}) 
+            # EventMesh.publish("publish_AI_btnInfo",{"func":self.AI_VC_start}) 
+        except Exception as e:
+                usys.print_exception(e)   
+    def AI_client_new_voice(self): #上传未读的语音地址/包括音频地址也可以
         json_data = \
         {
             "event": "audio.convert",
@@ -5377,7 +5447,7 @@ class AI_VC(Abstract):
         print("AI_client_new_voice!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{}".format(json_data))
         self.AI_client_VC_send(ujson.dumps(json_data))
         
-    
+
     def chenggong_tone(self):
         EventMesh.publish("audio_montage_play",["chenggong.mp3"])    
     def send_tone(self):
index a39f20e..16959bb 100644 (file)
@@ -964,6 +964,7 @@ class device_res_author(Abstract):
                 #self.dev_sign_in()
                 EventMesh.publish("dev_sign_in")
             dev_tokenip = "http://dmp.raisound.com/bz-api/dev/auth/token" #设备新令牌更新地址
+
             token = self.dev_token
             if token == None:
                 token = ""
index 0097f34..46b628f 100644 (file)
@@ -248,6 +248,7 @@ def main_init():
             pcr.add_support(pro.IOTWeb_post_bt_connect_restProtoCol())
             pcr.add_support(pro.IOTWeb_unbind_devProtoCol())
             pcr.add_support(pro.IOTWeb_user_unbind_devProtoCol())
+            pcr.add_support(pro.IOTWeb_play_MusicProtoCol())
             sm = pro.SockMangager()
 
             sm.add_support_resolver(pcr)
index 67e3a87..3846cd2 100644 (file)
@@ -681,6 +681,8 @@ class WEB_CMD_ENUM:
     USER_UNBIND_DEV_R="user_unbind_dev_R"
     USER_UNBIND_DEV_S="user_unbind_dev_S"
 
+    MUSIC_PLAY_R="music_play_R"
+    MUSIC_PLAY_S="music_play_S"
 class IOTSendCmdManager(Abstract):
     #
     def __init__(self):
@@ -2142,7 +2144,6 @@ class IOTWeb_post_sosProtoCol(ProtoCol):
 
     def recv(self, event, msg):
         """
-
         @param event:msg
         @param msg: 接收到的下行数据
         """
@@ -2466,7 +2467,38 @@ class IOTWeb_sos_listProtoCol(ProtoCol):
             read_soslist = EventMesh.publish("get_storage_config","sos_list")
             print(read_soslist)
             EventMesh.publish(WEB_CMD_ENUM.SOS_LIST_S_CMD)
+#音乐播放
+class IOTWeb_play_MusicProtoCol(ProtoCol):
+    """push_music"""
+    TYPE = "push_music"
 
+    def send(self, event, msg):
+        # print("push_music{}".format(msg))
+        # 通过websocket发送到服务器端
+        date_tmp = utime.localtime()
+        time_tmp = utime.mktime(date_tmp)
+        get_chat_config = {
+            "cmd":"push_music",
+            "ts":time_tmp,
+            "msg":"音乐播放",
+            "data":None
+        }
+        send_data = b''
+        send_data = protocol_send_total_data(get_chat_config)
+        print("send_data push_music{}".format(send_data))
+        EventMesh.publish("CHANNEL_IOT_WEB_SEND", send_data)
+
+    def recv(self, event, msg):
+        """
+        @param event:上行下发push_music
+        @param msg: 接收到的下行数据
+        """
+        #提取音乐播放名称,地址
+        musicName = msg["data"]["musicName"]
+        musicUrl = msg["data"]["musicUrl"]
+        print("提取到的音乐名称为{},路径为{}".format(musicName,musicUrl))
+        EventMesh.publish("play_music",[musicName,musicUrl,1])
+        print("recv push_music{}".format(msg))
 #音量下发
 class IOTWeb_volumeProtoCol(ProtoCol):
     """volume"""
@@ -2911,7 +2943,7 @@ class IOTWeb_chat_configProtoCol(ProtoCol):
             data = msg["data"]
             speed = None
             try:
-                speed = int(data["speed"])
+                speed = float(data["speed"])
             except Exception as e:
                 usys.print_exception(e)
             vadDuration = data["vadDuration"]