Spaces:
Sleeping
Sleeping
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 | |
import random | |
from transformers import pipeline | |
import torch | |
import asyncio | |
from nltk.tokenize import sent_tokenize | |
# 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 | |
async def get_voices(): | |
voices = await edge_tts.list_voices() | |
return [v['ShortName'] for v in voices] | |
VOICE_NAMES = asyncio.run(get_voices()) | |
def generar_guion_profesional(prompt): | |
"""Genera guiones detallados con sistema de 3 niveles""" | |
try: | |
generator = pipeline( | |
"text-generation", | |
model=MODEL_NAME, | |
device=0 if torch.cuda.is_available() else -1 | |
) | |
response = generator( | |
f"Escribe un guion profesional para un video de YouTube sobre '{prompt}'. " | |
"La estructura debe incluir:\n" | |
"1. Introducci贸n atractiva\n" | |
"2. Tres secciones detalladas con subt铆tulos\n" | |
"3. Conclusi贸n impactante\n" | |
"Usa un estilo natural para narraci贸n:", | |
max_length=1000, | |
temperature=0.7, | |
top_k=50, | |
top_p=0.95, | |
num_return_sequences=1 | |
) | |
guion = response[0]['generated_text'] | |
return guion | |
except Exception as e: | |
logger.error(f"Error generando guion: {str(e)}") | |
return f"Guion de ejemplo sobre {prompt}. Introducci贸n. Desarrollo. Conclusi贸n." | |
async def crear_video_profesional(prompt, custom_script, voz_index, musica=None): | |
try: | |
# 1. Generar o usar guion | |
guion = custom_script if custom_script else generar_guion_profesional(prompt) | |
logger.info(f"Guion generado ({len(guion.split())} palabras)") | |
# 2. Generar voz | |
voz_archivo = "voz.mp3" | |
await edge_tts.Communicate(guion, VOICE_NAMES[voz_index]).save(voz_archivo) | |
audio = AudioFileClip(voz_archivo) | |
duracion_total = audio.duration | |
# 3. Crear video simple (versi贸n funcional) | |
clip = ColorClip(size=(1280, 720), color=(0, 0, 0), duration=duracion_total) | |
video_final = clip.set_audio(audio) | |
# 4. Exportar video | |
output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4" | |
video_final.write_videofile( | |
output_path, | |
fps=24, | |
codec="libx264", | |
audio_codec="aac" | |
) | |
return output_path | |
except Exception as e: | |
logger.error(f"ERROR: {str(e)}") | |
return None | |
finally: | |
if os.path.exists(voz_archivo): | |
os.remove(voz_archivo) | |
def run_async_func(prompt, custom_script, voz_index, musica=None): | |
return asyncio.run(crear_video_profesional(prompt, custom_script, voz_index, musica)) | |
# Interfaz profesional CORREGIDA | |
with gr.Blocks(theme=gr.themes.Soft(), title="Generador de Videos Profesional") as app: | |
gr.Markdown("# 馃幀 GENERADOR DE VIDEOS CON IA") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.Markdown("### Configuraci贸n del Contenido") | |
prompt = gr.Textbox(label="Tema principal", placeholder="Ej: 'Los misterios de la antigua Grecia'") | |
voz = gr.Dropdown( | |
label="Selecciona una voz", | |
choices=VOICE_NAMES, | |
value=VOICE_NAMES[0] | |
) | |
btn = gr.Button("馃殌 Generar Video", variant="primary", size="lg") | |
with gr.Column(scale=2): | |
output = gr.Video(label="Video Resultante", format="mp4") | |
# CORRECCI脫N: Quitar el par谩metro timeout que causaba el error | |
btn.click( | |
fn=run_async_func, | |
inputs=[prompt, gr.Textbox(visible=False), voz, gr.File(visible=False)], | |
outputs=output | |
) | |
if __name__ == "__main__": | |
app.launch(server_name="0.0.0.0", server_port=7860) |