add banbanmini backend
This commit is contained in:
87
talkingq-url/handlers/audio_packet_parser.py
Normal file
87
talkingq-url/handlers/audio_packet_parser.py
Normal file
@@ -0,0 +1,87 @@
|
||||
import struct
|
||||
from fastapi import WebSocket
|
||||
from services.audio_session import audio_session_manager, AudioSession
|
||||
from utils.logger import session_logger
|
||||
from services.factory import get_asr, get_llm, get_tts
|
||||
|
||||
DEVICE_ID_SIZE = 22 # 将大小设为22,在实际解析中会更灵活处理
|
||||
SESSION_ID_SIZE = 33
|
||||
SAMPLE_RATE = 16000 # 固定为16K采样率
|
||||
CHANNELS = 1 # 单声道
|
||||
SAMPLE_WIDTH = 2 # 16位 = 2字节
|
||||
|
||||
async def parse_packet(data: bytes, websocket: WebSocket):
|
||||
try:
|
||||
min_header_size = 4 + 1 + 4 # sequence_number + packet_type + data_size
|
||||
if len(data) < min_header_size:
|
||||
session_logger.warning(
|
||||
"unknown", "unknown", f"数据包太小: {len(data)} < {min_header_size}"
|
||||
)
|
||||
return None, None, None, None, None
|
||||
|
||||
null_pos = data.find(b'\x00')
|
||||
if null_pos == -1 or null_pos > 25: # 如果没找到或超出最大长度限制
|
||||
null_pos = 22 # 使用默认值
|
||||
|
||||
device_id = data[:null_pos].decode("ascii")
|
||||
|
||||
session_start = null_pos + 1
|
||||
session_end = session_start + SESSION_ID_SIZE
|
||||
session_data = data[session_start:session_end]
|
||||
session_null_pos = session_data.find(b'\x00')
|
||||
|
||||
if session_null_pos != -1:
|
||||
session_id = session_data[:session_null_pos].decode("ascii")
|
||||
else:
|
||||
session_id = session_data.decode("ascii").rstrip("\x00")
|
||||
|
||||
|
||||
offset = session_start + len(session_id) + 1
|
||||
if offset + min_header_size > len(data):
|
||||
session_logger.warning(
|
||||
"unknown", "unknown", f"解析剩余头信息时数据包太小: {len(data)} < {offset + min_header_size}"
|
||||
)
|
||||
return None, None, None, None, None
|
||||
|
||||
remaining_data = data[offset:]
|
||||
offset = 0
|
||||
sequence_number = struct.unpack("<I", remaining_data[offset:offset + 4])[0]
|
||||
offset += 4
|
||||
packet_type = remaining_data[offset]
|
||||
offset += 1
|
||||
data_size = struct.unpack("<I", remaining_data[offset:offset + 4])[0]
|
||||
offset += 4
|
||||
audio_data = remaining_data[offset:offset + data_size]
|
||||
|
||||
session_key = (device_id, session_id)
|
||||
sample_rate = SAMPLE_RATE
|
||||
session = await audio_session_manager.get_session(session_key)
|
||||
|
||||
if not session:
|
||||
asr_service = await get_asr(None)
|
||||
llm_service = await get_llm(None)
|
||||
tts_service = await get_tts(None)
|
||||
|
||||
session = AudioSession(
|
||||
asr_service=asr_service,
|
||||
llm_service=llm_service,
|
||||
tts_service=tts_service,
|
||||
sample_rate=sample_rate,
|
||||
)
|
||||
session.device_id = device_id
|
||||
session.session_id = session_id
|
||||
await audio_session_manager.set_session(session_key, session)
|
||||
|
||||
if packet_type == 1:
|
||||
session.sample_rate = sample_rate
|
||||
|
||||
session.last_received_seq = max(session.last_received_seq, sequence_number)
|
||||
return session_key, session, packet_type, audio_data, sample_rate
|
||||
except Exception as e:
|
||||
session_logger.error(
|
||||
"unknown",
|
||||
"unknown",
|
||||
f"解析WebSocket数据包时出错: {str(e)}",
|
||||
exc_info=True,
|
||||
)
|
||||
return None, None, None, None, None
|
||||
Reference in New Issue
Block a user