Spaces:
Paused
Paused
File size: 7,297 Bytes
9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 4957d04 9d02e09 9a6b3d7 9d02e09 4957d04 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 9d02e09 9a6b3d7 |
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 |
# FILE: api/ltx_aduc_orchestrator.py
# DESCRIPTION: The main workflow orchestrator for the ADUC-SDR LTX suite.
# In this simplified architecture, it coordinates a single unified client (LtxAducPipeline)
# to execute the complete video generation pipeline from prompt to MP4.
import logging
import time
import yaml
import os
import sys
from PIL import Image
from typing import Optional, Dict, Union
# O Orquestrador importa o CLIENTE UNIFICADO que ele vai coordenar.
from api.ltx.ltx_aduc_pipeline import ltx_aduc_pipeline
# O Orquestrador importa as FERRAMENTAS de que precisa para as tarefas finais.
from tools.video_encode_tool import video_encode_tool_singleton
# Importa o Path para carregar a configuração.
from pathlib import Path
LTX_VIDEO_REPO_DIR = Path("/data/LTX-Video")
# ==============================================================================
# --- A CLASSE ORQUESTRADORA (Cérebro do Workflow) ---
# ==============================================================================
class LtxAducOrchestrator:
"""
Orquestra o fluxo de trabalho completo de geração de vídeo,
coordenando o cliente unificado LTX. É o ponto de entrada principal para a UI.
"""
def __init__(self):
"""
Inicializa o orquestrador, carregando a configuração base uma única vez.
"""
self.output_dir = "/app/output"
self.base_config = self._load_base_config()
logging.info("✅ LTX ADUC Orchestrator initialized and ready.")
def _load_base_config(self) -> Dict:
"""Carrega a configuração base do arquivo YAML, que contém os parâmetros padrão."""
try:
config_path = LTX_VIDEO_REPO_DIR / "configs" / "ltxv-13b-0.9.8-distilled-fp8.yaml"
with open(config_path, "r") as file:
return yaml.safe_load(file)
except Exception as e:
logging.error(f"Failed to load base config file. Orchestrator may not function correctly. Error: {e}")
return {}
def __call__(
self,
prompt: str,
initial_image: Optional[Image.Image] = None,
height: int = 432,
width: int = 768,
duration_in_seconds: float = 4.0,
ltx_configs: Optional[Dict] = None,
output_filename_base: str = "ltx_aduc_video"
) -> Optional[str]:
"""
Ponto de entrada principal do Orquestrador. Executa o pipeline completo de geração de vídeo.
Args:
prompt (str): O prompt de texto completo, onde cada nova linha é uma cena.
initial_image (Optional[Image.Image]): Imagem PIL para condicionar a primeira cena.
height (int): Altura do vídeo final.
width (int): Largura do vídeo final.
duration_in_seconds (float): Duração total desejada do vídeo.
ltx_configs (Optional[Dict]): Configurações avançadas da UI para sobrescrever os padrões.
output_filename_base (str): Nome base para o arquivo de vídeo de saída.
Returns:
Optional[str]: O caminho para o arquivo .mp4 gerado, ou None em caso de falha.
"""
t0 = time.time()
logging.info(f"Orchestrator starting new job for prompt: '{prompt.splitlines()[0]}...'")
try:
# =================================================================
# --- ETAPA 1: PREPARAÇÃO DOS INPUTS E CONFIGURAÇÕES ---
# =================================================================
prompt_list = [line.strip() for line in prompt.splitlines() if line.strip()]
if not prompt_list:
raise ValueError("O prompt está vazio ou não contém linhas válidas.")
initial_conditioning_items = []
if initial_image:
logging.info("Orchestrator delegating: create conditioning item.")
conditioning_params = [(0, 1.0)] # (frame_number, strength)
initial_conditioning_items = ltx_aduc_pipeline.encode_to_conditioning_items(
media_list=[initial_image],
params=conditioning_params,
resolution=(height, width)
)
common_ltx_args = self.base_config.get("first_pass", {}).copy()
common_ltx_args.update({
'negative_prompt': "blurry, low quality, bad anatomy, deformed",
'height': height,
'width': width
})
if ltx_configs:
common_ltx_args.update(ltx_configs)
# =================================================================
# --- ETAPA 2: DELEGAR GERAÇÃO DO VÍDEO LATENTE ---
# =================================================================
logging.info("Orchestrator delegating: generate latent video.")
final_latents, used_seed = ltx_aduc_pipeline.generate_latents(
prompt_list=prompt_list,
duration_in_seconds=duration_in_seconds,
common_ltx_args=common_ltx_args,
initial_conditioning_items=initial_conditioning_items
)
if final_latents is None:
raise RuntimeError("LTX client failed to generate a latent tensor.")
logging.info(f"Orchestrator received latent tensor with shape: {final_latents.shape}")
# =================================================================
# --- ETAPA 3: DELEGAR DECODIFICAÇÃO PARA PIXELS ---
# =================================================================
logging.info("Orchestrator delegating: decode latent to pixels.")
pixel_tensor = ltx_aduc_pipeline.decode_to_pixels(final_latents)
if pixel_tensor is None:
raise RuntimeError("LTX client failed to decode the latent tensor.")
logging.info(f"Orchestrator received pixel tensor with shape: {pixel_tensor.shape}")
# =================================================================
# --- ETAPA 4: TAREFA FINAL - CODIFICAR PARA MP4 ---
# =================================================================
video_filename = f"{output_filename_base}_{int(time.time())}_{used_seed}.mp4"
output_path = f"{self.output_dir}/{video_filename}"
logging.info(f"Orchestrator executing final task: saving tensor to MP4 at {output_path}")
video_encode_tool_singleton.save_video_from_tensor(
pixel_5d=pixel_tensor,
path=output_path,
fps=24
)
total_time = time.time() - t0
logging.info(f"🚀🚀🚀 Orchestrator job complete! Video saved to {output_path}. Total time: {total_time:.2f}s")
return output_path
except Exception:
logging.error("ORCHESTRATOR FAILED! A critical error occurred during the workflow.", exc_info=True)
return None
# ==============================================================================
# --- INSTÂNCIA SINGLETON DO ORQUESTRADOR ---
# ==============================================================================
ltx_aduc_orchestrator = LtxAducOrchestrator()
|