File size: 3,156 Bytes
43fcbe8
40236ce
8337d0b
 
 
 
 
c9d2e08
dd712f9
518f669
40236ce
c7b9a72
720c3d5
518f669
8337d0b
c7b9a72
 
 
518f669
c7b9a72
 
 
518f669
 
43fcbe8
c7b9a72
40236ce
720c3d5
518f669
8337d0b
 
c7b9a72
40236ce
8337d0b
518f669
8337d0b
40236ce
518f669
8337d0b
c7b9a72
 
518f669
8337d0b
518f669
8337d0b
 
 
 
 
 
 
c7b9a72
8337d0b
 
 
 
fa201eb
 
 
518f669
720c3d5
c9d2e08
518f669
 
 
d7f3a60
 
720c3d5
518f669
c7b9a72
8337d0b
c7b9a72
40236ce
c7b9a72
9e5ee0a
c7b9a72
 
8337d0b
720c3d5
518f669
8337d0b
 
 
 
518f669
9e5ee0a
d7f3a60
518f669
 
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
import os
import asyncio
import edge_tts
import gradio as gr
from moviepy.editor import *
from transformers import pipeline
import requests
from datetime import datetime

# 1. Configuraci贸n inicial
VOICES = asyncio.run(edge_tts.list_voices())
PEXELS_API_KEY = os.getenv("PEXELS_API_KEY")

# 2. Generador de gui贸n
def generar_guion(prompt):
    try:
        generator = pipeline("text-generation", model="facebook/mbart-large-50")
        return generator(
            f"Genera un guion sobre '{prompt}':",
            max_length=200,
            num_return_sequences=1
        )[0]['generated_text']
    except:
        return prompt  # Fallback

# 3. Funci贸n principal (sincr贸nica)
def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None):
    try:
        # A. Generar contenido
        guion = script_personalizado if script_personalizado else generar_guion(prompt)
        
        # B. Generar voz (soluci贸n sincr贸nica)
        os.system(f'edge-tts --voice "{voz_seleccionada}" --text "{guion}" --write-media "voz.mp3"')
        
        # C. Buscar videos en Pexels
        headers = {"Authorization": PEXELS_API_KEY}
        query = prompt[:50].replace(" ", "+")
        videos = requests.get(
            f"https://api.pexels.com/videos/search?query={query}&per_page=2",
            headers=headers,
            timeout=10
        ).json().get("videos", [])
        
        # D. Procesar m煤sica
        audio = AudioFileClip("voz.mp3")
        if musica:
            musica_clip = AudioFileClip(musica.name)
            if musica_clip.duration < audio.duration:
                musica_clip = musica_clip.loop(duration=audio.duration)
            audio = CompositeAudioClip([audio, musica_clip.volumex(0.3)])
        
        # E. Renderizar video
        clips = [VideoFileClip(v["video_files"][0]["link"]).subclip(0, 5) for v in videos[:2]]
        final_clip = concatenate_videoclips(clips).set_audio(audio)
        output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
        final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac", threads=2)
        
        return output_path
    except Exception as e:
        print(f"ERROR: {str(e)}")
        return None

# 4. Interfaz Gradio (versi贸n estable)
with gr.Blocks() as app:
    gr.Markdown("# 馃幀 GENERADOR DE VIDEOS")
    
    with gr.Row():
        with gr.Column():
            prompt = gr.Textbox(label="Tema del video")
            script = gr.TextArea(label="Guion personalizado (opcional)", lines=5)
            voz = gr.Dropdown(
                label="Selecciona voz",
                choices=[v["Name"] for v in VOICES],
                value="es-ES-ElviraNeural"
            )
            musica = gr.File(label="M煤sica (opcional)", file_types=[".mp3"])
            btn = gr.Button("Generar Video", variant="primary")
        
        with gr.Column():
            output = gr.Video(label="Resultado")

    btn.click(
        fn=crear_video,
        inputs=[prompt, script, voz, musica],
        outputs=output
    )

# 5. Lanzamiento SIN par谩metros conflictivos
app.launch(server_name="0.0.0.0", server_port=7860)