| | from fastapi import FastAPI, HTTPException |
| | from fastapi.responses import StreamingResponse |
| | from fastapi.middleware.cors import CORSMiddleware |
| | from pydantic import BaseModel |
| | import edge_tts |
| | import asyncio |
| |
|
| | app = FastAPI(title="Edge TTS API", description="基于Edge TTS的文本转语音API", version="1.0") |
| |
|
| | |
| | app.add_middleware( |
| | CORSMiddleware, |
| | allow_origins=["*"], |
| | allow_credentials=True, |
| | allow_methods=["*"], |
| | allow_headers=["*"], |
| | ) |
| |
|
| | class TTSRequest(BaseModel): |
| | text: str |
| | voice: str = "zh-CN-YunxiNeural" |
| | rate: str = "+0%" |
| | volume: str = "+0%" |
| |
|
| | @app.post("/tts", response_class=StreamingResponse, summary="文本转语音") |
| | async def text_to_speech(request: TTSRequest): |
| | try: |
| | communicate = edge_tts.Communicate(request.text, request.voice, rate=request.rate, volume=request.volume) |
| | |
| | |
| | audio_data = b"" |
| | async for chunk in communicate.stream(): |
| | if chunk["type"] == "audio": |
| | audio_data += chunk["data"] |
| | |
| | |
| | return StreamingResponse(iter([audio_data]), media_type="audio/mpeg") |
| | except Exception as e: |
| | raise HTTPException(status_code=500, detail=str(e)) |
| |
|
| | @app.get("/voices", summary="获取可用语音列表") |
| | async def get_voices(): |
| | try: |
| | voices = await edge_tts.list_voices() |
| | return [{ |
| | "short_name": voice.get("ShortName", ""), |
| | "friendly_name": voice.get("FriendlyName", voice.get("ShortName", "")), |
| | "gender": voice.get("Gender", ""), |
| | "locale": voice.get("Locale", "") |
| | } for voice in voices] |
| | except Exception as e: |
| | raise HTTPException(status_code=500, detail=str(e)) |
| |
|
| | @app.get("/", summary="首页") |
| | def read_root(): |
| | return {"message": "欢迎使用Edge TTS API", "docs": "/docs"} |
| |
|
| | if __name__ == "__main__": |
| | import uvicorn |
| | uvicorn.run(app, host="0.0.0.0", port=7860) |
| |
|