fix: 修复ChatTTS音频代理路由和音频播放错误处理

This commit is contained in:
2026-04-22 21:57:32 +08:00
parent c93b83e2cf
commit d0fc1f8cff
3 changed files with 63 additions and 3 deletions

Binary file not shown.

29
main.py
View File

@@ -4,9 +4,10 @@
import os import os
import uvicorn import uvicorn
import aiohttp
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse from fastapi.responses import FileResponse, Response
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
# 导入后端服务 # 导入后端服务
@@ -24,6 +25,32 @@ app.add_middleware(
allow_headers=["*"], allow_headers=["*"],
) )
# ChatTTS 音频代理(解决 HTTPS 页面访问 HTTP 资源问题)
@app.get("/chattts/audio/{filename}")
async def proxy_chattts_audio(filename: str):
"""代理 ChatTTS 音频文件"""
chattts_url = os.getenv("CHATTTS_URL", "http://192.168.2.5:12002")
try:
async with aiohttp.ClientSession() as session:
async with session.get(
f"{chattts_url}/audio/{filename}",
timeout=aiohttp.ClientTimeout(total=30)
) as resp:
if resp.status != 200:
return Response(content=b'{"detail":"Audio not found"}', status_code=404, media_type="application/json")
audio_data = await resp.read()
return Response(
content=audio_data,
media_type="audio/wav",
headers={"Cache-Control": "public, max-age=3600"}
)
except Exception as e:
return Response(content=f'{"detail":"{str(e)}"}'.encode(), status_code=500, media_type="application/json")
# 挂载 API # 挂载 API
app.mount("/api", api_app) app.mount("/api", api_app)

View File

@@ -545,6 +545,25 @@
let currentVoice = 'zh-CN-XiaoxiaoNeural'; let currentVoice = 'zh-CN-XiaoxiaoNeural';
let autoPlay = true; // 自动播放开关 let autoPlay = true; // 自动播放开关
let volumeLevel = 1.5; // 音量倍率 let volumeLevel = 1.5; // 音量倍率
let audioUnlocked = false; // 音频播放是否解锁
// 解锁音频播放(浏览器需要用户交互后才能自动播放)
function unlockAudio() {
if (!audioUnlocked) {
// 创建一个静音音频来解锁
const silentAudio = new Audio();
silentAudio.play().then(() => {
audioUnlocked = true;
console.log('音频播放已解锁');
}).catch(e => {
console.log('音频解锁失败:', e);
});
}
}
// 页面点击解锁音频
document.addEventListener('click', unlockAudio, { once: true });
document.addEventListener('touchstart', unlockAudio, { once: true });
// 元素 // 元素
const statusDot = document.getElementById('statusDot'); const statusDot = document.getElementById('statusDot');
@@ -937,11 +956,25 @@
}; };
audio.onended = () => { audio.onended = () => {
icon.textContent = url.startsWith('/audio') || url.startsWith('http') ? '🔊' : '▶️'; icon.textContent = url.startsWith('/audio') || url.startsWith('http') || url.startsWith('blob:') ? '🔊' : '▶️';
btn.classList.remove('playing'); btn.classList.remove('playing');
}; };
audio.play(); audio.onerror = (e) => {
console.error('音频播放失败:', url, e);
icon.textContent = '❌';
btn.classList.remove('playing');
};
// 添加播放失败的catch
audio.play().catch(e => {
console.error('播放被阻止:', e);
icon.textContent = '🔇';
// 提示用户点击播放
if (e.name === 'NotAllowedError') {
showError('请先点击页面解锁音频播放');
}
});
} }
// 显示加载 // 显示加载