File size: 10,534 Bytes
db47818 |
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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# app_refactored_with_postprod.py
import gradio as gr
import os
import sys
from pathlib import Path
import traceback
# --- Import dos Serviços de Backend ---
# Serviço LTX para geração de vídeo base e refinamento de textura
try:
from api.ltx_server_refactored import video_generation_service
except ImportError:
print("ERRO FATAL: Não foi possível importar 'video_generation_service' de 'api.ltx_server_refactored'.")
print("Verifique se o arquivo existe e se o ambiente está configurado corretamente.")
sys.exit(1)
# Serviço SeedVR para upscaling de alta qualidade
try:
from api.seedvr_server import SeedVRServer
except ImportError:
print("AVISO: Não foi possível importar SeedVRServer. A aba de upscaling SeedVR será desativada.")
SeedVRServer = None # Define como None para tratamento gracioso de erro
# Inicializa o servidor SeedVR uma vez, se disponível
if SeedVRServer:
print("Inicializando o servidor de inferência SeedVR...")
seedvr_inference_server = SeedVRServer()
else:
seedvr_inference_server = None
# --- ESTADO DA SESSÃO ---
# Mantém os caminhos dos arquivos entre os cliques dos botões
def create_initial_state():
return {
"low_res_video": None,
"low_res_latents": None,
"refined_video": None,
"refined_latents": None,
"used_seed": None
}
# --- FUNÇÕES WRAPPER PARA A UI ---
def run_generate_low(prompt, neg_prompt, start_img, height, width, duration, cfg, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
"""
Executa a primeira etapa: geração de um vídeo base em baixa resolução.
"""
print("UI: Chamando generate_low")
try:
# 1. Preparar conditioning_items (se uma imagem de início for fornecida)
conditioning_items = []
if start_img:
# A função `prepare_condition_items` precisa de uma estimativa do número de frames
num_frames_estimate = int(duration * 24)
items_list = [[start_img, 0, 1.0]] # Imagem de início, no frame 0, com peso 1.0
conditioning_items = video_generation_service.prepare_condition_items(items_list, height, width, num_frames_estimate)
# Determina a seed a ser usada
used_seed = None if randomize_seed else seed
# 2. Chamar a função de geração de baixa resolução do backend
video_path, tensor_path, final_seed = video_generation_service.generate_low(
prompt=prompt, negative_prompt=neg_prompt,
height=height, width=width, duration=duration,
guidance_scale=cfg, seed=used_seed,
conditioning_items=conditioning_items
)
# 3. Atualizar o estado da aplicação com os caminhos dos arquivos resultantes
new_state = {
"low_res_video": video_path,
"low_res_latents": tensor_path,
"refined_video": None, # Limpa resultados de execuções anteriores
"refined_latents": None,
"used_seed": final_seed
}
# 4. Retorna os resultados para a UI
# - O caminho do vídeo para o componente de vídeo
# - O novo estado para o componente gr.State
# - Um update para tornar o grupo de pós-produção visível
return video_path, new_state, gr.update(visible=True)
except Exception as e:
error_message = f"❌ Ocorreu um erro na Geração Base:\n{e}"
print(f"{error_message}\nDetalhes: {traceback.format_exc()}")
raise gr.Error(error_message)
def run_seedvr_upscaling(state, seed, resolution, batch_size, fps, progress=gr.Progress(track_tqdm=True)):
"""
Função de callback que executa o processo de upscaling com SeedVR.
"""
if not state or not state.get("low_res_video"):
raise gr.Error("Erro: Gere um vídeo base primeiro na Etapa 1.")
if not seedvr_inference_server:
raise gr.Error("Erro: O servidor SeedVR não está disponível. Verifique a instalação e os logs.")
video_path = state["low_res_video"]
progress(0, desc="Iniciando SeedVR Upscaling...")
print(f"▶️ Iniciando processo de upscaling SeedVR para o vídeo: {video_path}")
try:
# Wrapper para a barra de progresso do Gradio
def progress_wrapper(p, desc=""):
progress(p, desc=desc)
print(f"⌛ Progresso SeedVR: {p*100:.1f}% - {desc}")
# Chama o método de inferência do servidor SeedVR
output_filepath = seedvr_inference_server.run_inference(
file_path=video_path,
seed=seed,
resolution=resolution,
batch_size=batch_size,
fps=fps,
progress=progress_wrapper
)
final_message = f"✅ Processo SeedVR concluído!\nVídeo salvo em: {output_filepath}"
print(final_message)
# Retorna o vídeo e a mensagem de sucesso para a UI
return gr.update(value=output_filepath, interactive=True), gr.update(value=final_message, interactive=False)
except Exception as e:
error_message = f"❌ Ocorreu um erro grave durante o upscaling com SeedVR:\n{e}"
print(f"{error_message}\nDetalhes: {traceback.format_exc()}")
# Retorna None para o vídeo e a mensagem de erro para o status box
return None, gr.update(value=error_message, interactive=False)
# --- DEFINIÇÃO DA INTERFACE GRADIO ---
with gr.Blocks(css="#col-container { margin: 0 auto; max-width: 900px; }", theme=gr.themes.Monochrome()) as demo:
gr.Markdown("# LTX Video - Geração e Pós-Produção por Etapas")
# Componente invisível para armazenar o estado da aplicação (caminhos de arquivos, etc.)
app_state = gr.State(value=create_initial_state())
# --- ETAPA 1: Geração Base ---
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Etapa 1: Configurações de Geração")
prompt_input = gr.Textbox(label="Prompt", value="A majestic dragon flying over a medieval castle", lines=3)
neg_prompt_input = gr.Textbox(label="Negative Prompt", value="worst quality, blurry, low quality, jittery", lines=2)
start_image = gr.Image(label="Imagem de Início (Opcional)", type="filepath", sources=["upload", "clipboard"])
with gr.Accordion("Parâmetros Avançados", open=False):
height_input = gr.Slider(label="Height", value=512, step=32, minimum=256, maximum=1024)
width_input = gr.Slider(label="Width", value=704, step=32, minimum=256, maximum=1024)
duration_input = gr.Slider(label="Duração (s)", value=4, step=1, minimum=1, maximum=10)
cfg_input = gr.Slider(label="Guidance Scale (CFG)", value=3.0, step=0.1, minimum=1.0, maximum=10.0)
seed_input = gr.Number(label="Seed", value=42, precision=0)
randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
generate_low_btn = gr.Button("1. Gerar Vídeo Base (Low-Res)", variant="primary")
with gr.Column(scale=1):
gr.Markdown("### Vídeo Base Gerado")
low_res_video_output = gr.Video(label="O resultado da Etapa 1 aparecerá aqui", interactive=False)
# --- ETAPA 2: Pós-Produção (no rodapé, em abas) ---
with gr.Group(visible=False) as post_prod_group:
gr.Markdown("<hr style='margin-top: 20px; margin-bottom: 20px;'>")
gr.Markdown("## Etapa 2: Pós-Produção")
gr.Markdown("Use o vídeo gerado acima como entrada para as ferramentas abaixo.")
with gr.Tabs():
with gr.TabItem("🚀 Upscaler Textura (LTX)"):
gr.Markdown("*(Funcionalidade a ser implementada no futuro)*")
# Aqui iriam os componentes para o refinamento LTX
# refine_ltx_btn = gr.Button("Aplicar Refinamento de Textura LTX")
# refined_ltx_video_output = gr.Video(label="Vídeo com Textura Refinada")
with gr.TabItem("✨ Upscaler SeedVR"):
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### Parâmetros do SeedVR")
seedvr_seed = gr.Slider(minimum=0, maximum=999999, value=42, step=1, label="Seed")
seedvr_resolution = gr.Slider(minimum=720, maximum=1440, value=1072, step=8, label="Resolução Vertical (Altura)")
seedvr_batch_size = gr.Slider(minimum=1, maximum=16, value=4, step=1, label="Batch Size por GPU")
seedvr_fps_output = gr.Number(label="FPS de Saída (0 = original)", value=0)
run_seedvr_button = gr.Button("Iniciar Upscaling SeedVR", variant="primary", interactive=(seedvr_inference_server is not None))
if not seedvr_inference_server:
gr.Markdown("<p style='color: red;'>Serviço SeedVR não disponível.</p>")
with gr.Column(scale=1):
gr.Markdown("### Resultado do Upscaling")
seedvr_video_output = gr.Video(label="Vídeo com Upscale SeedVR", interactive=False)
seedvr_status_box = gr.Textbox(label="Status do Processamento", value="Aguardando...", lines=3, interactive=False)
with gr.TabItem("🔊 Áudio (MM-Audio)"):
gr.Markdown("*(Funcionalidade futura para adicionar som aos vídeos)*")
# Componentes para a geração de áudio viriam aqui
# --- LÓGICA DE EVENTOS DA UI ---
# Conecta o botão da Etapa 1 à sua função de backend
generate_low_btn.click(
fn=run_generate_low,
inputs=[prompt_input, neg_prompt_input, start_image, height_input, width_input, duration_input, cfg_input, seed_input, randomize_seed],
outputs=[low_res_video_output, app_state, post_prod_group]
)
# Conecta o botão da Aba SeedVR à sua função de backend
run_seedvr_button.click(
fn=run_seedvr_upscaling,
inputs=[
app_state,
seedvr_seed,
seedvr_resolution,
seedvr_batch_size,
seedvr_fps_output
],
outputs=[
seedvr_video_output,
seedvr_status_box
]
)
if __name__ == "__main__":
# Inicia a aplicação Gradio
demo.queue().launch(
server_name="0.0.0.0",
debug=True,
show_error=True
) |