import os import asyncio import edge_tts import gradio as gr from moviepy.editor import * from transformers import pipeline import requests from datetime import datetime # 1. Configuración inicial (SIN ASYNCIO en callbacks) VOICES = asyncio.run(edge_tts.list_voices()) PEXELS_API_KEY = os.getenv("PEXELS_API_KEY") # 2. Generador de guión (sincrónico) def generar_guion(prompt): try: generator = pipeline("text-generation", model="facebook/mbart-large-50") return generator( f"Genera un guion sobre '{prompt}' (4 puntos breves):", max_length=200, num_return_sequences=1 )[0]['generated_text'] except Exception as e: print(f"Error en generación: {e}") return prompt # Fallback al texto original # 3. Función principal (sincrónica) def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None): try: # A. Generar guión guion = script_personalizado if script_personalizado else generar_guion(prompt) # B. Generar voz (solución sincrónica) os.system(f'edge-tts --voice "{voz_seleccionada}" --text "{guion}" --write-media "voz.mp3"') # C. Descargar videos headers = {"Authorization": PEXELS_API_KEY} query = prompt[:50].replace(" ", "+") response = requests.get( f"https://api.pexels.com/videos/search?query={query}&per_page=2", headers=headers, timeout=10 ) videos = response.json().get("videos", []) # D. Procesar audio audio = AudioFileClip("voz.mp3") if musica: musica_clip = AudioFileClip(musica.name) if musica_clip.duration < audio.duration: musica_clip = musica_clip.loop(duration=audio.duration) audio = CompositeAudioClip([audio, musica_clip.volumex(0.3)]) # E. Renderizar video clips = [VideoFileClip(v["video_files"][0]["link"]).subclip(0, 5) for v in videos[:2]] final_clip = concatenate_videoclips(clips).set_audio(audio) output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4" final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac", threads=2) return output_path except Exception as e: print(f"ERROR CRÍTICO: {e}") return None # 4. Interfaz (con queue enabled=False) with gr.Blocks(title="Generador de Videos", css="footer {visibility: hidden}") as app: gr.Markdown("# 🎬 GENERADOR DE VIDEOS (ESTABLE)") with gr.Row(): with gr.Column(): prompt = gr.Textbox(label="Tema principal", placeholder="Ej: 'Tecnología en 2025'") script = gr.TextArea(label="Guion personalizado (opcional)", lines=5) voz = gr.Dropdown( label="Selecciona voz", choices=[v["Name"] for v in VOICES], value="es-ES-ElviraNeural" ) musica = gr.File(label="Música (opcional)", file_types=[".mp3"]) btn = gr.Button("Generar Video", variant="primary") with gr.Column(): output = gr.Video(label="Resultado", autoplay=True) btn.click( fn=crear_video, inputs=[prompt, script, voz, musica], outputs=output, api_name="generar" # Evita usar colas ) # 5. Lanzamiento (sin colas) app.launch(enable_queue=False) # ¡Clave para evitar el error!