import gradio as gr from pydub import AudioSegment import uuid import os UPLOAD_DIR = "uploads" OUTPUT_DIR = "outputs" CROSSFADE_MS = 20_000 # 20 segundos reales os.makedirs(UPLOAD_DIR, exist_ok=True) os.makedirs(OUTPUT_DIR, exist_ok=True) # ------------------------- # MOTOR DE MEZCLA REAL # ------------------------- def create_mix(files, progress=gr.Progress()): if not files or len(files) < 2 or len(files) > 4: raise gr.Error("Sube entre 2 y 4 canciones") progress(0, desc="Validando archivos…") paths = [] for f in files: ext = f.name.split(".")[-1].lower() if ext not in ["mp3", "wav", "flac", "m4a"]: raise gr.Error("Formato no soportado") name = f"{uuid.uuid4().hex}.{ext}" path = os.path.join(UPLOAD_DIR, name) # Copia segura (NO rename, esto arregla bugs en HF) with open(f.name, "rb") as src, open(path, "wb") as dst: dst.write(src.read()) paths.append(path) progress(10, desc="Cargando primera canción…") current = AudioSegment.from_file(paths[0]) step = 80 // (len(paths) - 1) for i, p in enumerate(paths[1:], start=1): progress(10 + step * (i - 1), desc=f"Mezclando canción {i + 1}") next_track = AudioSegment.from_file(p) current = current.append(next_track, crossfade=CROSSFADE_MS) progress(95, desc="Exportando mix…") out_name = f"monx_ai_mix_{uuid.uuid4().hex}.wav" out_path = os.path.join(OUTPUT_DIR, out_name) current.export(out_path, format="wav") progress(100, desc="Mix listo 🎶") return out_path # ------------------------- # INTERFAZ GRADIO # ------------------------- with gr.Blocks(title="MONX AI") as demo: gr.Markdown( """
Fusión de audio inteligente con crossfade