from fastapi import FastAPI, Form, UploadFile, File, HTTPException from fastapi.responses import HTMLResponse, JSONResponse from typing import Optional import uvicorn from voice_processing import tts, get_model_names, voice_mapping, get_unique_filename import os import base64 import numpy as np import librosa #import soundfile as sf from scipy.io import wavfile # HTML and JavaScript for frontend (defined as a string) html = """ TTS Converter

Text-to-Speech Conversion













""" app = FastAPI() @app.get("/") def read_root(): return HTMLResponse(content=html, status_code=200) @app.get("/models") def get_models(): return get_model_names() @app.get("/voices") def get_voices(): return list(voice_mapping.keys()) def save_audio_data_to_file(audio_data, sample_rate=40000): file_path = get_unique_filename('wav') # Generate a unique file name wavfile.write(file_path, sample_rate, audio_data) return file_path @app.post("/convert") async def convert_tts(model_name: str = Form(...), tts_text: str = Form("Текстыг оруулна уу."), selected_voice: str = Form(...), slang_rate: float = Form(...), use_uploaded_voice: bool = Form(False), voice_upload: Optional[UploadFile] = File(None)): edge_tts_voice = voice_mapping.get(selected_voice) if not edge_tts_voice: raise HTTPException(status_code=400, detail=f"Invalid voice '{selected_voice}'.") voice_upload_file = None if use_uploaded_voice: if voice_upload is None: raise HTTPException(status_code=400, detail="No voice file uploaded") voice_upload_file = await voice_upload.read() # Process the text input or uploaded voice info, edge_tts_output_path, tts_output_data,edge_output_file = await tts( model_name, tts_text, edge_tts_voice, slang_rate, use_uploaded_voice, voice_upload_file ) if edge_output_file and os.path.exists(edge_output_file): os.remove(edge_output_file) _, audio_output = tts_output_data # Generate a unique filename and save the audio data audio_file_path = save_audio_data_to_file(audio_output) if isinstance(audio_output, np.ndarray) else audio_output # Encode the audio file to base64 try: with open(audio_file_path, 'rb') as file: audio_bytes = file.read() audio_data_uri = f"data:audio/wav;base64,{base64.b64encode(audio_bytes).decode('utf-8')}" except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to read audio file: {e}") finally: # Cleanup the temporary audio file if os.path.exists(audio_file_path): os.remove(audio_file_path) return JSONResponse(content={"info": info, "audio_data_uri": audio_data_uri}) def convert_to_audio_bytes(audio_file_path): try: with open(audio_file_path, 'rb') as audio_file: return audio_file.read() except Exception as e: print(f"Error reading audio file: {e}") return None if __name__ == "__main__": uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True) # More routes can be added as needed # To run the server, use the command: #uvicorn main:app --reload