mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-29 18:23:59 +08:00
update:优化对话数据上传
This commit is contained in:
@@ -1,100 +0,0 @@
|
||||
"""
|
||||
ASR上报功能已集成到ConnectionHandler类中。
|
||||
|
||||
上报功能包括:
|
||||
1. 每个连接对象拥有自己的上报队列和处理线程
|
||||
2. 上报线程的生命周期与连接对象绑定
|
||||
3. 使用ConnectionHandler.enqueue_asr_report方法进行上报
|
||||
|
||||
具体实现请参考core/connection.py中的相关代码。
|
||||
"""
|
||||
|
||||
import os
|
||||
from config.logger import setup_logging
|
||||
from config.manage_api_client import report
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
async def report_asr(conn, text, file_path):
|
||||
"""执行ASR上报操作
|
||||
|
||||
Args:
|
||||
conn: 连接对象
|
||||
text: 识别文本
|
||||
file_path: 音频文件路径(可以为None或空字符串,表示纯文本上报)
|
||||
"""
|
||||
audio_data = None
|
||||
try:
|
||||
# 处理无音频的纯文本上报
|
||||
if not file_path or not os.path.exists(file_path):
|
||||
# 纯文本上报时使用空音频数据
|
||||
result = await report(
|
||||
mac_address=conn.device_id,
|
||||
session_id=conn.session_id,
|
||||
sort=int(conn.session_open_time),
|
||||
chat_type=1, # ASR类型为1
|
||||
content=text,
|
||||
audio=b'', # 空音频数据
|
||||
file_extension="wav"
|
||||
)
|
||||
logger.bind(tag=TAG).info(f"纯文本上报成功: {conn.device_id}, {conn.session_id}")
|
||||
else:
|
||||
# 读取文件为二进制数据
|
||||
with open(file_path, 'rb') as f:
|
||||
audio_data = f.read()
|
||||
|
||||
# 正常ASR上报(带音频)
|
||||
result = await report(
|
||||
mac_address=conn.device_id,
|
||||
session_id=conn.session_id,
|
||||
sort=int(conn.session_open_time),
|
||||
chat_type=1, # ASR类型为1
|
||||
content=text,
|
||||
audio=audio_data,
|
||||
file_extension="wav"
|
||||
)
|
||||
logger.bind(tag=TAG).info(f"ASR上报成功: {conn.device_id}, {conn.session_id},文件: {file_path}")
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"ASR上报失败: {e}")
|
||||
return None
|
||||
finally:
|
||||
# 清理资源
|
||||
if file_path and os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
logger.bind(tag=TAG).debug(f"ASR上报后删除文件: {file_path}")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"ASR上报后删除文件失败: {e}")
|
||||
|
||||
# 手动清理audio_data
|
||||
if audio_data:
|
||||
del audio_data
|
||||
|
||||
def enqueue_asr_report(conn, text, audio):
|
||||
"""将ASR数据加入上报队列
|
||||
|
||||
Args:
|
||||
conn: 连接对象
|
||||
text: 识别文本
|
||||
audio: 音频数据(可以为空列表,表示纯文本上报)
|
||||
"""
|
||||
try:
|
||||
if not audio or len(audio) == 0:
|
||||
# 纯文本上报,不需要保存文件
|
||||
file_path = None
|
||||
else:
|
||||
# 保存音频数据到文件
|
||||
file_path = conn.asr.save_audio_to_file(audio, conn.session_id)
|
||||
|
||||
# 使用连接对象的队列,传入文件路径
|
||||
conn.asr_report_queue.put((text, file_path))
|
||||
|
||||
if not audio or len(audio) == 0:
|
||||
logger.bind(tag=TAG).info(f"纯文本数据已加入上报队列: {conn.device_id}, {text[:20] if text else ''}...")
|
||||
else:
|
||||
logger.bind(tag=TAG).info(f"ASR数据已加入上报队列: {conn.device_id}, 文件: {file_path}")
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"加入ASR上报队列失败: {e}")
|
||||
@@ -1,10 +1,11 @@
|
||||
from config.logger import setup_logging
|
||||
import time
|
||||
import copy
|
||||
from core.utils.util import remove_punctuation_and_length
|
||||
from core.handle.sendAudioHandle import send_stt_message
|
||||
from core.handle.intentHandler import handle_user_intent
|
||||
from core.utils.output_counter import check_device_output_limit
|
||||
from core.handle.asrReportHandle import enqueue_asr_report
|
||||
from core.handle.ttsReportHandle import enqueue_tts_report
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
@@ -42,7 +43,7 @@ async def handleAudioMessage(conn, audio):
|
||||
text_len, _ = remove_punctuation_and_length(text)
|
||||
if text_len > 0:
|
||||
# 使用自定义模块进行上报
|
||||
enqueue_asr_report(conn, text, conn.asr_audio)
|
||||
enqueue_tts_report(conn, 1, text, copy.deepcopy(conn.asr_audio))
|
||||
|
||||
await startToChat(conn, text)
|
||||
else:
|
||||
|
||||
@@ -6,7 +6,7 @@ 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
|
||||
from core.handle.asrReportHandle import enqueue_asr_report
|
||||
from core.handle.ttsReportHandle import enqueue_tts_report
|
||||
import asyncio
|
||||
|
||||
TAG = __name__
|
||||
@@ -56,11 +56,11 @@ async def handleTextMessage(conn, message):
|
||||
await send_tts_message(conn, "stop", None)
|
||||
elif is_wakeup_words:
|
||||
# 上报纯文字数据(复用ASR上报功能,但不提供音频数据)
|
||||
enqueue_asr_report(conn, "嘿,你好呀", [])
|
||||
enqueue_tts_report(conn, 1, "嘿,你好呀", [])
|
||||
await startToChat(conn, "嘿,你好呀")
|
||||
else:
|
||||
# 上报纯文字数据(复用ASR上报功能,但不提供音频数据)
|
||||
enqueue_asr_report(conn, text, [])
|
||||
enqueue_tts_report(conn, 1, text, [])
|
||||
# 否则需要LLM对文字内容进行答复
|
||||
await startToChat(conn, text)
|
||||
elif msg_json["type"] == "iot":
|
||||
@@ -70,19 +70,22 @@ async def handleTextMessage(conn, message):
|
||||
asyncio.create_task(handleIotStatus(conn, msg_json["states"]))
|
||||
elif msg_json["type"] == "server":
|
||||
# 如果配置是从API读取的,则需要验证secret
|
||||
read_config_from_api = conn.config.get("read_config_from_api", False)
|
||||
if not read_config_from_api:
|
||||
if not conn.read_config_from_api:
|
||||
return
|
||||
# 获取post请求的secret
|
||||
post_secret = msg_json.get("content", {}).get("secret", "")
|
||||
secret = conn.config["manager-api"].get("secret", "")
|
||||
# 如果secret不匹配,则返回
|
||||
if post_secret != secret:
|
||||
await conn.websocket.send(json.dumps({
|
||||
"type": "config_update_response",
|
||||
"status": "error",
|
||||
"message": "服务器密钥验证失败"
|
||||
}))
|
||||
await conn.websocket.send(
|
||||
json.dumps(
|
||||
{
|
||||
"type": "config_update_response",
|
||||
"status": "error",
|
||||
"message": "服务器密钥验证失败",
|
||||
}
|
||||
)
|
||||
)
|
||||
return
|
||||
# 动态更新配置
|
||||
if msg_json["action"] == "update_config":
|
||||
|
||||
@@ -9,62 +9,51 @@ TTS上报功能已集成到ConnectionHandler类中。
|
||||
具体实现请参考core/connection.py中的相关代码。
|
||||
"""
|
||||
|
||||
import os
|
||||
from config.logger import setup_logging
|
||||
from config.manage_api_client import report
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
async def report_tts(conn, text, audio_data):
|
||||
|
||||
def report_tts(conn, type, text, opus_data):
|
||||
"""执行TTS上报操作
|
||||
|
||||
|
||||
Args:
|
||||
conn: 连接对象
|
||||
type: 上报类型,1为用户,2为智能体
|
||||
text: 合成文本
|
||||
audio_data: 音频二进制数据
|
||||
opus_data: opus音频数据
|
||||
"""
|
||||
try:
|
||||
# 执行上报
|
||||
result = await report(
|
||||
report(
|
||||
mac_address=conn.device_id,
|
||||
session_id=conn.session_id,
|
||||
sort=int(conn.session_open_time),
|
||||
chat_type=2, # TTS类型为2
|
||||
chat_type=type,
|
||||
content=text,
|
||||
audio=audio_data,
|
||||
file_extension="wav"
|
||||
opus_data=opus_data,
|
||||
)
|
||||
logger.bind(tag=TAG).info(f"TTS上报成功: {conn.device_id}, {conn.session_id}, 数据大小: {len(audio_data)} 字节")
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"TTS上报失败: {e}")
|
||||
return None
|
||||
finally:
|
||||
# 手动清理audio_data引用,帮助垃圾回收
|
||||
del audio_data
|
||||
|
||||
def enqueue_tts_report(conn, text, file_path):
|
||||
|
||||
def enqueue_tts_report(conn, type, text, opus_data):
|
||||
if not conn.read_config_from_api:
|
||||
return
|
||||
"""将TTS数据加入上报队列
|
||||
|
||||
|
||||
Args:
|
||||
conn: 连接对象
|
||||
text: 合成文本
|
||||
file_path: TTS音频文件路径
|
||||
opus_data: opus音频数据
|
||||
"""
|
||||
try:
|
||||
# 检查文件是否存在
|
||||
if not file_path or not os.path.exists(file_path):
|
||||
logger.bind(tag=TAG).error(f"加入TTS上报队列失败: 文件不存在 {file_path}")
|
||||
return
|
||||
|
||||
# 立即读取文件为二进制数据,因为外部会删除文件
|
||||
with open(file_path, 'rb') as f:
|
||||
audio_data = f.read()
|
||||
|
||||
# 使用连接对象的队列,传入文本和二进制数据而非文件路径
|
||||
conn.tts_report_queue.put((text, audio_data))
|
||||
|
||||
logger.bind(tag=TAG).info(f"TTS数据已加入上报队列: {conn.device_id}, 文件大小: {len(audio_data)} 字节")
|
||||
conn.tts_report_queue.put((type, text, opus_data))
|
||||
|
||||
logger.bind(tag=TAG).info(
|
||||
f"TTS数据已加入上报队列: {conn.device_id}, 音频大小: {len(opus_data)} "
|
||||
)
|
||||
except Exception as e:
|
||||
logger.bind(tag=TAG).error(f"加入TTS上报队列失败: {e}, 文件: {file_path}")
|
||||
logger.bind(tag=TAG).error(f"加入TTS上报队列失败: {text}, {e}")
|
||||
|
||||
Reference in New Issue
Block a user