mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-25 16:43:55 +08:00
update: 恢复唤醒播放机制,待优化和改造(目前只有linkerai拥有正常保存唤醒音频to_tts)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import json
|
||||
import asyncio
|
||||
import time
|
||||
from core.providers.tts.dto.dto import SentenceType
|
||||
import asyncio
|
||||
from core.utils import textUtils
|
||||
from core.providers.tts.dto.dto import SentenceType
|
||||
|
||||
TAG = __name__
|
||||
|
||||
@@ -30,7 +30,7 @@ async def sendAudioMessage(conn, sentenceType, audios, text):
|
||||
|
||||
|
||||
# 播放音频
|
||||
async def sendAudio(conn, audios, pre_buffer=False):
|
||||
async def sendAudio(conn, audios, pre_buffer=False, frame_duration=60):
|
||||
"""
|
||||
发送单个opus包,支持流控
|
||||
Args:
|
||||
@@ -50,12 +50,8 @@ async def sendAudio(conn, audios, pre_buffer=False):
|
||||
await conn.websocket.send(audios)
|
||||
return
|
||||
|
||||
# 重置没有声音的状态
|
||||
conn.last_activity_time = time.time() * 1000
|
||||
|
||||
# 流控逻辑:确保按60ms的帧时长间隔发送
|
||||
frame_duration = 60 # 毫秒
|
||||
|
||||
# 获取或初始化流控状态
|
||||
if not hasattr(conn, "audio_flow_control"):
|
||||
conn.audio_flow_control = {
|
||||
@@ -66,13 +62,10 @@ async def sendAudio(conn, audios, pre_buffer=False):
|
||||
|
||||
flow_control = conn.audio_flow_control
|
||||
current_time = time.perf_counter()
|
||||
|
||||
# 计算期望的发送时间
|
||||
# 计算预期发送时间
|
||||
expected_time = flow_control["start_time"] + (
|
||||
flow_control["packet_count"] * frame_duration / 1000
|
||||
)
|
||||
|
||||
# 流控延迟
|
||||
delay = expected_time - current_time
|
||||
if delay > 0:
|
||||
await asyncio.sleep(delay)
|
||||
@@ -83,6 +76,38 @@ async def sendAudio(conn, audios, pre_buffer=False):
|
||||
# 更新流控状态
|
||||
flow_control["packet_count"] += 1
|
||||
flow_control["last_send_time"] = time.perf_counter()
|
||||
else:
|
||||
if audios is None or len(audios) == 0:
|
||||
return
|
||||
# 流控参数优化
|
||||
frame_duration = 60 # 帧时长(毫秒),匹配 Opus 编码
|
||||
start_time = time.perf_counter()
|
||||
play_position = 0
|
||||
|
||||
# 执行预缓冲
|
||||
pre_buffer_frames = min(3, len(audios))
|
||||
for i in range(pre_buffer_frames):
|
||||
await conn.websocket.send(audios[i])
|
||||
remaining_audios = audios[pre_buffer_frames:]
|
||||
|
||||
# 播放剩余音频帧
|
||||
for opus_packet in remaining_audios:
|
||||
if conn.client_abort:
|
||||
break
|
||||
|
||||
# 重置没有声音的状态
|
||||
conn.last_activity_time = time.time() * 1000
|
||||
|
||||
# 计算预期发送时间
|
||||
expected_time = start_time + (play_position / 1000)
|
||||
current_time = time.perf_counter()
|
||||
delay = expected_time - current_time
|
||||
if delay > 0:
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
await conn.websocket.send(opus_packet)
|
||||
|
||||
play_position += frame_duration
|
||||
|
||||
|
||||
async def send_tts_message(conn, state, text=None):
|
||||
|
||||
Reference in New Issue
Block a user