peteriyo's picture
Update app.py
1a24654 verified
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()