File size: 4,086 Bytes
cbfaa69
c537a4f
374c72e
c537a4f
374c72e
c537a4f
374c72e
c537a4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a06bc2
c537a4f
6d66777
c537a4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d66777
374c72e
c537a4f
 
6d66777
c537a4f
 
 
 
 
 
6d66777
 
c537a4f
 
6d66777
c537a4f
 
6d66777
c537a4f
 
 
 
 
 
 
 
6d66777
c537a4f
6d66777
c537a4f
 
6d66777
c537a4f
 
 
 
 
6d66777
c537a4f
 
6d66777
 
c537a4f
 
 
 
 
 
 
 
 
9a06bc2
c537a4f
6d66777
374c72e
c537a4f
 
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
import gradio as gr
import asyncio
import edge_tts
import requests
import tempfile
import os
from datetime import datetime
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip

# Voz predeterminada (puedes cambiarla o cargar lista)
VOCES = [{'ShortName': 'es-ES-ElviraNeural', 'Name': 'Elvira', 'Gender': 'Female'}]
VOICE_NAMES = [f"{v['Name']} ({v['Gender']})" for v in VOCES]

# Simula función para generar texto según prompt
def generar_texto(prompt):
    # Aquí deberías integrar tu generador real, por ahora solo repetimos prompt
    return f"Este es un texto generado para el tema: {prompt}"

# Simula función para buscar videos (debes conectar con Pexels u otra API)
def buscar_videos(prompt):
    # Retorna lista simulada con links a videos (debes poner tu API real)
    return [
        {
            "video_files": [{"link": "https://filesamples.com/samples/video/mp4/sample_640x360.mp4"}],
            "duration": 10
        },
        {
            "video_files": [{"link": "https://filesamples.com/samples/video/mp4/sample_640x360.mp4"}],
            "duration": 10
        }
    ]

async def crear_video(prompt, voz_index, musica_path=None):
    try:
        texto = generar_texto(prompt)
        voz_shortname = VOCES[voz_index]['ShortName']

        # Generar audio TTS
        archivo_audio = "audio.mp3"
        await edge_tts.Communicate(texto, voz_shortname).save(archivo_audio)
        audio_clip = AudioFileClip(archivo_audio)
        duracion_audio = audio_clip.duration

        # Cargar música si se pasa
        if musica_path:
            musica_clip = AudioFileClip(musica_path).volumex(0.2)  # Volumen bajo para música
            musica_clip = musica_clip.subclip(0, duracion_audio)
            audio_final = CompositeAudioClip([musica_clip, audio_clip])
        else:
            audio_final = audio_clip

        # Descargar y preparar videos
        videos = buscar_videos(prompt)
        if not videos:
            return None

        clips = []
        for v in videos[:3]:
            video_url = v['video_files'][0]['link']
            response = requests.get(video_url, stream=True)
            temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
            for chunk in response.iter_content(chunk_size=1024*1024):
                temp_file.write(chunk)
            temp_file.close()

            clip = VideoFileClip(temp_file.name).subclip(0, min(duracion_audio/len(videos), v['duration']))
            clips.append(clip)

        video_final = concatenate_videoclips(clips)
        video_final = video_final.set_audio(audio_final)

        output_filename = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
        video_final.write_videofile(output_filename, codec="libx264", audio_codec="aac", fps=24)

        # Limpieza
        audio_clip.close()
        if musica_path:
            musica_clip.close()
        for c in clips:
            c.close()
            os.remove(c.filename)
        os.remove(archivo_audio)

        return output_filename

    except Exception as e:
        return f"Error: {e}"

def run_crear_video(prompt, voz_nombre, musica_file):
    try:
        voz_index = VOICE_NAMES.index(voz_nombre)
    except ValueError:
        voz_index = 0

    musica_path = musica_file.name if musica_file else None
    return asyncio.run(crear_video(prompt, voz_index, musica_path))


with gr.Blocks(title="Generador de Video con TTS y Música de Fondo") as demo:
    with gr.Row():
        with gr.Column():
            prompt = gr.Textbox(label="Tema del video", lines=2)
            voz = gr.Dropdown(VOICE_NAMES, label="Voz", value=VOICE_NAMES[0])
            musica = gr.File(label="Sube música de fondo (opcional, mp3/wav)", file_types=[".mp3", ".wav"])
            btn = gr.Button("Generar Video")
        with gr.Column():
            salida = gr.Video(label="Video generado")

    btn.click(run_crear_video, inputs=[prompt, voz, musica], outputs=salida)


if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7860)