| import gradio as gr |
| from pydub import AudioSegment |
| import uuid |
| import os |
|
|
| UPLOAD_DIR = "uploads" |
| OUTPUT_DIR = "outputs" |
| CROSSFADE_MS = 20_000 |
|
|
| os.makedirs(UPLOAD_DIR, exist_ok=True) |
| os.makedirs(OUTPUT_DIR, exist_ok=True) |
|
|
| |
| |
| |
|
|
| 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) |
|
|
| |
| 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 |
|
|
| |
| |
| |
|
|
| with gr.Blocks(title="MONX AI") as demo: |
| gr.Markdown( |
| """ |
| <div style="text-align:center"> |
| <h1>🎵 MONX AI</h1> |
| <p>Fusión de audio inteligente con crossfade</p> |
| </div> |
| """ |
| ) |
|
|
| with gr.Column(): |
| files = gr.File( |
| label="Sube de 2 a 4 canciones", |
| file_count="multiple", |
| file_types=[".mp3", ".wav", ".flac", ".m4a"] |
| ) |
|
|
| btn = gr.Button("✨ Crear Mix", variant="primary") |
|
|
| output = gr.Audio( |
| label="Resultado", |
| type="filepath" |
| ) |
|
|
| btn.click( |
| fn=create_mix, |
| inputs=files, |
| outputs=output |
| ) |
|
|
| |
| |
| |
|
|
| if __name__ == "__main__": |
| demo.launch() |