File size: 3,211 Bytes
9857383
 
 
 
 
35ee7d1
 
9857383
35ee7d1
 
 
 
 
9857383
35ee7d1
 
 
9857383
35ee7d1
9857383
35ee7d1
 
 
 
9857383
35ee7d1
 
 
 
9857383
35ee7d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9857383
35ee7d1
 
 
 
 
 
 
 
 
 
 
 
 
 
9857383
 
35ee7d1
9857383
 
35ee7d1
9857383
35ee7d1
9857383
35ee7d1
 
9857383
35ee7d1
 
 
 
9857383
 
88eef70
35ee7d1
 
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
import gradio as gr
import moviepy.editor as mp
import numpy as np
import librosa
import matplotlib.pyplot as plt
from io import BytesIO
import logging

# Configuraci贸n de logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("audio_to_video")

def generate_waveform_video(audio_path, image_path):
    try:
        # 1. Cargar audio
        logger.info("Cargando archivo de audio...")
        y, sr = librosa.load(audio_path)
        duration = librosa.get_duration(y=y, sr=sr)
        logger.info(f"Duraci贸n del audio: {duration:.2f} segundos")

        # 2. Cargar imagen
        logger.info("Procesando imagen...")
        img_clip = mp.ImageClip(image_path).set_duration(duration)
        img_width, img_height = img_clip.size

        # 3. Crear efecto de waveform
        logger.info("Generando efecto visual...")
        audio_envelope = np.abs(y)  # Envelope del audio
        audio_envelope = (audio_envelope / np.max(audio_envelope)) * (img_height // 3)

        def make_frame(t):
            fig, ax = plt.subplots(figsize=(img_width/100, img_height/100), dpi=100)
            ax.set_xlim(0, duration)
            ax.set_ylim(-img_height//2, img_height//2)
            ax.axis('off')
            
            time_index = int(t * sr)
            start = max(0, time_index - sr//10)
            end = min(len(audio_envelope), time_index + sr//10)
            wave_slice = audio_envelope[start:end]
            
            x_values = np.linspace(t-0.1, t+0.1, len(wave_slice))
            ax.fill_between(x_values, wave_slice - img_height//4, -wave_slice + img_height//4, 
                           facecolor='red', alpha=0.7)
            
            buf = BytesIO()
            plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)
            plt.close(fig)
            return mp.ImageClip(buf).get_frame(0)

        logger.info("Renderizando video...")
        effect_clip = mp.VideoClip(make_frame, duration=duration).set_fps(24)
        final_clip = mp.CompositeVideoClip([img_clip, effect_clip.set_pos("center")])
        
        # 4. Combinar con audio
        final_clip = final_clip.set_audio(mp.AudioFileClip(audio_path))
        
        # 5. Guardar en memoria
        buffer = BytesIO()
        final_clip.write_videofile(buffer, fps=24, codec="libx264", 
                                  audio_codec="aac", logger=None)
        buffer.seek(0)
        logger.info("Video generado exitosamente")
        return buffer

    except Exception as e:
        logger.error(f"Error durante la generaci贸n: {str(e)}")
        return f"Error: {str(e)}"

# Interfaz Gradio
iface = gr.Interface(
    fn=generate_waveform_video,
    inputs=[
        gr.Audio(type="filepath", label="Audio (WAV/MP3)"),
        gr.Image(type="filepath", label="Imagen de Fondo"),
    ],
    outputs=gr.Video(label="Video Resultante", format="mp4"),
    title="Generador de Video con Efectos de Audio",
    description="Crea videos con efectos visuales sincronizados con el audio. Actualmente soporta efecto de waveform.",
    allow_flagging="never"
)

if __name__ == "__main__":
    logger.info("Iniciando aplicaci贸n Gradio...")
    iface.queue().launch(share=False, debug=True)