Spaces:
Runtime error
Runtime error
File size: 5,017 Bytes
b4a9e0c 2c40a5e b4a9e0c c55d1ca a3b29da b4a9e0c c55d1ca a3b29da 1a24654 b4a9e0c 1a24654 2c40a5e a3b29da 1a24654 2c40a5e a3b29da 1a24654 a3b29da 1a24654 a3b29da 1a24654 2c40a5e a3b29da 1a24654 2c40a5e 1a24654 b4a9e0c 2c40a5e c55d1ca 1a24654 a3b29da c55d1ca 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e c55d1ca b4a9e0c 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e 1a24654 2c40a5e b4a9e0c c55d1ca 2c40a5e c55d1ca b4a9e0c c55d1ca 2c40a5e b4a9e0c |
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 |
import gradio as gr
from huggingface_hub import hf_hub_download
import os
import time
import torch
import cv2
import numpy as np
# =================================================================
# 1. CONFIGURACIÓN Y DESCARGA AUTOMÁTICA DE CHECKPOINTS
# =================================================================
# Directorio local donde se guardarán los archivos
LOCAL_CHECKPOINT_DIR = "checkpoints"
os.makedirs(LOCAL_CHECKPOINT_DIR, exist_ok=True)
downloaded_paths = {}
# --- LÓGICA DE DESCARGA VERIFICADA (VERSION FINAL) ---
try:
# 1. WAV2LIP PRINCIPAL (Fuente más estable para el modelo)
WAV2LIP_REPO = "Nekochu/Wav2Lip"
WAV2LIP_FILE = "wav2lip_gan.pth"
print(f"-> Descargando {WAV2LIP_FILE} desde {WAV2LIP_REPO}...")
path_wav2lip = hf_hub_download(repo_id=WAV2LIP_REPO, filename=WAV2LIP_FILE, local_dir=LOCAL_CHECKPOINT_DIR, local_dir_use_symlinks=False)
downloaded_paths[WAV2LIP_FILE] = path_wav2lip
print(f"✅ Descarga de {WAV2LIP_FILE} completada.")
# 2. DETECTOR FACIAL SFD (Fuente final verificada para el detector)
SFD_REPO = "face-alignment/s3fd"
SFD_FILE = "s3fd.pth"
print(f"-> Descargando {SFD_FILE} desde {SFD_REPO}...")
path_sfd = hf_hub_download(repo_id=SFD_REPO, filename=SFD_FILE, local_dir=LOCAL_CHECKPOINT_DIR, local_dir_use_symlinks=False)
downloaded_paths[SFD_FILE] = path_sfd
print(f"✅ Descarga de {SFD_FILE} completada.")
print("✅ Descarga de Checkpoints completada. Modelos listos.")
except Exception as e:
print(f"❌ ERROR CRÍTICO EN LA DESCARGA: {e}")
exit(1)
# Rutas de los modelos descargados (Globales para la inferencia)
WAV2LIP_PATH = downloaded_paths[WAV2LIP_FILE]
SFD_PATH = downloaded_paths[SFD_FILE]
# =================================================================
# 2. MODELO Y FUNCIONES HELPER (¡REQUIERE CÓDIGO EXTERNO!)
# =================================================================
# ---> NOTA IMPORTANTE: FALTAN FUNCIONES HELPER AQUÍ <---
# Debes pegar aquí:
# 1. La clase 'Wav2Lip' (definición del modelo).
# 2. Las funciones de utilidad para pre-procesamiento de video/audio (ej. get_smoothened_fpc, face_detect, etc.).
# Estos archivos se encuentran en el repositorio original de Wav2Lip (ver Paso 3).
# --- PLACEHOLDERS DE MODELO ---
def load_wav2lip_model(path):
"""Placeholder para cargar el modelo PyTorch."""
# Aquí iría la lógica real de carga del modelo Wav2Lip.
print(f"Cargando modelo Wav2Lip desde: {path}")
# model = Wav2Lip().to(device)
# model.load_state_dict(torch.load(path)['state_dict'])
# return model
return "Wav2Lip_Instance"
def execute_inference_pipeline(model, sfd_path, image_path, audio_path, output_path):
"""
Placeholder para la ejecución completa del pipeline de Wav2Lip.
"""
# Aquí se ejecuta la magia de Wav2Lip, usando las rutas de entrada.
print("Inferencia en proceso...")
# Simulación de la creación del archivo de salida
time.sleep(10) # Simulación del tiempo de renderizado en CPU
output_dir = os.path.dirname(output_path)
os.makedirs(output_dir, exist_ok=True)
# Crea un archivo de salida dummy para que Gradio no falle (EN PRODUCCIÓN DEBE SER UN MP4 REAL)
with open(output_path, 'w') as f:
f.write("Dummy video content")
return output_path
# Carga global de modelos
WAV2LIP_MODEL = load_wav2lip_model(WAV2LIP_PATH)
# =================================================================
# 3. FUNCIÓN PRINCIPAL DEL SERVIDOR (Lógica expuesta por la API)
# =================================================================
def generar_avatar_wav2lip(imagen_fuente, archivo_audio):
"""
Función que recibe la imagen y el audio,
ejecuta el modelo Wav2Lip y devuelve la ruta al video generado.
"""
# Ruta temporal y única para el archivo de salida
OUTPUT_VIDEO_PATH = os.path.join("results", f"output_{time.time()}.mp4")
print("--- INICIANDO PROCESO WAV2LIP ---")
print(f"Ruta de Salida: {OUTPUT_VIDEO_PATH}")
# Llama a la función de inferencia.
final_video_path = execute_inference_pipeline(
model=WAV2LIP_MODEL,
sfd_path=SFD_PATH,
image_path=imagen_fuente,
audio_path=archivo_audio,
output_path=OUTPUT_VIDEO_PATH
)
print("--- PROCESO FINALIZADO ---")
return final_video_path
# =================================================================
# 4. CONFIGURACIÓN DE LA INTERFAZ (UI y API)
# =================================================================
gr.Interface(
fn=generar_avatar_wav2lip,
inputs=[
gr.Image(type="filepath", label="Imagen del Avatar (JPG/PNG)"),
gr.Audio(type="filepath", label="Archivo de Audio (MP3/WAV)")
],
outputs=gr.Video(label="Video Generado"),
title="Wav2Lip en Space CPU (Con Descarga Automática)",
description="Modelo Wav2Lip optimizado para CPU. Recuerda que la inferencia en CPU será lenta."
).launch() |