Spaces:
Running
Running
File size: 5,126 Bytes
9857383 |
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import gradio as gr
import moviepy.editor as mp
import numpy as np
import librosa
import librosa.display
import matplotlib.pyplot as plt
import io
import os
# Funci贸n principal para generar el video
def audio_to_video(audio_file, image_file, effect_type="waveform"):
"""
Genera un video a partir de un archivo de audio y una imagen, con un efecto visual sincronizado.
Args:
audio_file: Ruta al archivo de audio (wav o mp3).
image_file: Ruta al archivo de imagen (debe ser un formato soportado por MoviePy).
effect_type: Tipo de efecto visual a utilizar ("waveform" por defecto, otros tipos se pueden agregar).
Returns:
Ruta al archivo de video generado (mp4). Si falla, retorna un mensaje de error.
"""
try:
# 1. Cargar el audio usando Librosa
y, sr = librosa.load(audio_file)
duration = librosa.get_duration(y=y, sr=sr)
# 2. Cargar la imagen
img_clip = mp.ImageClip(image_file)
img_clip = img_clip.set_duration(duration) # Asignar la duraci贸n del audio a la imagen
# 3. Generar el efecto visual
if effect_type == "waveform":
audio_envelope = np.abs(y) # Calculate the audio envelope
# Normalize audio envelope to image dimensions
audio_envelope = audio_envelope / np.max(audio_envelope)
audio_envelope = audio_envelope * img_clip.size[1] / 2 # Scale to half the image height
def make_frame(t):
# Create a new figure for each frame
fig, ax = plt.subplots(figsize=(img_clip.size[0]/100, img_clip.size[1]/100), dpi=100) # Adjust figsize for image dimensions
ax.set_xlim(0, duration)
ax.set_ylim(-img_clip.size[1] / 2, img_clip.size[1] / 2)
ax.axis('off') # Hide axis
# Plot waveform
time_index = int(t * sr)
wave_slice = audio_envelope[max(0,time_index - sr//10):min(len(audio_envelope), time_index + sr//10)]
time_slice = np.linspace(0,0.2,len(wave_slice))
ax.plot(np.linspace(t-0.1,t+0.1,len(wave_slice)), wave_slice-img_clip.size[1]/4, color='red')
ax.plot(np.linspace(t-0.1,t+0.1,len(wave_slice)), -wave_slice+img_clip.size[1]/4, color='red')
# Convert the Matplotlib figure to an image
buf = io.BytesIO()
fig.canvas.print_png(buf)
data = np.frombuffer(buf.getvalue(), dtype=np.uint8)
img = plt.imread(io.BytesIO(data)) #read as image
plt.close(fig) # Close the figure to prevent memory leaks
return img
audio_effect_clip = mp.VideoClip(make_frame, duration=duration)
audio_effect_clip = audio_effect_clip.set_fps(24) # Set a reasonable frame rate
else:
return "Error: Efecto visual no soportado."
# 4. Overlay effect onto image
final_clip = mp.CompositeVideoClip([img_clip, audio_effect_clip.set_pos("center")])
# 5. Agregar el audio al video
audio_clip = mp.AudioFileClip(audio_file)
final_clip = final_clip.set_audio(audio_clip)
# 6. Guardar el video
output_video_path = "output.mp4"
final_clip.write_videofile(output_video_path, fps=24, codec="libx264", audio_codec="aac") # Ajustar los par谩metros de codificaci贸n seg煤n sea necesario
return output_video_path
except Exception as e:
return f"Error: {str(e)}"
# ----------------------------------
# Gradio Interface
# ----------------------------------
iface = gr.Interface(
fn=audio_to_video,
inputs=[
gr.Audio(source="upload", type="filepath", label="Subir Archivo de Audio (WAV o MP3)"),
gr.Image(source="upload", type="filepath", label="Subir Imagen"),
gr.Radio(["waveform"], value="waveform", label="Tipo de Efecto Visual (Waveform es el 煤nico soportado por ahora)")
],
outputs="video",
title="Audio to Video Generator",
description="Sube un archivo de audio y una imagen para crear un video con un efecto visual sincronizado con la m煤sica. Por ahora solo funciona el efecto 'waveform'.",
examples=[["audio_example.wav", "image_example.jpg", "waveform"]] # Add example files if you want.
)
# ----------------------------------
# Example files (optional). Create these files
# or remove the 'examples' line above.
# ----------------------------------
# Create dummy audio and image for example purposes if they don't exist
if not os.path.exists("audio_example.wav"):
sr = 22050
T = 5
t = np.linspace(0, T, int(T*sr), endpoint=False)
x = 0.5*np.sin(2*np.pi*440*t) # A4 frequency
librosa.output.write_wav("audio_example.wav", x, sr)
if not os.path.exists("image_example.jpg"):
# Create a simple placeholder image
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(6,4))
ax.text(0.5, 0.5, "Placeholder Image", ha="center", va="center")
ax.axis("off")
fig.savefig("image_example.jpg")
plt.close(fig)
iface.launch() |