Spaces:
No application file
No application file
| from fastapi import FastAPI, UploadFile, File, Form | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import uvicorn | |
| import whisper | |
| import tempfile | |
| import os | |
| app = FastAPI() | |
| # Allow your Blogger site to communicate with this server | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["https://lyricvideogen.blogspot.com"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| print("Loading AI Model (this takes a moment on startup)...") | |
| # Using the "tiny" model so it runs fast on the free CPU tier | |
| model = whisper.load_model("tiny") | |
| async def sync_lyrics(audio: UploadFile = File(...), lyrics: str = Form(...)): | |
| print(f"Processing audio: {audio.filename}") | |
| # 1. Save the uploaded audio to a temporary file so Whisper can read it | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as temp_audio: | |
| temp_audio.write(await audio.read()) | |
| temp_audio_path = temp_audio.name | |
| try: | |
| # 2. Run the AI to detect vocal timestamps | |
| result = model.transcribe(temp_audio_path) | |
| # 3. Process the user's custom lyrics | |
| user_lines = [line.strip() for line in lyrics.split('\n') if line.strip()] | |
| timestamps = [] | |
| # 4. Map the AI's detected timestamps to the user's custom text | |
| for i, line in enumerate(user_lines): | |
| if i < len(result["segments"]): | |
| # Grab the start time of the vocal segment | |
| start_time = result["segments"][i]["start"] | |
| else: | |
| # Fallback if the user pasted more text lines than the AI heard vocals | |
| start_time = timestamps[-1]["time"] + 2.0 if timestamps else 0.0 | |
| timestamps.append({"text": line, "time": start_time}) | |
| return {"status": "success", "timestamps": timestamps} | |
| finally: | |
| # Clean up the server storage | |
| os.remove(temp_audio_path) | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |