File size: 2,574 Bytes
9b7097e
aa61beb
c537a4f
374c72e
9b7097e
374c72e
9b7097e
 
aa61beb
 
c537a4f
9b7097e
aa61beb
c537a4f
aa61beb
6d66777
9b7097e
aa61beb
6d66777
aa61beb
 
6d66777
aa61beb
 
 
9b7097e
6d66777
9b7097e
aa61beb
 
 
6d66777
9b7097e
aa61beb
 
 
 
 
9b7097e
aa61beb
 
 
9b7097e
aa61beb
 
 
 
 
 
 
 
 
 
9b7097e
aa61beb
 
9b7097e
 
 
 
aa61beb
 
 
9b7097e
aa61beb
9b7097e
 
aa61beb
 
 
9b7097e
aa61beb
9b7097e
aa61beb
 
9a06bc2
9b7097e
aa61beb
 
 
 
6d66777
aa61beb
374c72e
c537a4f
aa61beb
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
import os
import gradio as gr
import requests
import tempfile
import logging
from datetime import datetime

import edge_tts
import nest_asyncio
import asyncio

from transformers import pipeline
from moviepy.editor import AudioFileClip, VideoFileClip, concatenate_videoclips

nest_asyncio.apply()

PEXELS_API_KEY = os.getenv("PEXELS_API_KEY")
logger = logging.getLogger(__name__)

# Carga modelo
generator = pipeline("text-generation", model="DeepESP/gpt2-spanish")

# Cargar voces
loop = asyncio.get_event_loop()
VOCES = loop.run_until_complete(edge_tts.list_voices())
VOICE_NAMES = [f"{v['Name']} ({v['Gender']})" for v in VOCES]

def generar_guion(prompt):
    prompt_text = f"Escribe un guion profesional de YouTube sobre '{prompt}':\n"
    res = generator(prompt_text, max_new_tokens=300)[0]['generated_text']
    return res.strip()

def buscar_videos(prompt, max_videos=3):
    headers = {"Authorization": PEXELS_API_KEY}
    r = requests.get(f"https://api.pexels.com/videos/search?query={prompt}&per_page={max_videos}", headers=headers)
    return r.json().get("videos", [])

def crear_video(prompt, voz_nombre):
    try:
        idx = VOICE_NAMES.index(voz_nombre)
    except:
        idx = 0

    voz_short = VOCES[idx]['ShortName']
    guion = generar_guion(prompt)

    # Guardar voz
    tts = edge_tts.Communicate(guion, voz_short)
    voz_path = "voz.mp3"
    loop.run_until_complete(tts.save(voz_path))

    audio_clip = AudioFileClip(voz_path)
    duracion = audio_clip.duration

    # Descargar videos
    videos = buscar_videos(prompt)
    clips = []
    for v in videos:
        url = v['video_files'][0]['link']
        tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
        r = requests.get(url, stream=True)
        for c in r.iter_content(1024*1024):
            tmp.write(c)
        tmp.close()
        clip = VideoFileClip(tmp.name).subclip(0, min(v['duration'], duracion / len(videos)))
        clips.append(clip)

    final = concatenate_videoclips(clips).set_audio(audio_clip)
    salida = f"video_{datetime.now().strftime('%H%M%S')}.mp4"
    final.write_videofile(salida, fps=24)

    return salida

def run(prompt, voz):
    return crear_video(prompt, voz)

with gr.Blocks() as app:
    entrada = gr.Textbox(label="Tema del video")
    voz = gr.Dropdown(VOICE_NAMES, label="Voz", value=VOICE_NAMES[0])
    boton = gr.Button("Generar Video")
    salida = gr.Video(label="Resultado")

    boton.click(fn=run, inputs=[entrada, voz], outputs=salida)

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