diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index 1d977aa1..f2a18c84 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -57,6 +57,12 @@ delete_audio: true close_connection_no_voice_time: 120 # TTS请求超时时间(秒) tts_timeout: 10 +# 开场是否回复唤醒词 +enable_greeting: true +# 说完话是否开启提示音 +enable_stop_tts_notify: false +# 说完话是否开启提示音,音效地址 +stop_tts_notify_voice: "config/assets/tts_notify.mp3" CMD_exit: - "退出" @@ -514,3 +520,16 @@ module_test: - "你好,请介绍一下你自己" - "What's the weather like today?" - "请用100字概括量子计算的基本原理和应用前景" + +# 唤醒词,用于识别唤醒词还是讲话内容 +wakeup_words: + - "你好小智" + - "你好小志" + - "小爱同学" + - "你好小鑫" + - "你好小新" + - "小美同学" + - "小龙小龙" + - "喵喵同学" + - "小滨小滨" + - "小冰小冰" \ No newline at end of file diff --git a/main/xiaozhi-server/config/assets/tts_notify.mp3 b/main/xiaozhi-server/config/assets/tts_notify.mp3 new file mode 100644 index 00000000..ff071501 Binary files /dev/null and b/main/xiaozhi-server/config/assets/tts_notify.mp3 differ diff --git a/main/xiaozhi-server/core/handle/sendAudioHandle.py b/main/xiaozhi-server/core/handle/sendAudioHandle.py index 8999bf08..9a289d75 100644 --- a/main/xiaozhi-server/core/handle/sendAudioHandle.py +++ b/main/xiaozhi-server/core/handle/sendAudioHandle.py @@ -7,12 +7,26 @@ from core.utils.util import remove_punctuation_and_length, get_string_no_punctua TAG = __name__ logger = setup_logging() + async def sendAudioMessage(conn, audios, text, text_index=0): # 发送句子开始消息 if text_index == conn.tts_first_text_index: logger.bind(tag=TAG).info(f"发送第一段语音: {text}") await send_tts_message(conn, "sentence_start", text) + # 播放音频 + await sendAudio(conn, audios) + + await send_tts_message(conn, "sentence_end", text) + + # 发送结束消息(如果是最后一个文本) + if conn.llm_finish_task and text_index == conn.tts_last_text_index: + await send_tts_message(conn, 'stop', None) + if conn.close_after_chat: + await conn.close() + +# 播放音频 +async def sendAudio(conn, audios): # 流控参数优化 original_frame_duration = 60 # 原始帧时长(毫秒) adjusted_frame_duration = int(original_frame_duration * 0.8) # 缩短20% @@ -42,13 +56,6 @@ async def sendAudioMessage(conn, audios, text, text_index=0): if compensation > 0: await asyncio.sleep(compensation) - await send_tts_message(conn, "sentence_end", text) - - # 发送结束消息(如果是最后一个文本) - if conn.llm_finish_task and text_index == conn.tts_last_text_index: - await send_tts_message(conn, 'stop', None) - if conn.close_after_chat: - await conn.close() async def send_tts_message(conn, state, text=None): """发送 TTS 状态消息""" @@ -60,10 +67,20 @@ async def send_tts_message(conn, state, text=None): if text is not None: message["text"] = text - await conn.websocket.send(json.dumps(message)) + # TTS播放结束 if state == "stop": + # 播放提示音 + tts_notify = conn.config.get("enable_stop_tts_notify", False) + if tts_notify: + stop_tts_notify_voice = conn.config.get("stop_tts_notify_voice", "config/assets/tts_notify.mp3") + audios, duration = conn.tts.audio_to_opus_data(stop_tts_notify_voice) + await sendAudio(conn, audios) + # 清除服务端讲话状态 conn.clearSpeakStatus() + # 发送消息到客户端 + await conn.websocket.send(json.dumps(message)) + async def send_stt_message(conn, text): """发送 STT 状态消息""" diff --git a/main/xiaozhi-server/core/handle/textHandle.py b/main/xiaozhi-server/core/handle/textHandle.py index c63b9a33..3f60592a 100644 --- a/main/xiaozhi-server/core/handle/textHandle.py +++ b/main/xiaozhi-server/core/handle/textHandle.py @@ -2,7 +2,9 @@ from config.logger import setup_logging import json from core.handle.abortHandle import handleAbortMessage from core.handle.helloHandle import handleHelloMessage +from core.utils.util import remove_punctuation_and_length from core.handle.receiveAudioHandle import startToChat, handleAudioMessage +from core.handle.sendAudioHandle import send_stt_message, send_tts_message from core.handle.iotHandle import handleIotDescriptors, handleIotStatus TAG = __name__ @@ -38,7 +40,21 @@ async def handleTextMessage(conn, message): conn.client_have_voice = False conn.asr_audio.clear() if "text" in msg_json: - await startToChat(conn, msg_json["text"]) + text = msg_json["text"] + _, text = remove_punctuation_and_length(text) + + # 识别是否是唤醒词 + is_wakeup_words = text in conn.config.get("wakeup_words") + # 是否开启唤醒词回复 + enable_greeting = conn.config.get("enable_greeting", True) + + if is_wakeup_words and not enable_greeting: + # 如果是唤醒词,且关闭了唤醒词回复,就不用回答 + await send_stt_message(conn, text) + await send_tts_message(conn, "stop", None) + else: + # 否则需要LLM对文字内容进行答复 + await startToChat(conn, text) elif msg_json["type"] == "iot": if "descriptors" in msg_json: await handleIotDescriptors(conn, msg_json["descriptors"])