import gradio as gr from gradio_client import Client, handle_file def procesar_movimiento(imagen_input, video_input): if not imagen_input or not video_input: return None, "Error: Por favor, asegúrate de cargar tanto la foto como el video." # Lista de servidores públicos de LivePortrait (motores alternativos) motores = [ "KwaiVGI/LivePortrait", "innoai/LivePortrait", "appl044/LivePortrait" ] detalles_errores = [] # Probar cada motor uno por uno si el anterior está caído o pausado for motor in motores: try: client = Client(motor) resultado = client.predict( img_input=handle_file(imagen_input), driving_video=handle_file(video_input), api_name="/predict" ) if resultado: return resultado, f"¡Éxito total usando el motor: {motor}!" except Exception as e: # Si falla (por estar PAUSED o desconectado), guardamos el error y probamos el siguiente detalles_errores.append(f"[{motor} no disponible]") continue # Si llega aquí, es porque lamentablemente todos estaban dormidos a la vez error_msg = " Todos los motores gratuitos están pausados en Hugging Face en este momento. " error_msg += "Detalles: " + " || ".join(detalles_errores) return None, error_msg # --- INTERFAZ GRÁFICA --- with gr.Blocks() as demo: gr.Markdown("# 🎬 Mi Clonador AI Móvil (Multimotor)") with gr.Tabs(): with gr.TabItem("Cargar Archivos"): input_img = gr.Image(label="Foto estática (Rostro)", type="filepath") input_vid = gr.Video(label="Video guía de movimiento") btn_generar = gr.Button("🪄 Generar Video", variant="primary") with gr.TabItem("Resultado"): output_vid = gr.Video(label="Tu video listo") output_info = gr.Textbox(label="Estado del sistema", interactive=False) btn_generar.click( fn=procesar_movimiento, inputs=[input_img, input_vid], outputs=[output_vid, output_info] ) demo.launch()