Update deformes4D_engine.py
Browse files- deformes4D_engine.py +51 -17
deformes4D_engine.py
CHANGED
|
@@ -100,23 +100,23 @@ class Deformes4DEngine:
|
|
| 100 |
self.save_video_from_tensor(pixel_tensor, silent_video_path, fps=24)
|
| 101 |
del pixel_tensor; gc.collect()
|
| 102 |
|
| 103 |
-
try:
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
except (subprocess.CalledProcessError, ValueError, FileNotFoundError):
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
video_with_audio_path = audio_specialist_singleton.generate_audio_for_video(
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
if os.path.exists(silent_video_path):
|
| 118 |
-
|
| 119 |
-
return
|
| 120 |
|
| 121 |
def _generate_latent_tensor_internal(self, conditioning_items, ltx_params, target_resolution, total_frames_to_generate):
|
| 122 |
final_ltx_params = {
|
|
@@ -227,6 +227,8 @@ class Deformes4DEngine:
|
|
| 227 |
current_ltx_params = {**base_ltx_params, "handler_strength": handler_strength, "motion_prompt": motion_prompt}
|
| 228 |
total_frames_to_generate = self._quantize_to_multiple(int(seconds_per_fragment * 24), 8) + 1
|
| 229 |
|
|
|
|
|
|
|
| 230 |
# --- NOVA LÓGICA: Preparação das instruções de condicionamento ---
|
| 231 |
if is_first_fragment:
|
| 232 |
img_start = self._preprocess_image_for_latent_conversion(Image.open(start_keyframe_path).convert("RGB"), target_resolution_tuple)
|
|
@@ -246,6 +248,38 @@ class Deformes4DEngine:
|
|
| 246 |
conditioning_items.append(LatentConditioningItem(destination_latent, total_frames_to_generate - 1, destination_convergence_strength))
|
| 247 |
|
| 248 |
new_full_latents = self._generate_latent_tensor_internal(conditioning_items, current_ltx_params, target_resolution_tuple, total_frames_to_generate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 249 |
|
| 250 |
# --- NOVA LÓGICA: Preparação movida para o final do loop ---
|
| 251 |
is_last_fragment = (i == num_transitions_to_generate - 1)
|
|
|
|
| 100 |
self.save_video_from_tensor(pixel_tensor, silent_video_path, fps=24)
|
| 101 |
del pixel_tensor; gc.collect()
|
| 102 |
|
| 103 |
+
#try:
|
| 104 |
+
# result = subprocess.run(
|
| 105 |
+
# ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", silent_video_path],
|
| 106 |
+
# capture_output=True, text=True, check=True)
|
| 107 |
+
# frag_duration = float(result.stdout.strip())
|
| 108 |
+
#except (subprocess.CalledProcessError, ValueError, FileNotFoundError):
|
| 109 |
+
# logger.warning(f"ffprobe falhou em {os.path.basename(silent_video_path)}. Calculando duração manualmente.")
|
| 110 |
+
# num_pixel_frames = latent_tensor.shape[2] * 8
|
| 111 |
+
# frag_duration = num_pixel_frames / 24.0
|
| 112 |
+
#
|
| 113 |
+
#video_with_audio_path = audio_specialist_singleton.generate_audio_for_video(
|
| 114 |
+
# video_path=silent_video_path, prompt=audio_prompt,
|
| 115 |
+
# duration_seconds=frag_duration)
|
| 116 |
+
#
|
| 117 |
+
#if os.path.exists(silent_video_path):
|
| 118 |
+
# os.remove(silent_video_path)
|
| 119 |
+
return silent_video_path
|
| 120 |
|
| 121 |
def _generate_latent_tensor_internal(self, conditioning_items, ltx_params, target_resolution, total_frames_to_generate):
|
| 122 |
final_ltx_params = {
|
|
|
|
| 227 |
current_ltx_params = {**base_ltx_params, "handler_strength": handler_strength, "motion_prompt": motion_prompt}
|
| 228 |
total_frames_to_generate = self._quantize_to_multiple(int(seconds_per_fragment * 24), 8) + 1
|
| 229 |
|
| 230 |
+
|
| 231 |
+
|
| 232 |
# --- NOVA LÓGICA: Preparação das instruções de condicionamento ---
|
| 233 |
if is_first_fragment:
|
| 234 |
img_start = self._preprocess_image_for_latent_conversion(Image.open(start_keyframe_path).convert("RGB"), target_resolution_tuple)
|
|
|
|
| 248 |
conditioning_items.append(LatentConditioningItem(destination_latent, total_frames_to_generate - 1, destination_convergence_strength))
|
| 249 |
|
| 250 |
new_full_latents = self._generate_latent_tensor_internal(conditioning_items, current_ltx_params, target_resolution_tuple, total_frames_to_generate)
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
# --- [INÍCIO] Bloco de Verificação de Frames por Chunk ---
|
| 254 |
+
logger.info("--- [VERIFICAÇÃO DE CHUNKS INDIVIDUAIS] ---")
|
| 255 |
+
total_chunks_verificados = new_full_latents.shape[2]
|
| 256 |
+
for chunk_idx in range(total_chunks_verificados):
|
| 257 |
+
try:
|
| 258 |
+
# Isola o chunk atual
|
| 259 |
+
single_chunk_latent = new_full_latents[:, :, chunk_idx:chunk_idx+1, :, :]
|
| 260 |
+
|
| 261 |
+
# Gera um nome de arquivo temporário para o vídeo do chunk
|
| 262 |
+
temp_video_base_name = f"debug_chunk_{chunk_idx}"
|
| 263 |
+
|
| 264 |
+
# Converte o latente do chunk em um vídeo MP4
|
| 265 |
+
temp_video_path = self._generate_video_from_latents(single_chunk_latent, temp_video_base_name)
|
| 266 |
+
|
| 267 |
+
# Conta os frames no vídeo gerado
|
| 268 |
+
if os.path.exists(temp_video_path):
|
| 269 |
+
with imageio.get_reader(temp_video_path) as reader:
|
| 270 |
+
frame_count = reader.count_frames()
|
| 271 |
+
logger.info(f" - VERIFICADO: Chunk {chunk_idx} gerou um vídeo com {frame_count} frames.")
|
| 272 |
+
# Apaga o vídeo de debug
|
| 273 |
+
os.remove(temp_video_path)
|
| 274 |
+
else:
|
| 275 |
+
logger.warning(f" - FALHA: Não foi possível gerar o vídeo para o Chunk {chunk_idx}.")
|
| 276 |
+
|
| 277 |
+
except Exception as e:
|
| 278 |
+
logger.error(f" - ERRO ao verificar Chunk {chunk_idx}: {e}")
|
| 279 |
+
logger.info("--- [FIM DA VERIFICAÇÃO] ---")
|
| 280 |
+
# --- [FIM] Bloco de Verificação ---
|
| 281 |
+
|
| 282 |
+
|
| 283 |
|
| 284 |
# --- NOVA LÓGICA: Preparação movida para o final do loop ---
|
| 285 |
is_last_fragment = (i == num_transitions_to_generate - 1)
|