'commit'
This commit is contained in:
@@ -18,95 +18,6 @@ router = APIRouter(prefix="/api", tags=["学伴"])
|
|||||||
# 配置日志
|
# 配置日志
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# 保留原有的HTTP接口,用于向后兼容
|
|
||||||
@router.post("/xueban/upload-audio")
|
|
||||||
async def upload_audio(file: UploadFile = File(...)):
|
|
||||||
"""
|
|
||||||
上传音频文件并进行ASR处理 - 原有接口,用于向后兼容
|
|
||||||
- 参数: file - 音频文件
|
|
||||||
- 返回: JSON包含识别结果
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 记录日志
|
|
||||||
logger.info(f"接收到音频文件: {file.filename}")
|
|
||||||
|
|
||||||
# 保存临时文件
|
|
||||||
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
|
||||||
file_ext = os.path.splitext(file.filename)[1]
|
|
||||||
temp_file_name = f"temp_audio_{timestamp}{file_ext}"
|
|
||||||
temp_file_path = os.path.join(tempfile.gettempdir(), temp_file_name)
|
|
||||||
|
|
||||||
with open(temp_file_path, "wb") as f:
|
|
||||||
content = await file.read()
|
|
||||||
f.write(content)
|
|
||||||
|
|
||||||
logger.info(f"音频文件已保存至临时目录: {temp_file_path}")
|
|
||||||
|
|
||||||
# 调用ASR服务进行处理
|
|
||||||
asr_result = await process_asr(temp_file_path)
|
|
||||||
|
|
||||||
# 删除临时文件
|
|
||||||
os.remove(temp_file_path)
|
|
||||||
logger.info(f"临时文件已删除: {temp_file_path}")
|
|
||||||
|
|
||||||
# 使用大模型生成反馈
|
|
||||||
logger.info(f"使用大模型生成反馈,输入文本: {asr_result['text']}")
|
|
||||||
response_generator = get_xueban_response_async(asr_result['text'], stream=False)
|
|
||||||
feedback_text = ""
|
|
||||||
async for chunk in response_generator:
|
|
||||||
feedback_text += chunk
|
|
||||||
logger.info(f"大模型反馈生成完成: {feedback_text}")
|
|
||||||
|
|
||||||
# 使用流式TTS生成语音
|
|
||||||
import io
|
|
||||||
audio_chunks = []
|
|
||||||
|
|
||||||
# 定义音频回调函数,收集音频块
|
|
||||||
def audio_callback(audio_chunk):
|
|
||||||
audio_chunks.append(audio_chunk)
|
|
||||||
|
|
||||||
# 获取LLM流式输出并断句
|
|
||||||
text_stream = stream_and_split_text(asr_result['text'])
|
|
||||||
|
|
||||||
# 初始化TTS处理器
|
|
||||||
tts = StreamingVolcanoTTS(max_concurrency=2)
|
|
||||||
|
|
||||||
# 流式处理文本并生成音频
|
|
||||||
await tts.synthesize_stream(text_stream, audio_callback)
|
|
||||||
|
|
||||||
# 合并所有音频块
|
|
||||||
if audio_chunks:
|
|
||||||
tts_temp_file = os.path.join(tempfile.gettempdir(), f"tts_{timestamp}.mp3")
|
|
||||||
with open(tts_temp_file, "wb") as f:
|
|
||||||
for chunk in audio_chunks:
|
|
||||||
f.write(chunk)
|
|
||||||
logger.info(f"TTS语音合成成功,文件保存至: {tts_temp_file}")
|
|
||||||
else:
|
|
||||||
raise Exception("TTS语音合成失败,未生成音频数据")
|
|
||||||
|
|
||||||
# 上传TTS音频文件到OBS
|
|
||||||
tts_audio_url = upload_file_to_obs(tts_temp_file)
|
|
||||||
os.remove(tts_temp_file) # 删除临时TTS文件
|
|
||||||
logger.info(f"TTS文件已上传至OBS: {tts_audio_url}")
|
|
||||||
|
|
||||||
# 返回结果,包含ASR文本和TTS音频URL
|
|
||||||
return JSONResponse(content={
|
|
||||||
"success": True,
|
|
||||||
"message": "音频处理和语音反馈生成成功",
|
|
||||||
"data": {
|
|
||||||
"asr_text": asr_result['text'],
|
|
||||||
"feedback_text": feedback_text,
|
|
||||||
"audio_url": tts_audio_url
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"音频处理失败: {str(e)}")
|
|
||||||
return JSONResponse(content={
|
|
||||||
"success": False,
|
|
||||||
"message": f"音频处理失败: {str(e)}"
|
|
||||||
}, status_code=500)
|
|
||||||
|
|
||||||
# 新增WebSocket接口,用于流式处理
|
# 新增WebSocket接口,用于流式处理
|
||||||
@router.websocket("/xueban/streaming-chat")
|
@router.websocket("/xueban/streaming-chat")
|
||||||
async def streaming_chat(websocket: WebSocket):
|
async def streaming_chat(websocket: WebSocket):
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user