File size: 4,279 Bytes
43fcbe8
fa691a5
38ff849
8337d0b
fa691a5
 
07b3b3d
38ff849
53ae22b
 
fa691a5
 
53ae22b
 
3e716f3
 
 
 
 
 
fa691a5
53ae22b
c1f9283
fa691a5
38ff849
 
fa691a5
 
3e716f3
38ff849
3e716f3
77ffd33
3e716f3
 
77ffd33
3e716f3
 
 
 
38ff849
53ae22b
3e716f3
07b3b3d
53ae22b
 
 
 
 
 
 
3e716f3
 
fa691a5
53ae22b
fa691a5
53ae22b
3e716f3
07b3b3d
53ae22b
3e716f3
fa691a5
3e716f3
 
c7b9a72
3e716f3
53ae22b
3e716f3
 
fa691a5
3e716f3
 
 
 
38ff849
3e716f3
 
 
fa691a5
3e716f3
 
 
38ff849
3e716f3
 
 
38ff849
3e716f3
38ff849
 
3e716f3
38ff849
fa201eb
 
38ff849
fa201eb
3e716f3
720c3d5
07b3b3d
 
 
c9d2e08
3e716f3
 
 
 
 
 
 
c1f9283
3e716f3
 
 
d7f3a60
 
3e716f3
 
 
 
 
 
 
 
8337d0b
3e716f3
 
 
 
9e5ee0a
d7f3a60
07b3b3d
3e716f3
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
131
import os
import re
import requests
import gradio as gr
from moviepy.editor import *
import edge_tts
import tempfile
import logging
from datetime import datetime
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
import nltk
from transformers import pipeline
import torch
import asyncio
from nltk.tokenize import sent_tokenize
import nest_asyncio  # Nueva importaci贸n importante

# Aplicar parche para el event loop
nest_asyncio.apply()

# Configuraci贸n inicial
nltk.download('punkt', quiet=True)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Configuraci贸n de modelos
PEXELS_API_KEY = os.getenv("PEXELS_API_KEY")
MODEL_NAME = "DeepESP/gpt2-spanish"

# Lista de voces disponibles (versi贸n optimizada)
async def get_voices():
    voices = await edge_tts.list_voices()
    return [v['ShortName'] for v in voices]

# Ejecutar en un nuevo event loop
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
VOICE_NAMES = loop.run_until_complete(get_voices())

def generar_guion_profesional(prompt):
    """Genera guiones optimizados para voz"""
    try:
        generator = pipeline(
            "text-generation",
            model=MODEL_NAME,
            device=0 if torch.cuda.is_available() else -1
        )
        
        response = generator(
            f"Escribe un guion conciso (m谩ximo 500 caracteres) sobre '{prompt}':",
            max_length=500,
            temperature=0.7,
            num_return_sequences=1
        )
        
        return response[0]['generated_text']
    except Exception as e:
        logger.error(f"Error generando guion: {str(e)}")
        return f"Guion de ejemplo sobre {prompt}. Esto es una introducci贸n. Aqu铆 est谩n los puntos principales. Conclusi贸n final."

# Funci贸n as铆ncrona optimizada
async def async_video_creation(prompt, custom_script, voz_index, musica=None):
    try:
        # 1. Generar guion
        guion = custom_script if custom_script else generar_guion_profesional(prompt)
        if len(guion) > 2000:
            guion = guion[:2000]  # Limitar tama帽o para TTS
            
        # 2. Generar voz
        voz_archivo = "voz.mp3"
        communicate = edge_tts.Communicate(text=guion, voice=VOICE_NAMES[voz_index])
        await communicate.save(voz_archivo)
        
        # 3. Crear clip de audio
        audio = AudioFileClip(voz_archivo)
        duracion = audio.duration
        
        # 4. Crear video simple (versi贸n simplificada)
        clip = ColorClip(size=(1280, 720), color=(0, 0, 0), duration=duracion)
        clip = clip.set_audio(audio)
        
        # 5. Exportar
        output_path = f"video_output_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
        clip.write_videofile(
            output_path,
            fps=24,
            codec="libx264",
            audio_codec="aac",
            threads=2
        )
        
        return output_path
        
    except Exception as e:
        logger.error(f"Error cr铆tico: {str(e)}")
        return None
    finally:
        if os.path.exists(voz_archivo):
            os.remove(voz_archivo)

# Wrapper sincr贸nico para Gradio
def generar_video(prompt, custom_script, voz_index, musica=None):
    try:
        return asyncio.run(async_video_creation(prompt, custom_script, voz_index, musica))
    except Exception as e:
        logger.error(f"Error en wrapper: {str(e)}")
        return None

# Interfaz simplificada
with gr.Blocks(title="Generador de Videos") as app:
    gr.Markdown("## 馃帴 Generador Autom谩tico de Videos")
    
    with gr.Row():
        with gr.Column():
            prompt = gr.Textbox(label="Tema del video", placeholder="Ej: Inteligencia Artificial")
            voz = gr.Dropdown(label="Voz Narradora", choices=VOICE_NAMES, value=VOICE_NAMES[0])
            btn = gr.Button("Generar Video", variant="primary")
        
        with gr.Column():
            output = gr.Video(label="Resultado", format="mp4")
    
    btn.click(
        fn=generar_video,
        inputs=[prompt, gr.Textbox(visible=False), voz],
        outputs=output,
        timeout=300  # 5 minutos de timeout
    )

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