MTSeek / app.py
teszenofficial's picture
Create app.py
072eb0c verified
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(
"""
<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
)
# -------------------------
# HF ENTRYPOINT
# -------------------------
if __name__ == "__main__":
demo.launch()