Spaces:
Running
Running
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) |