Carlexxx commited on
Commit
ffa9bff
·
verified ·
1 Parent(s): 3649689

Delete app-old.py

Browse files
Files changed (1) hide show
  1. app-old.py +0 -215
app-old.py DELETED
@@ -1,215 +0,0 @@
1
- # --- app.py (O Painel de Controle do Maestro - Produção em Lote com Diário de Bordo) ---
2
- # By Carlex & Gemini
3
-
4
- # --- Ato 1: A Convocação da Orquestra (Importações) ---
5
- import gradio as gr
6
- import torch
7
- import spaces
8
- import os
9
- import yaml
10
- from PIL import Image
11
- import shutil
12
- import gc
13
- import traceback
14
- import subprocess
15
- import math
16
- import google.generativeai as genai
17
- import numpy as np
18
- import imageio
19
- import tempfile
20
- from pathlib import Path
21
- from huggingface_hub import hf_hub_download
22
- import json
23
- from facexlib.utils.face_restoration_helper import FaceRestoreHelper
24
- import huggingface_hub
25
- import spaces
26
- import argparse
27
-
28
- import spaces
29
- import argparse
30
-
31
-
32
- import cv2
33
-
34
- from facexlib.utils.face_restoration_helper import FaceRestoreHelper
35
- import huggingface_hub
36
-
37
-
38
-
39
- from dreamo.dreamo_pipeline import DreamOPipeline
40
- from dreamo.utils import img2tensor, resize_numpy_image_area, tensor2img, resize_numpy_image_long
41
- from tools import BEN2
42
-
43
-
44
- # --- Músicos Originais (Sua implementação) ---
45
- from inference import create_ltx_video_pipeline, load_image_to_tensor_with_resize_and_crop, seed_everething, calculate_padding
46
- from ltx_video.pipelines.pipeline_ltx_video import ConditioningItem
47
-
48
- # --- Ato 2: A Preparação do Palco (Configurações) ---
49
- config_file_path = "configs/ltxv-13b-0.9.8-distilled.yaml"
50
- with open(config_file_path, "r") as file:
51
- PIPELINE_CONFIG_YAML = yaml.safe_load(file)
52
-
53
- # --- Constantes Globais ---
54
- LTX_REPO = "Lightricks/LTX-Video"
55
- models_dir = "downloaded_models_gradio_cpu_init"
56
- Path(models_dir).mkdir(parents=True, exist_ok=True)
57
- WORKSPACE_DIR = "aduc_workspace"
58
- GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
59
-
60
- # --- Carregamento de Modelos LTX na CPU ---
61
- print("Baixando e criando pipelines LTX na CPU...")
62
- distilled_model_actual_path = hf_hub_download(repo_id=LTX_REPO, filename=PIPELINE_CONFIG_YAML["checkpoint_path"], local_dir=models_dir, local_dir_use_symlinks=False)
63
- pipeline_instance = create_ltx_video_pipeline(ckpt_path=distilled_model_actual_path, precision=PIPELINE_CONFIG_YAML["precision"], text_encoder_model_name_or_path=PIPELINE_CONFIG_YAML["text_encoder_model_name_or_path"], sampler=PIPELINE_CONFIG_YAML["sampler"], device="cpu")
64
- print("Modelos LTX prontos.")
65
-
66
-
67
- # --- Ato 3: As Partituras dos Músicos (Funções) ---
68
-
69
- def get_storyboard_from_director_v2(num_fragments: int, prompt: str, initial_image_path: str, progress=gr.Progress()):
70
- progress(0.5, desc="[Diretor Gemini] Criando o storyboard completo...")
71
- if not initial_image_path: raise gr.Error("Por favor, forneça uma imagem de referência inicial.")
72
- if not GEMINI_API_KEY: raise gr.Error("Chave da API Gemini (GEMINI_API_KEY) não configurada!")
73
- genai.configure(api_key=GEMINI_API_KEY)
74
- try:
75
- with open("prompts/director_storyboard_v2.txt", "r", encoding="utf-8") as f: template = f.read()
76
- except FileNotFoundError: raise gr.Error("'prompts/director_storyboard_v2.txt' não encontrado!")
77
- director_prompt = template.format(user_prompt=prompt, num_fragments=int(num_fragments))
78
- model = genai.GenerativeModel('gemini-2.0-flash')
79
- img = Image.open(initial_image_path)
80
- response = model.generate_content([director_prompt, img])
81
- try:
82
- cleaned_response = response.text.strip().replace("```json", "").replace("```", "")
83
- storyboard_data = json.loads(cleaned_response)
84
- storyboard_list = storyboard_data.get("storyboard", [])
85
- if not storyboard_list: raise gr.Error("A IA não retornou um storyboard válido.")
86
- return storyboard_list
87
- except (json.JSONDecodeError, KeyError, TypeError) as e:
88
- raise gr.Error(f"O Diretor retornou uma resposta inesperada. Erro: {e}\nResposta Bruta: {response.text}")
89
-
90
- def run_ltx_animation(current_fragment_index, motion_prompt, input_frame_path, height, width, fps, seed, cfg, progress=gr.Progress()):
91
- progress(0, desc=f"[Animador LTX] Aquecendo para a Cena {current_fragment_index}...")
92
- target_device = "cuda"; output_path = os.path.join(WORKSPACE_DIR, f"fragment_{current_fragment_index}.mp4")
93
- try:
94
- pipeline_instance.to(target_device)
95
- duration_fragment, target_frames_ideal = 3.0, 3.0 * fps
96
- n_val = round((float(round(target_frames_ideal)) - 1.0) / 8.0); actual_num_frames = max(9, min(int(n_val * 8 + 1), 257))
97
- num_frames_padded = ((actual_num_frames - 2) // 8 + 1) * 8 + 1
98
- padded_h, padded_w = ((int(height) - 1) // 32 + 1) * 32, ((int(width) - 1) // 32 + 1) * 32
99
- padding_vals = calculate_padding(int(height), int(width), padded_h, padded_w)
100
- timesteps = PIPELINE_CONFIG_YAML.get("first_pass", {}).get("timesteps")
101
- kwargs = {"prompt": motion_prompt, "negative_prompt": "blurry, distorted", "height": padded_h, "width": padded_w, "num_frames": num_frames_padded, "frame_rate": int(fps), "generator": torch.Generator(device=target_device).manual_seed(int(seed) + current_fragment_index), "output_type": "pt", "guidance_scale": float(cfg), "timesteps": timesteps, "vae_per_channel_normalize": True, "decode_timestep": PIPELINE_CONFIG_YAML["decode_timestep"], "decode_noise_scale": PIPELINE_CONFIG_YAML["decode_noise_scale"], "stochastic_sampling": PIPELINE_CONFIG_YAML["stochastic_sampling"], "image_cond_noise_scale": 0.15, "is_video": True, "mixed_precision": (PIPELINE_CONFIG_YAML["precision"] == "mixed_precision"), "offload_to_cpu": False, "enhance_prompt": False}
102
- media_tensor = load_image_to_tensor_with_resize_and_crop(input_frame_path, int(height), int(width)); media_tensor = torch.nn.functional.pad(media_tensor, padding_vals); kwargs["conditioning_items"] = [ConditioningItem(media_tensor.to(target_device), 0, 1.0)]
103
- result_tensor = pipeline_instance(**kwargs).images
104
- pad_l, pad_r, pad_t, pad_b = padding_vals; slice_h, slice_w = (-pad_b if pad_b > 0 else None), (-pad_r if pad_r > 0 else None)
105
- cropped_tensor = result_tensor[:, :, :actual_num_frames, pad_t:slice_h, pad_l:slice_w]; video_np = (cropped_tensor[0].permute(1, 2, 3, 0).cpu().float().numpy() * 255).astype(np.uint8)
106
- with imageio.get_writer(output_path, fps=int(fps), codec='libx264', quality=8) as writer:
107
- for i, frame in enumerate(video_np): progress(i / len(video_np), desc=f"Renderizando frame {i+1}/{len(video_np)}..."); writer.append_data(frame)
108
- return output_path
109
- finally:
110
- pipeline_instance.to("cpu"); gc.collect(); torch.cuda.empty_cache()
111
-
112
- def concatenate_masterpiece(fragment_paths: list, progress=gr.Progress()):
113
- progress(0.5, desc="Montando a obra-prima final..."); list_file_path, final_output_path = os.path.join(WORKSPACE_DIR, "concat_list.txt"), os.path.join(WORKSPACE_DIR, "obra_prima_final.mp4")
114
- with open(list_file_path, "w") as f:
115
- for path in fragment_paths: f.write(f"file '{os.path.abspath(path)}'\n")
116
- command = f"ffmpeg -y -f concat -safe 0 -i {list_file_path} -c copy {final_output_path}"
117
- try:
118
- subprocess.run(command, shell=True, check=True, capture_output=True, text=True); return final_output_path
119
- except subprocess.CalledProcessError as e:
120
- raise gr.Error(f"FFmpeg falhou ao unir os vídeos: {e.stderr}")
121
-
122
- def run_full_production(storyboard, ref_img_path, height, width, fps, seed, cfg):
123
- if not storyboard: raise gr.Error("Nenhum roteiro para produzir.")
124
- if not ref_img_path: raise gr.Error("Nenhuma imagem de referência definida.")
125
- video_fragments, log_history = [], ""
126
- for i, motion_prompt in enumerate(storyboard):
127
- log_message = f"Iniciando produção da Cena {i+1}/{len(storyboard)}..."
128
- log_history += log_message + "\n"
129
- yield {production_log_output: gr.update(value=log_history)}
130
- fragment_path = run_ltx_animation(i + 1, motion_prompt, ref_img_path, height, width, fps, seed, cfg, gr.Progress())
131
- video_fragments.append(fragment_path)
132
- log_message = f"Cena {i+1} concluída e salva em {os.path.basename(fragment_path)}."
133
- log_history += log_message + "\n"
134
- yield {production_log_output: gr.update(value=log_history), fragment_gallery_output: gr.update(value=video_fragments), fragment_list_state: video_fragments, final_fragments_display: gr.update(value=video_fragments)}
135
- log_history += "\nProdução de todas as cenas concluída!"
136
- yield {production_log_output: gr.update(value=log_history)}
137
-
138
- # --- Ato 4: A Apresentação (UI do Gradio) ---
139
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
140
- gr.Markdown("# LTX Video - Storyboard em Vídeo (ADUC-SDR)\n*By Carlex & Gemini*")
141
-
142
- storyboard_state = gr.State([])
143
- reference_image_state = gr.State("")
144
- fragment_list_state = gr.State([])
145
-
146
- if os.path.exists(WORKSPACE_DIR): shutil.rmtree(WORKSPACE_DIR)
147
- os.makedirs(WORKSPACE_DIR)
148
-
149
- with gr.Tabs():
150
- with gr.TabItem("ETAPA 1: O DIRETOR (Roteiro Visual)"):
151
- with gr.Row():
152
- with gr.Column():
153
- num_fragments_input = gr.Slider(2, 10, 4, step=1, label="Número de Cenas (Fragmentos)")
154
- prompt_input = gr.Textbox(label="Ideia Geral (Prompt)")
155
- image_input = gr.Image(type="filepath", label="Imagem de Referência")
156
- director_button = gr.Button("▶️ Gerar Roteiro Visual (Gemini)", variant="primary")
157
- with gr.Column():
158
- storyboard_output = gr.JSON(label="Roteiro Visual Gerado (Storyboard)")
159
-
160
- with gr.TabItem("ETAPA 2: A PRODUÇÃO (Gerar Cenas em Vídeo)"):
161
- with gr.Row():
162
- with gr.Column():
163
- storyboard_to_render = gr.JSON(label="Roteiro a ser Produzido")
164
- animator_button = gr.Button("▶️ Produzir TODAS as Cenas (LTX)", variant="primary")
165
- production_log_output = gr.Textbox(label="Diário de Bordo da Produção", lines=5, interactive=False, placeholder="Aguardando início da produção...")
166
- with gr.Column():
167
- fragment_gallery_output = gr.Gallery(label="Cenas Produzidas (Fragmentos de Vídeo)", object_fit="contain", height="auto")
168
- with gr.Row():
169
- height_slider = gr.Slider(256, 1024, 512, step=32, label="Altura")
170
- width_slider = gr.Slider(256, 1024, 512, step=32, label="Largura")
171
- with gr.Row():
172
- fps_slider = gr.Slider(8, 24, 15, step=1, label="FPS")
173
- seed_number = gr.Number(42, label="Seed")
174
- cfg_slider = gr.Slider(1.0, 10.0, 2.5, step=0.1, label="CFG")
175
-
176
- with gr.TabItem("ETAPA 3: PÓS-PRODUÇÃO"):
177
- with gr.Row():
178
- with gr.Column():
179
- final_fragments_display = gr.JSON(label="Vídeos a Concatenar")
180
- editor_button = gr.Button("▶️ Concatenar Tudo (FFmpeg)", variant="primary")
181
- with gr.Column():
182
- final_video_output = gr.Video(label="A Obra-Prima Final")
183
-
184
- # --- Ato 5: A Regência (Lógica de Conexão dos Botões) ---
185
-
186
- def director_success(img_path, storyboard_json):
187
- if not img_path: raise gr.Error("A imagem de referência é necessária.")
188
- storyboard_list = storyboard_json if isinstance(storyboard_json, list) else storyboard_json.get("storyboard", [])
189
- if not storyboard_list: raise gr.Error("O storyboard está vazio.")
190
- return storyboard_list, img_path, gr.update(value=storyboard_json)
191
-
192
- director_button.click(
193
- fn=get_storyboard_from_director_v2,
194
- inputs=[num_fragments_input, prompt_input, image_input],
195
- outputs=[storyboard_output]
196
- ).success(
197
- fn=director_success,
198
- inputs=[image_input, storyboard_output],
199
- outputs=[storyboard_state, reference_image_state, storyboard_to_render]
200
- )
201
-
202
- animator_button.click(
203
- fn=run_full_production,
204
- inputs=[storyboard_state, reference_image_state, height_slider, width_slider, fps_slider, seed_number, cfg_slider],
205
- outputs=[production_log_output, fragment_gallery_output, fragment_list_state, final_fragments_display]
206
- )
207
-
208
- editor_button.click(
209
- fn=concatenate_masterpiece,
210
- inputs=[fragment_list_state],
211
- outputs=[final_video_output]
212
- )
213
-
214
- if __name__ == "__main__":
215
- demo.queue().launch(server_name="0.0.0.0", share=True)