mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-21 22:53:56 +08:00
update:开启唤醒词加速 (#486)
This commit is contained in:
@@ -145,6 +145,7 @@ tmp
|
||||
.history
|
||||
.DS_Store
|
||||
main/xiaozhi-server/data
|
||||
!main/xiaozhi-server/config/assets/wakeup_words.wav
|
||||
main/manager-web/node_modules
|
||||
.config.yaml
|
||||
.secrets.yaml
|
||||
|
||||
@@ -57,6 +57,8 @@ delete_audio: true
|
||||
close_connection_no_voice_time: 120
|
||||
# TTS请求超时时间(秒)
|
||||
tts_timeout: 10
|
||||
# 开启唤醒词加速
|
||||
enable_wakeup_words_response_cache: true
|
||||
# 开场是否回复唤醒词
|
||||
enable_greeting: true
|
||||
# 说完话是否开启提示音
|
||||
|
||||
Binary file not shown.
@@ -202,7 +202,7 @@ class ConnectionHandler:
|
||||
self.client_ip_info = get_ip_info(self.client_ip)
|
||||
if self.client_ip_info is not None and "city" in self.client_ip_info:
|
||||
self.logger.bind(tag=TAG).info(f"Client ip info: {self.client_ip_info}")
|
||||
self.prompt = self.prompt + f"\n我在:{self.client_ip_info}"
|
||||
self.prompt = self.prompt + f"\nuser location:{self.client_ip_info}"
|
||||
self.dialogue.update_system_message(self.prompt)
|
||||
|
||||
def change_system_prompt(self, prompt):
|
||||
|
||||
@@ -1,8 +1,68 @@
|
||||
import json
|
||||
from config.logger import setup_logging
|
||||
from core.handle.sendAudioHandle import send_stt_message
|
||||
from core.utils.util import remove_punctuation_and_length
|
||||
import shutil
|
||||
import asyncio
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
|
||||
logger = setup_logging()
|
||||
|
||||
WAKEUP_CONFIG = {"dir": "config/assets/", "file_name": "wakeup_words", "create_time": time.time(), "refresh_time": 10,
|
||||
"words": ["很高兴见到你", "你好啊", "我们又见面了", "最近可好?", "很高兴再次和你谈话", "在干嘛"]}
|
||||
|
||||
|
||||
async def handleHelloMessage(conn):
|
||||
await conn.websocket.send(json.dumps(conn.welcome_msg))
|
||||
|
||||
|
||||
async def checkWakeupWords(conn, text):
|
||||
enable_wakeup_words_response_cache = conn.config["enable_wakeup_words_response_cache"]
|
||||
"""是否开启唤醒词加速"""
|
||||
if not enable_wakeup_words_response_cache:
|
||||
return False
|
||||
"""检查是否是唤醒词"""
|
||||
_, text = remove_punctuation_and_length(text)
|
||||
if text in conn.config.get("wakeup_words"):
|
||||
await send_stt_message(conn, text)
|
||||
conn.tts_first_text_index = 0
|
||||
conn.tts_last_text_index = 0
|
||||
conn.llm_finish_task = True
|
||||
|
||||
file = getWakeupWordFile()
|
||||
if file is None:
|
||||
asyncio.create_task(wakeupWordsResponse(conn))
|
||||
return False
|
||||
opus_packets, duration = conn.tts.audio_to_opus_data(file)
|
||||
conn.audio_play_queue.put((opus_packets, text, 0))
|
||||
if time.time() - WAKEUP_CONFIG["create_time"] > WAKEUP_CONFIG["refresh_time"]:
|
||||
asyncio.create_task(wakeupWordsResponse(conn))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getWakeupWordFile():
|
||||
"""查找config/assets/目录下名称为wakeup_words的文件"""
|
||||
for file in os.listdir(WAKEUP_CONFIG["dir"]):
|
||||
if WAKEUP_CONFIG["file_name"] in file:
|
||||
return f"config/assets/{file}"
|
||||
return None
|
||||
|
||||
|
||||
async def wakeupWordsResponse(conn):
|
||||
"""唤醒词响应"""
|
||||
wakeup_word = random.choice(WAKEUP_CONFIG["words"])
|
||||
result = conn.llm.response_no_stream(conn.prompt, wakeup_word)
|
||||
tts_file = await asyncio.to_thread(conn.tts.to_tts, result)
|
||||
if tts_file is not None and os.path.exists(tts_file):
|
||||
file_type = os.path.splitext(tts_file)[1]
|
||||
if file_type:
|
||||
file_type = file_type.lstrip('.')
|
||||
old_file = getWakeupWordFile()
|
||||
if old_file is not None:
|
||||
os.remove(old_file)
|
||||
"""将文件挪到"wakeup_words.mp3"""
|
||||
shutil.move(tts_file, WAKEUP_CONFIG["dir"] + WAKEUP_CONFIG["file_name"] + "." + file_type)
|
||||
WAKEUP_CONFIG["create_time"] = time.time()
|
||||
|
||||
@@ -2,6 +2,7 @@ from config.logger import setup_logging
|
||||
import json
|
||||
import uuid
|
||||
from core.handle.sendAudioHandle import send_stt_message
|
||||
from core.handle.helloHandle import checkWakeupWords
|
||||
from core.utils.util import remove_punctuation_and_length
|
||||
|
||||
TAG = __name__
|
||||
@@ -12,6 +13,10 @@ async def handle_user_intent(conn, text):
|
||||
# 检查是否有明确的退出命令
|
||||
if await check_direct_exit(conn, text):
|
||||
return True
|
||||
# 检查是否是唤醒词
|
||||
if await checkWakeupWords(conn, text):
|
||||
return True
|
||||
|
||||
if conn.use_function_call_mode:
|
||||
# 使用支持function calling的聊天方法,不再进行意图分析
|
||||
return False
|
||||
@@ -35,6 +40,7 @@ async def check_direct_exit(conn, text):
|
||||
return False
|
||||
|
||||
|
||||
|
||||
async def analyze_intent_with_llm(conn, text):
|
||||
"""使用LLM分析用户意图"""
|
||||
if not hasattr(conn, 'intent') or not conn.intent:
|
||||
|
||||
@@ -36,7 +36,7 @@ class TTSProviderBase(ABC):
|
||||
|
||||
return tmp_file
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).info(f"Failed to generate TTS file: {e}")
|
||||
logger.bind(tag=TAG).error(f"Failed to generate TTS file: {e}")
|
||||
return None
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@@ -73,9 +73,7 @@ def get_ip_info(ip_addr):
|
||||
resp = requests.get(url).json()
|
||||
|
||||
ip_info = {
|
||||
"city": resp.get("cityName"),
|
||||
"region": resp.get("regionName"),
|
||||
"country": resp.get("countryName")
|
||||
"city": resp.get("cityName")
|
||||
}
|
||||
return ip_info
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user