Voice-Clone / api.py
Shanmukhcr7's picture
Upload folder using huggingface_hub
faaced4 verified
Raw
History Blame Contribute Delete
3.58 kB
import os
import shutil
from fastapi import FastAPI, UploadFile, Form, HTTPException
from fastapi.responses import FileResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
import time
# Import existing logic exactly as it was
from utils import load_and_validate_audio, save_temp_wav, save_generated_audio, generate_history_list
from generate import generate_speech
from config import OUTPUTS_DIR, UPLOADS_DIR
app = FastAPI(title="Voice Cloning API")
# Add CORS to allow frontend communication
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.post("/api/generate")
async def api_generate(
audio_file: UploadFile,
text_prompt: str = Form(...)
):
if not text_prompt or not text_prompt.strip():
raise HTTPException(status_code=400, detail="Please enter some text to generate.")
temp_upload_path = os.path.join(UPLOADS_DIR, audio_file.filename)
try:
# Save the uploaded file temporarily
with open(temp_upload_path, "wb") as buffer:
shutil.copyfileobj(audio_file.file, buffer)
# 1. Load and validate (Using EXACT same logic as before)
y, sr = load_and_validate_audio(temp_upload_path)
# 2. Save processed wav for model
processed_path = save_temp_wav(y, sr, temp_upload_path)
# 3. Generate speech
out_sr, out_y, gen_time = generate_speech(text_prompt, processed_path)
# 4. Save output
out_path = save_generated_audio(out_y, out_sr, text_prompt)
# Cleanup processed path
if os.path.exists(processed_path):
os.remove(processed_path)
return JSONResponse(content={
"success": True,
"message": f"Generation successful in {gen_time:.1f} seconds.",
"generation_time": gen_time,
"audio_url": f"/outputs/{os.path.basename(out_path)}"
})
except ValueError as ve:
raise HTTPException(status_code=400, detail=str(ve))
except Exception as e:
raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}")
finally:
# Cleanup original upload
if os.path.exists(temp_upload_path):
os.remove(temp_upload_path)
@app.get("/api/history")
def get_history():
history = generate_history_list()
# history returns [(filename, path, size_str), ...]
# We map it to JSON for the frontend
items = []
for f in history:
items.append({
"filename": f[0],
"url": f"/outputs/{f[0]}",
"size": f[2]
})
return {"history": items}
@app.delete("/api/history/{filename}")
def delete_history_item(filename: str):
file_path = os.path.join(OUTPUTS_DIR, filename)
if os.path.exists(file_path):
os.remove(file_path)
return {"success": True}
raise HTTPException(status_code=404, detail="File not found")
@app.get("/outputs/{filename}")
def serve_audio(filename: str):
file_path = os.path.join(OUTPUTS_DIR, filename)
if os.path.exists(file_path):
return FileResponse(file_path)
raise HTTPException(status_code=404, detail="File not found")
# Serve the compiled React frontend static files
dist_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "dist")
if os.path.exists(dist_path):
app.mount("/", StaticFiles(directory=dist_path, html=True), name="static")