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 | |
| 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") |