INVIDEO_BASIC / app.py
gnosticdev's picture
Update app.py
9b819da verified
raw
history blame
4.34 kB
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)