Initial commit: clean project structure
- Backend: FastAPI + SQLAlchemy + Celery (Python 3.11+) - Frontend: Vue 3 + TypeScript + Pinia + Tailwind - Admin Frontend: separate Vue 3 app for management - Docker Compose: 9 services orchestration - Specs: design prototypes, memory system PRD, product roadmap Cleanup performed: - Removed temporary debug scripts from backend root - Removed deprecated admin_app.py (embedded UI) - Removed duplicate docs from admin-frontend - Updated .gitignore for Vite cache and egg-info
This commit is contained in:
66
backend/app/services/adapters/tts/edge_tts.py
Normal file
66
backend/app/services/adapters/tts/edge_tts.py
Normal file
@@ -0,0 +1,66 @@
|
||||
"""EdgeTTS 免费语音生成适配器。"""
|
||||
|
||||
import time
|
||||
|
||||
import edge_tts
|
||||
|
||||
from app.core.logging import get_logger
|
||||
from app.services.adapters.base import BaseAdapter
|
||||
from app.services.adapters.registry import AdapterRegistry
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
# 默认中文女声 (晓晓)
|
||||
DEFAULT_VOICE = "zh-CN-XiaoxiaoNeural"
|
||||
|
||||
|
||||
@AdapterRegistry.register("tts", "edge_tts")
|
||||
class EdgeTTSAdapter(BaseAdapter[bytes]):
|
||||
"""EdgeTTS 语音生成适配器 (Free)。
|
||||
|
||||
不需要 API Key。
|
||||
"""
|
||||
|
||||
adapter_type = "tts"
|
||||
adapter_name = "edge_tts"
|
||||
|
||||
async def execute(self, text: str, **kwargs) -> bytes:
|
||||
"""生成语音。"""
|
||||
# 支持动态指定音色
|
||||
voice = kwargs.get("voice") or self.config.model or DEFAULT_VOICE
|
||||
|
||||
start_time = time.time()
|
||||
logger.info("edge_tts_generate_start", text_length=len(text), voice=voice)
|
||||
|
||||
# EdgeTTS 只能输出到文件,我们需要用临时文件周转一下
|
||||
# 或者直接 capture stream (communicate) 但 edge-tts 库主要面向文件
|
||||
|
||||
# 优化: 使用 communicate 直接获取 bytes,无需磁盘IO
|
||||
communicate = edge_tts.Communicate(text, voice)
|
||||
|
||||
audio_data = b""
|
||||
async for chunk in communicate.stream():
|
||||
if chunk["type"] == "audio":
|
||||
audio_data += chunk["data"]
|
||||
|
||||
elapsed = time.time() - start_time
|
||||
logger.info(
|
||||
"edge_tts_generate_success",
|
||||
elapsed_seconds=round(elapsed, 2),
|
||||
audio_size_bytes=len(audio_data),
|
||||
)
|
||||
|
||||
return audio_data
|
||||
|
||||
async def health_check(self) -> bool:
|
||||
"""检查 EdgeTTS 是否可用 (网络连通性)。"""
|
||||
try:
|
||||
# 简单生成一个词
|
||||
await self.execute("Hi")
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@property
|
||||
def estimated_cost(self) -> float:
|
||||
return 0.0 # Free!
|
||||
Reference in New Issue
Block a user