File size: 5,713 Bytes
8b274aa
15e8c2d
bafc5cd
15e8c2d
b8bd6c3
6bc8144
15e8c2d
 
6bc8144
 
 
 
3a7d955
6bc8144
 
 
2b5730b
b8bd6c3
2b5730b
b8bd6c3
b82e6a6
1829fd6
2b5730b
6bc8144
2b5730b
6bc8144
 
 
 
 
 
 
2b5730b
 
1829fd6
6bc8144
2b5730b
6bc8144
2b5730b
6bc8144
b8bd6c3
2b5730b
 
6bc8144
2b5730b
 
6bc8144
 
2b5730b
 
6bc8144
2b5730b
 
6bc8144
2b5730b
6bc8144
 
 
2b5730b
6bc8144
2b5730b
 
6bc8144
2b5730b
6bc8144
2b5730b
 
 
 
6bc8144
 
 
2b5730b
 
 
 
1d525bc
2b5730b
 
 
3a7d955
2b5730b
3a7d955
2b5730b
 
 
50a2015
2b5730b
 
 
 
 
 
 
6bc8144
2b5730b
 
 
 
 
50a2015
2b5730b
 
50a2015
2b5730b
 
 
6bc8144
 
2b5730b
6bc8144
2b5730b
163c0da
2b5730b
 
b82e6a6
2b5730b
6bc8144
2b5730b
 
 
 
 
6bc8144
 
2b5730b
 
6bc8144
2b5730b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163c0da
15e8c2d
2b5730b
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import os
import asyncio
import logging
import tempfile
import requests
from datetime import datetime
import edge_tts
import gradio as gr
import torch
from transformers import GPT2Tokenizer, GPT2LMHeadModel
from keybert import KeyBERT
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
import subprocess
import re
import math
from pydub import AudioSegment
from pexelsapi.pexels import Pexels

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

PEXELS_API_KEY = os.environ.get("PEXELS_API_KEY")

# Inicializaci贸n de modelos
MODEL_NAME = "gpt2" 
try:
    tokenizer = GPT2Tokenizer.from_pretrained(MODEL_NAME)
    model = GPT2LMHeadModel.from_pretrained(MODEL_NAME).eval()
    if tokenizer.pad_token is None:
        tokenizer.pad_token = tokenizer.eos_token
except Exception as e:
    logger.error(f"Error al cargar modelo GPT-2: {e}")
    tokenizer = model = None

try:
    kw_model = KeyBERT('multi-qa-MiniLM-L6-cos-v1')
except Exception as e:
    logger.error(f"Error al cargar KeyBERT: {e}")
    kw_model = None

# Funciones principales
def generate_script(prompt, max_length=250):
    if not tokenizer or not model:
        return "Error: Modelo no disponible"
    
    try:
        inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
        outputs = model.generate(**inputs, max_length=max_length)
        return tokenizer.decode(outputs[0], skip_special_tokens=True)
    except Exception as e:
        logger.error(f"Error generando gui贸n: {e}")
        return "Error al generar gui贸n"

async def text_to_speech(text, output_path, voice="es-ES-ElviraNeural"):
    try:
        communicate = edge_tts.Communicate(text, voice)
        await communicate.save(output_path)
        return True
    except Exception as e:
        logger.error(f"Error en TTS: {e}")
        return False

def search_pexels_videos(query_list, num_videos=3):
    if not PEXELS_API_KEY:
        raise ValueError("API key no configurada")
    
    pexel = Pexels(PEXELS_API_KEY)
    video_urls = []
    
    for query in query_list:
        try:
            results = pexel.search_videos(query=query, per_page=num_videos)
            for video in results.get('videos', []):
                best = max(video['video_files'], key=lambda x: x['width']*x['height'])
                video_urls.append(best['link'])
        except Exception as e:
            logger.error(f"Error buscando videos: {e}")
    
    return video_urls

def download_video(url, temp_dir):
    try:
        response = requests.get(url, stream=True, timeout=30)
        filename = f"video_{datetime.now().strftime('%Y%m%d%H%M%S')}.mp4"
        filepath = os.path.join(temp_dir, filename)
        
        with open(filepath, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        return filepath
    except Exception as e:
        logger.error(f"Error descargando video: {e}")
        return None

def create_video(audio_path, video_paths, output_path):
    try:
        clips = [VideoFileClip(path) for path in video_paths]
        final_clip = concatenate_videoclips(clips)
        audio = AudioFileClip(audio_path)
        
        if final_clip.duration < audio.duration:
            final_clip = final_clip.loop(duration=audio.duration)
        
        final_clip = final_clip.set_audio(audio)
        final_clip.write_videofile(
            output_path,
            codec="libx264",
            audio_codec="aac",
            fps=24
        )
        return True
    except Exception as e:
        logger.error(f"Error creando video: {e}")
        return False

# Interfaz de Gradio
with gr.Blocks() as app:
    with gr.Row():
        with gr.Column():
            prompt_type = gr.Radio(["Generar Guion", "Usar Guion Existente"], label="Tipo de Entrada")
            text_input = gr.Textbox(label="Texto", lines=5)
            generate_btn = gr.Button("Generar Video")
        
        with gr.Column():
            video_output = gr.Video()
            status_output = gr.Textbox(label="Estado")

    @generate_btn.click(inputs=[prompt_type, text_input], outputs=[video_output, status_output])
    async def generate_video(prompt_type, text):
        temp_dir = tempfile.mkdtemp()
        try:
            if prompt_type == "Generar Guion":
                script = generate_script(text)
            else:
                script = text
            
            tts_path = os.path.join(temp_dir, "audio.mp3")
            if not await text_to_speech(script, tts_path):
                return None, "Error generando voz"
            
            keywords = extract_keywords(script) if kw_model else [text.split()[0]]
            video_urls = search_pexels_videos(keywords)
            
            video_paths = []
            for url in video_urls:
                path = download_video(url, temp_dir)
                if path:
                    video_paths.append(path)
            
            if not video_paths:
                return None, "Error descargando videos"
            
            output_path = os.path.join(temp_dir, "final.mp4")
            if create_video(tts_path, video_paths, output_path):
                return output_path, "Video generado"
            else:
                return None, "Error creando video"
        except Exception as e:
            logger.error(f"Error: {str(e)}")
            return None, f"Error: {str(e)}"
        finally:
            pass  # Hugging Face limpia autom谩ticamente

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