mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-29 00:53:52 +08:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a9f809700 |
@@ -22,39 +22,45 @@ from config.manage_api_client import report as manage_report
|
|||||||
TAG = __name__
|
TAG = __name__
|
||||||
|
|
||||||
|
|
||||||
async def report(conn: "ConnectionHandler", type, text, opus_data, report_time):
|
async def report(conn: "ConnectionHandler", chat_type, text, audio_data, report_time):
|
||||||
"""执行聊天记录上报操作
|
"""执行聊天记录上报操作
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
conn: 连接对象
|
conn: 连接对象
|
||||||
type: 上报类型,1为用户,2为智能体,3为工具调用
|
chat_type: 上报类型,1为用户(ASR/PCM),2为智能体(TTS/Opus),3为工具调用
|
||||||
text: 合成文本
|
text: 合成文本
|
||||||
opus_data: opus音频数据
|
audio_data: 音频数据(chat_type=1时为PCM格式,chat_type=2时为Opus格式)
|
||||||
report_time: 上报时间
|
report_time: 上报时间
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if opus_data:
|
if audio_data:
|
||||||
audio_data = opus_to_wav(conn, opus_data)
|
|
||||||
|
if chat_type == 1:
|
||||||
|
wav_data = pcm_to_wav(conn, audio_data)
|
||||||
|
elif chat_type == 2:
|
||||||
|
wav_data = opus_to_wav(conn, audio_data)
|
||||||
else:
|
else:
|
||||||
audio_data = None
|
wav_data = None
|
||||||
|
else:
|
||||||
|
wav_data = None
|
||||||
# 执行异步上报
|
# 执行异步上报
|
||||||
await manage_report(
|
await manage_report(
|
||||||
mac_address=conn.device_id,
|
mac_address=conn.device_id,
|
||||||
session_id=conn.session_id,
|
session_id=conn.session_id,
|
||||||
chat_type=type,
|
chat_type=chat_type,
|
||||||
content=text,
|
content=text,
|
||||||
audio=audio_data,
|
audio=wav_data,
|
||||||
report_time=report_time,
|
report_time=report_time,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
conn.logger.bind(tag=TAG).error(f"聊天记录上报失败: {e}")
|
conn.logger.bind(tag=TAG).error(f"聊天记录上报失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
def opus_to_wav(conn: "ConnectionHandler", pcm_data):
|
def pcm_to_wav(conn: "ConnectionHandler", pcm_data):
|
||||||
"""将PCM数据转换为WAV格式的字节流
|
"""将PCM数据转换为WAV格式的字节流
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
output_dir: 输出目录(保留参数以保持接口兼容)
|
conn: 连接对象
|
||||||
pcm_data: PCM音频数据(可能是列表或bytes)
|
pcm_data: PCM音频数据(可能是列表或bytes)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -96,11 +102,62 @@ def opus_to_wav(conn: "ConnectionHandler", pcm_data):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def opus_to_wav(conn: "ConnectionHandler", opus_data):
|
||||||
|
"""将Opus数据转换为WAV格式的字节流
|
||||||
|
|
||||||
|
Args:
|
||||||
|
conn: 连接对象
|
||||||
|
opus_data: Opus音频数据(可能是列表或bytes)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bytes: WAV格式的音频数据
|
||||||
|
"""
|
||||||
|
decoder = None
|
||||||
|
try:
|
||||||
|
decoder = opuslib_next.Decoder(16000, 1)
|
||||||
|
pcm_data = []
|
||||||
|
|
||||||
|
if isinstance(opus_data, list):
|
||||||
|
for opus_packet in opus_data:
|
||||||
|
try:
|
||||||
|
pcm_frame = decoder.decode(opus_packet, 960)
|
||||||
|
pcm_data.append(pcm_frame)
|
||||||
|
except opuslib_next.OpusError as e:
|
||||||
|
conn.logger.bind(tag=TAG).error(f"Opus解码错误: {e}", exc_info=True)
|
||||||
|
elif isinstance(opus_data, bytes):
|
||||||
|
pcm_frame = decoder.decode(opus_data, 960)
|
||||||
|
pcm_data.append(pcm_frame)
|
||||||
|
|
||||||
|
if not pcm_data:
|
||||||
|
raise ValueError("没有有效的音频数据")
|
||||||
|
|
||||||
|
pcm_data_bytes = b"".join(pcm_data)
|
||||||
|
|
||||||
|
wav_header = bytearray()
|
||||||
|
wav_header.extend(b"RIFF")
|
||||||
|
wav_header.extend((36 + len(pcm_data_bytes)).to_bytes(4, "little"))
|
||||||
|
wav_header.extend(b"WAVE")
|
||||||
|
wav_header.extend(b"fmt ")
|
||||||
|
wav_header.extend((16).to_bytes(4, "little"))
|
||||||
|
wav_header.extend((1).to_bytes(2, "little"))
|
||||||
|
wav_header.extend((1).to_bytes(2, "little"))
|
||||||
|
wav_header.extend((16000).to_bytes(4, "little"))
|
||||||
|
wav_header.extend((32000).to_bytes(4, "little"))
|
||||||
|
wav_header.extend((2).to_bytes(2, "little"))
|
||||||
|
wav_header.extend((16).to_bytes(2, "little"))
|
||||||
|
wav_header.extend(b"data")
|
||||||
|
wav_header.extend(len(pcm_data_bytes).to_bytes(4, "little"))
|
||||||
|
|
||||||
|
return bytes(wav_header) + pcm_data_bytes
|
||||||
|
finally:
|
||||||
|
if decoder is not None:
|
||||||
|
try:
|
||||||
|
del decoder
|
||||||
|
except Exception as e:
|
||||||
|
conn.logger.bind(tag=TAG).debug(f"释放decoder资源时出错: {e}")
|
||||||
|
|
||||||
|
|
||||||
def enqueue_tts_report(conn: "ConnectionHandler", text, opus_data):
|
def enqueue_tts_report(conn: "ConnectionHandler", text, opus_data):
|
||||||
if not conn.read_config_from_api or conn.need_bind or not conn.report_tts_enable:
|
|
||||||
return
|
|
||||||
if conn.chat_history_conf == 0:
|
|
||||||
return
|
|
||||||
"""将TTS数据加入上报队列
|
"""将TTS数据加入上报队列
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -108,6 +165,10 @@ def enqueue_tts_report(conn: "ConnectionHandler", text, opus_data):
|
|||||||
text: 合成文本
|
text: 合成文本
|
||||||
opus_data: opus音频数据
|
opus_data: opus音频数据
|
||||||
"""
|
"""
|
||||||
|
if not conn.read_config_from_api or conn.need_bind or not conn.report_tts_enable:
|
||||||
|
return
|
||||||
|
if conn.chat_history_conf == 0:
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
# 使用连接对象的队列,传入文本和二进制数据而非文件路径
|
# 使用连接对象的队列,传入文本和二进制数据而非文件路径
|
||||||
if conn.chat_history_conf == 2:
|
if conn.chat_history_conf == 2:
|
||||||
@@ -164,10 +225,6 @@ def enqueue_tool_report(conn: "ConnectionHandler", tool_name: str, tool_input: d
|
|||||||
|
|
||||||
|
|
||||||
def enqueue_asr_report(conn: "ConnectionHandler", text, opus_data):
|
def enqueue_asr_report(conn: "ConnectionHandler", text, opus_data):
|
||||||
if not conn.read_config_from_api or conn.need_bind or not conn.report_asr_enable:
|
|
||||||
return
|
|
||||||
if conn.chat_history_conf == 0:
|
|
||||||
return
|
|
||||||
"""将ASR数据加入上报队列
|
"""将ASR数据加入上报队列
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -175,6 +232,10 @@ def enqueue_asr_report(conn: "ConnectionHandler", text, opus_data):
|
|||||||
text: 合成文本
|
text: 合成文本
|
||||||
opus_data: opus音频数据
|
opus_data: opus音频数据
|
||||||
"""
|
"""
|
||||||
|
if not conn.read_config_from_api or conn.need_bind or not conn.report_asr_enable:
|
||||||
|
return
|
||||||
|
if conn.chat_history_conf == 0:
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
# 使用连接对象的队列,传入文本和二进制数据而非文件路径
|
# 使用连接对象的队列,传入文本和二进制数据而非文件路径
|
||||||
if conn.chat_history_conf == 2:
|
if conn.chat_history_conf == 2:
|
||||||
|
|||||||
Reference in New Issue
Block a user