INVIDEO_BASIC / app.py
gnosticdev's picture
Update app.py
c7b9a72 verified
raw
history blame
3.48 kB
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!