CoolFace
Apppublic

OpenAPI-AI/ST-STTAPI

sourceHugging Facemitupdated 4mo agoView on Hugging Face
0likes
app.py93 linesDownload Raw Back to root
1import os2import io3import traceback4import numpy as np5import scipy.io.wavfile as wavfile6from fastapi import FastAPI, HTTPException7from fastapi.responses import Response8from pydantic import BaseModel9from supertonic import TTS10import uvicorn11 12app = FastAPI(title="Supertonic TTS API")13 14class TTSRequest(BaseModel):15    text: str16    lang: str = "ru"17    voice: str = "M2"18 19print("Загрузка модели Supertonic TTS...")20tts = TTS(auto_download=True)21default_style = tts.get_voice_style(voice_name="M2")22print("Модель успешно загружена и готова к работе!")23 24@app.get("/")25async def root():26    return {27        "status": "ok",28        "message": "Supertonic TTS API is running",29        "docs": "/docs",30        "usage": "POST /api/tts с JSON: {'text': 'ваш текст', 'lang': 'ru', 'voice': 'M2'}"31    }32 33@app.post("/api/tts")34async def synthesize(request: TTSRequest):35    try:36        # 1. Получаем стиль голоса37        if request.voice == "M2":38            style = default_style39        else:40            style = tts.get_voice_style(voice_name=request.voice)41 42        # 2. Синтез43        wav, duration = tts.synthesize(request.text, voice_style=style, lang=request.lang)44 45        # 3. Конвертация аудио в numpy (если модель вернула тензор PyTorch)46        if hasattr(wav, 'cpu'):47            wav = wav.cpu().numpy()48        elif hasattr(wav, 'numpy'):49            wav = wav.numpy()50            51        wav = np.asarray(wav)52        53        # 4. Убираем лишние измерения (например, если форма (1, 48000) -> (48000,))54        wav = wav.squeeze()55        56        # 5. Нормализация и конвертация в int16 (стандарт для WAV)57        wav = wav.astype(np.float32)58        max_val = np.max(np.abs(wav))59        if max_val > 1.0:60            wav = wav / max_val61            62        # Конвертируем в int16 (от -32768 до 32767)63        wav_int16 = (wav * 32767).astype(np.int16)64 65        # 6. Получаем sample rate66        sample_rate = getattr(tts, 'sample_rate', 24000)67 68        # 7. Записываем в память через scipy69        out = io.BytesIO()70        wavfile.write(out, sample_rate, wav_int16)71        audio_bytes = out.getvalue()72 73        # 8. ИСПРАВЛЕНИЕ: Превращаем duration из numpy массива в обычный float74        # .item() безопасно извлекает скалярное значение из numpy array75        duration_float = float(np.asarray(duration).item())76 77        # 9. Возвращаем аудио78        return Response(79            content=audio_bytes,80            media_type='audio/wav',81            headers={82                "Content-Disposition": "attachment; filename=speech.wav",83                "X-Audio-Duration": str(round(duration_float, 2))84            }85        )86        87    except Exception as e:88        traceback.print_exc()89        raise HTTPException(status_code=500, detail=f"Ошибка генерации: {str(e)}")90 91if __name__ == '__main__':92    port = int(os.environ.get('PORT', 7860))93    uvicorn.run(app, host='0.0.0.0', port=port)