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