Spaces:
Sleeping
Sleeping
File size: 5,418 Bytes
43fcbe8 d68572a 38ff849 8337d0b fa691a5 d68572a 38ff849 d68572a 9143db2 fa691a5 7c87717 d68572a 38ff849 7c87717 ab6a3fb 7c87717 38ff849 7c87717 d68572a 30c3706 7c87717 9143db2 7c87717 9143db2 30c3706 ae19496 60e6f97 7c87717 60e6f97 9143db2 30c3706 7c87717 9143db2 7c87717 38ff849 7c87717 07b3b3d d68572a 60e6f97 d68572a 60e6f97 d68572a 60e6f97 d68572a 7c87717 d68572a 7c87717 c7b9a72 30c3706 7c87717 60e6f97 7c87717 d68572a 30c3706 7c87717 d68572a 7c87717 9143db2 7c87717 d68572a 60e6f97 7c87717 9143db2 7c87717 60e6f97 7c87717 60e6f97 d68572a 7c87717 60e6f97 7c87717 30c3706 9143db2 7c87717 38ff849 7c87717 9143db2 7c87717 60e6f97 7c87717 9143db2 7c87717 d68572a 7c87717 3e716f3 38ff849 d68572a 60e6f97 ab6a3fb 38ff849 fa201eb 7c87717 fa201eb 7c87717 720c3d5 7c87717 07b3b3d 30c3706 7c87717 c9d2e08 7c87717 30c3706 7c87717 d7f3a60 7c87717 8337d0b d68572a 30c3706 7c87717 9e5ee0a d7f3a60 07b3b3d 7c87717 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import os
import subprocess
import requests
import gradio as gr
from moviepy.editor import *
from datetime import datetime
import logging
import re
import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# Configuración básica
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Configuración de entorno (usa tu propia API key de Pexels)
PEXELS_API_KEY = os.getenv("PEXELS_API_KEY") or "TU_API_KEY_AQUI"
# Voces disponibles (Edge-TTS)
VOICES = ["es-MX-DaliaNeural", "es-ES-ElviraNeural", "en-US-JennyNeural"]
# Carga el modelo GPT-2 en español (ligero y rápido)
tokenizer = GPT2Tokenizer.from_pretrained("datificate/gpt2-small-spanish")
model = GPT2LMHeadModel.from_pretrained("datificate/gpt2-small-spanish")
def generar_texto(tema):
"""Genera un texto largo y natural sobre el tema (sin estructuras forzadas)."""
try:
prompt = f"Habla extensamente sobre {tema} en un tono natural y detallado:"
inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
outputs = model.generate(
inputs.input_ids,
max_length=800,
do_sample=True,
temperature=0.7,
top_k=50,
pad_token_id=tokenizer.eos_token_id
)
texto = tokenizer.decode(outputs[0], skip_special_tokens=True)
return re.sub(r'\s+', ' ', texto).strip()
except Exception as e:
logger.error(f"Error generando texto: {e}")
return f"Contenido generado sobre {tema}."
def buscar_videos(tema):
"""Busca videos en Pexels y devuelve los 3 más relevantes."""
try:
headers = {"Authorization": PEXELS_API_KEY}
response = requests.get(
f"https://api.pexels.com/videos/search?query={tema}&per_page=3",
headers=headers,
timeout=10
)
return response.json().get("videos", [])[:3]
except Exception as e:
logger.error(f"Error buscando videos: {e}")
return []
def crear_video(tema, voz_seleccionada):
"""Genera el video final con voz y clips de video."""
try:
# 1. Generar texto
texto = generar_texto(tema)
# 2. Convertir texto a voz (Edge-TTS)
voz_archivo = "narracion.mp3"
subprocess.run([
'edge-tts',
'--voice', voz_seleccionada,
'--text', texto,
'--write-media', voz_archivo
], check=True)
# 3. Procesar audio
audio = AudioFileClip(voz_archivo)
duracion_total = audio.duration
# 4. Buscar y descargar videos
videos = buscar_videos(tema) or buscar_videos("nature")
clips = []
for i, video in enumerate(videos[:3]): # Máximo 3 videos
try:
mejor_calidad = max(video['video_files'], key=lambda x: x.get('width', 0))
url_video = mejor_calidad['link']
# Descargar video temporal
temp_file = f"temp_video_{i}.mp4"
with requests.get(url_video, stream=True) as r:
r.raise_for_status()
with open(temp_file, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
# Ajustar duración del clip
clip = VideoFileClip(temp_file)
duracion_clip = min(duracion_total / len(videos), clip.duration)
clips.append(clip.subclip(0, duracion_clip))
except Exception as e:
logger.error(f"Error procesando video {i}: {e}")
# 5. Combinar clips (o usar fondo negro si no hay videos)
if not clips:
video_final = ColorClip((1280, 720), (0, 0, 0), duration=duracion_total)
else:
video_final = concatenate_videoclips(clips, method="compose")
video_final = video_final.set_audio(audio)
# 6. Exportar video
nombre_archivo = f"video_final_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
video_final.write_videofile(
nombre_archivo,
fps=24,
codec="libx264",
audio_codec="aac",
threads=2,
preset='fast'
)
return nombre_archivo
except Exception as e:
logger.error(f"Error crítico: {e}")
return None
finally:
# Limpieza de archivos temporales
if os.path.exists(voz_archivo):
os.remove(voz_archivo)
for i in range(3):
temp_file = f"temp_video_{i}.mp4"
if os.path.exists(temp_file):
os.remove(temp_file)
# Interfaz de Gradio (sencilla y funcional)
with gr.Blocks() as app:
gr.Markdown("# 🎬 Generador Automático de Videos")
with gr.Row():
tema = gr.Textbox(label="Tema del video", placeholder="Ej: 'Historia de la inteligencia artificial'")
voz = gr.Dropdown(label="Voz", choices=VOICES, value=VOICES[0])
btn = gr.Button("Generar Video", variant="primary")
salida = gr.Video(label="Resultado")
btn.click(
fn=crear_video,
inputs=[tema, voz],
outputs=salida
)
if __name__ == "__main__":
app.launch(server_name="0.0.0.0", server_port=7860) |