Spaces:
Running
Running
File size: 5,716 Bytes
43fcbe8 77c11ae 38ff849 8337d0b fa691a5 77c11ae 38ff849 77c11ae 99b44b3 77c11ae 9143db2 99b44b3 fa691a5 77c11ae 38ff849 77c11ae 99b44b3 38ff849 99b44b3 d68572a 77c11ae 99b44b3 d5141b3 99b44b3 d5141b3 99b44b3 d5141b3 99b44b3 d5141b3 99b44b3 38ff849 99b44b3 d5141b3 99b44b3 d5141b3 99b44b3 d5141b3 99b44b3 d68572a 99b44b3 c7b9a72 99b44b3 77c11ae 60e6f97 99b44b3 d68572a 99b44b3 77c11ae 7c87717 9143db2 99b44b3 77c11ae d5141b3 99b44b3 d5141b3 99b44b3 7c87717 d68572a 99b44b3 fa201eb 77c11ae fa201eb 99b44b3 720c3d5 07b3b3d d5141b3 7c87717 c9d2e08 99b44b3 77c11ae 99b44b3 8337d0b 99b44b3 d5141b3 9e5ee0a d7f3a60 07b3b3d d5141b3 |
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 |
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 nltk.tokenize import sent_tokenize
from transformers import pipeline
import torch
import asyncio
# 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"
# Soluci贸n robusta para obtener voces
async def get_voices():
try:
voices = await edge_tts.list_voices()
voice_names = []
for v in voices:
try:
name = v.get('Name', v.get('ShortName', 'Desconocido'))
gender = v.get('Gender', 'Desconocido')
locale = v.get('Locale', v.get('Language', 'Desconocido'))
voice_names.append(f"{name} ({gender}, {locale})")
except Exception as e:
logger.warning(f"Error procesando voz: {v} - {str(e)}")
continue
return voice_names, voices
except Exception as e:
logger.error(f"Error al obtener voces: {str(e)}")
return [], []
# Obtener voces de forma s铆ncrona para la inicializaci贸n
VOICE_NAMES, VOICES = asyncio.run(get_voices())
if not VOICES:
VOICE_NAMES = ["Voz Predeterminada (Femenino, es-ES)"]
VOICES = [{'ShortName': 'es-ES-ElviraNeural'}]
def generar_guion_profesional(prompt):
"""Genera guiones con respaldo robusto"""
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}':\n\n1. Introducci贸n\n2. Desarrollo\n3. Conclusi贸n\n\n",
max_length=800,
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"""Gui贸n de respaldo sobre {prompt}:
1. INTRODUCCI脫N: Hoy exploraremos {prompt}
2. DESARROLLO: Aspectos clave sobre el tema
3. CONCLUSI脫N: Resumen y cierre"""
def buscar_videos_avanzado(prompt, guion, num_videos=3):
"""B煤squeda con m煤ltiples respaldos"""
try:
palabras = re.findall(r'\b\w{4,}\b', prompt.lower())[:5]
response = requests.get(
f"https://api.pexels.com/videos/search?query={'+'.join(palabras)}&per_page={num_videos}",
headers={"Authorization": PEXELS_API_KEY},
timeout=10
)
return response.json().get('videos', [])[:num_videos]
except Exception as e:
logger.error(f"Error buscando videos: {str(e)}")
return []
async def crear_video_profesional(prompt, custom_script, voz_index, musica=None):
try:
# 1. Generar gui贸n
guion = custom_script if custom_script else generar_guion_profesional(prompt)
# 2. Configurar voz
voz_seleccionada = VOICES[voz_index]['ShortName'] if VOICES else 'es-ES-ElviraNeural'
# 3. Generar audio
voz_archivo = "voz.mp3"
await edge_tts.Communicate(guion, voz_seleccionada).save(voz_archivo)
audio = AudioFileClip(voz_archivo)
# 4. Obtener videos
videos_data = buscar_videos_avanzado(prompt, guion)
if not videos_data:
raise Exception("No se encontraron videos")
# 5. Procesar videos
clips = []
for video in videos_data[:3]: # Usar m谩ximo 3 videos
video_file = next((vf for vf in video['video_files'] if vf['quality'] == 'sd'), video['video_files'][0])
with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as temp_video:
response = requests.get(video_file['link'], stream=True)
for chunk in response.iter_content(chunk_size=1024*1024):
temp_video.write(chunk)
clip = VideoFileClip(temp_video.name).subclip(0, min(10, video['duration']))
clips.append(clip)
# 6. Crear video final
video_final = concatenate_videoclips(clips)
video_final = video_final.set_audio(audio)
output_path = f"video_output_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
video_final.write_videofile(output_path, fps=24, 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)
# Interfaz optimizada
with gr.Blocks(title="Generador de Videos") as app:
with gr.Row():
with gr.Column():
prompt = gr.Textbox(label="Tema del video")
custom_script = gr.TextArea(label="Gui贸n personalizado (opcional)")
voz = gr.Dropdown(VOICE_NAMES, label="Voz", value=VOICE_NAMES[0])
btn = gr.Button("Generar Video", variant="primary")
with gr.Column():
output = gr.Video(label="Resultado", format="mp4")
btn.click(
fn=lambda p, cs, v: asyncio.run(crear_video_profesional(p, cs, VOICE_NAMES.index(v))),
inputs=[prompt, custom_script, voz],
outputs=output
)
if __name__ == "__main__":
app.launch(server_name="0.0.0.0", server_port=7860) |