Spaces:
Sleeping
Sleeping
File size: 2,865 Bytes
bf2ed68 f1f9cb5 0140161 9faf044 f1f9cb5 9faf044 0140161 9faf044 f1f9cb5 0140161 f1f9cb5 0140161 7b346cc 0140161 f1f9cb5 bf2ed68 0140161 f1f9cb5 7b346cc 0140161 f1f9cb5 7b346cc 0140161 bf2ed68 0140161 f1f9cb5 bf2ed68 f1f9cb5 bf2ed68 7b346cc f1f9cb5 bf2ed68 f1f9cb5 bf2ed68 f1f9cb5 bf2ed68 f1f9cb5 0140161 f1f9cb5 0140161 f1f9cb5 bf2ed68 f1f9cb5 bf2ed68 f1f9cb5 bf2ed68 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import gradio as gr
import subprocess
import os
import uuid
# Carpeta temporal para guardar los videos generados
TEMP_DIR = "temp_videos"
os.makedirs(TEMP_DIR, exist_ok=True)
def get_audio_duration(audio_path):
"""Obtiene duración del audio en segundos usando ffprobe"""
try:
result = subprocess.run([
"ffprobe", "-v", "error", "-show_entries",
"format=duration", "-of",
"default=noprint_wrappers=1:nokey=1", audio_path
], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
return float(result.stdout.strip())
except:
return None
def generate_video(audio_path, image_path):
if not os.path.isfile(audio_path) or not os.path.isfile(image_path):
return "❌ Missing or invalid input files."
duration = get_audio_duration(audio_path)
if not duration:
return "❌ Could not get audio duration. Check your audio file."
output_filename = os.path.join("temp_videos", f"output_{uuid.uuid4().hex[:8]}.mp4")
try:
cmd = [
"ffmpeg", "-y",
"-loop", "1", "-framerate", "1", "-i", image_path,
"-i", audio_path,
"-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2", # 👈 FIX AQUI
"-c:v", "libx264", "-preset", "ultrafast", "-tune", "stillimage",
"-c:a", "aac", "-b:a", "192k",
"-t", str(duration),
"-pix_fmt", "yuv420p", "-r", "1",
output_filename
]
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if os.path.exists(output_filename) and os.path.getsize(output_filename) > 0:
return output_filename
else:
print("FFmpeg ERROR:", result.stderr)
return "❌ Something went wrong while generating the video."
except Exception as e:
return f"⚠️ Error: {str(e)}"
# Interfaz Gradio
with gr.Blocks(theme="Taithrah/Minimal") as app:
gr.Markdown("# 🎶 Audio to Video Tool\nUpload an audio file and an image to generate a simple MP4 video (like TunesToTube)")
with gr.Row():
audio = gr.Audio(label="🎧 Upload your audio file", type="filepath")
image = gr.Image(label="🖼️ Upload your image", type="filepath")
submit = gr.Button("🚀 Generate Video")
output = gr.Video(label="🎬 Your Video")
def handle_generate(audio_path, image_path):
result = generate_video(audio_path, image_path)
# Si es una string con error, la mandamos como mensaje, si es ruta, se muestra el video
if result.endswith(".mp4") and os.path.exists(result):
return result
else:
return gr.update(value=None, visible=False), gr.update(value=result, visible=True)
submit.click(fn=handle_generate, inputs=[audio, image], outputs=output)
app.launch() |