Carlos s commited on
Commit
1d88c5c
·
verified ·
1 Parent(s): fe4edb6

Update api/ltx_server.py

Browse files
Files changed (1) hide show
  1. api/ltx_server.py +28 -35
api/ltx_server.py CHANGED
@@ -437,46 +437,39 @@ class VideoService:
437
 
438
 
439
 
440
- def _concat_crossfade_videos_por_frames(selp, mp4_list, out_path, crossfade_frames=8):
441
  """
442
- Concatena múltiplos vídeos com crossfade visual em número de frames.
443
- Funciona mesmo com mais de 2 vídeos.
 
 
 
444
  """
445
- if len(mp4_list) < 2:
446
- raise ValueError("É necessário ao menos dois vídeos.")
447
-
448
- filter_parts = []
449
- concat_sequence = []
450
 
451
- # Ajuste inicial de PTS
452
- for i, path in enumerate(mp4_list):
453
- filter_parts.append(f"[{i}:v]setpts=PTS-STARTPTS[v{i}]")
454
-
455
- # Cria crossfades entre pares consecutivos
456
- for i in range(len(mp4_list) - 1):
457
- filter_parts.append(
458
- f"[v{i}]trim=0:-{crossfade_frames},setpts=PTS-STARTPTS[v{i}pre];"
459
- f"[v{i}]trim=-{crossfade_frames},setpts=PTS-STARTPTS[v{i}fade];"
460
- f"[v{i+1}]trim=0:{crossfade_frames},setpts=PTS-STARTPTS[v{i+1}fade];"
461
- f"[v{i}fade][v{i+1}fade]blend=all_expr='A*(1-T/{crossfade_frames})+B*(T/{crossfade_frames})'[xf{i}]"
462
- )
463
- concat_sequence.append(f"[v{i}pre][xf{i}]")
464
 
465
- # Último vídeo completo
466
- concat_sequence.append(f"[v{len(mp4_list)-1}]")
 
 
 
 
 
 
 
 
467
 
468
- # Monta concat final
469
- concat_str = "".join(concat_sequence)
470
- filter_complex = ";".join(filter_parts) + ";" + concat_str + f"concat=n={len(concat_sequence)}:v=1:a=0[v]"
471
 
472
- # Comando FFmpeg
473
- inputs = " ".join([f"-i '{v}'" for v in mp4_list])
474
- cmd = f"ffmpeg -y {inputs} -filter_complex \"{filter_complex}\" -map \"[v]\" -c:v libx264 -pix_fmt yuv420p '{out_path}'"
475
-
476
- print("[DEBUG] Executando FFmpeg:\n", cmd)
477
- subprocess.run(cmd, shell=True, check=True)
478
- print("✅ Vídeo final gerado:", out_path)
479
-
480
 
481
 
482
  def generate(
@@ -708,7 +701,7 @@ class VideoService:
708
 
709
  final_concat = os.path.join(results_dir, f"concat_fim_{used_seed}.mp4")
710
  #self._concat_mp4s_no_reencode(partes_mp4, final_concat)
711
- self._concat_crossfade_videos_por_frames(
712
  partes_mp4,
713
  final_concat,
714
  crossfade_frames=8,
 
437
 
438
 
439
 
440
+ def _concat_crossfade_cascade(self, videos, output_path, crossfade_duration=8):
441
  """
442
+ Concatena vídeos em cascata com crossfade.
443
+
444
+ :param videos: lista de caminhos de vídeos
445
+ :param output_path: caminho final do vídeo concatenado
446
+ :param crossfade_duration: duração do crossfade em frames
447
  """
448
+ if len(videos) < 2:
449
+ raise ValueError("Precisa de pelo menos 2 vídeos para concatenar")
 
 
 
450
 
451
+ temp_video = videos[0]
452
+
453
+ for i in range(1, len(videos)):
454
+ next_video = videos[i]
455
+ tmp_output = f"/tmp/cascade_{i}.mp4"
 
 
 
 
 
 
 
 
456
 
457
+ cmd = f"""
458
+ ffmpeg -y -i "{temp_video}" -i "{next_video}" -filter_complex "
459
+ [0:v]trim=0:-{crossfade_duration},setpts=PTS-STARTPTS[v0pre];
460
+ [0:v]trim=-{crossfade_duration},setpts=PTS-STARTPTS[v0fade];
461
+ [1:v]trim=0:{crossfade_duration},setpts=PTS-STARTPTS[v1fade];
462
+ [v0fade][v1fade]blend=all_expr='A*(1-T/{crossfade_duration})+B*(T/{crossfade_duration})'[xf];
463
+ [0:v]trim=0:-{crossfade_duration},setpts=PTS-STARTPTS[v0start];
464
+ [1:v]trim={crossfade_duration}:,setpts=PTS-STARTPTS[v1end];
465
+ [v0start][xf][v1end]concat=n=3:v=1:a=0[v]" -map "[v]" -c:v libx264 -pix_fmt yuv420p "{tmp_output}"
466
+ """
467
 
468
+ subprocess.run(cmd, shell=True, check=True)
469
+ temp_video = tmp_output # próximo loop concatena sobre este
 
470
 
471
+ # Renomeia o último temporário como saída final
472
+ os.rename(temp_video, output_path)
 
 
 
 
 
 
473
 
474
 
475
  def generate(
 
701
 
702
  final_concat = os.path.join(results_dir, f"concat_fim_{used_seed}.mp4")
703
  #self._concat_mp4s_no_reencode(partes_mp4, final_concat)
704
+ self._concat_crossfade_cascade(
705
  partes_mp4,
706
  final_concat,
707
  crossfade_frames=8,