goryhon commited on
Commit
5043bf0
·
verified ·
1 Parent(s): 104b059

Update web-demos/hugging_face/app.py

Browse files
Files changed (1) hide show
  1. web-demos/hugging_face/app.py +38 -38
web-demos/hugging_face/app.py CHANGED
@@ -365,48 +365,48 @@ def inpaint_video(video_state, *_args):
365
 
366
 
367
  # generate video after vos inference
368
- def generate_video_from_frames(frames, output_path, fps=30, bitrate=None):
369
  """
370
- Generates a video from a list of frames.
371
-
372
- Args:
373
- frames (list of numpy arrays): The frames to include in the video.
374
- output_path (str): The path to save the generated video.
375
- fps (int, optional): The frame rate of the output video. Defaults to 30.
376
  """
377
- # Приведение fps к обычному float (из np.float64, если нужно)
378
- import numpy as np
379
- import imageio
380
- import torch
381
- import torchvision
382
  import os
383
- from fractions import Fraction
384
-
385
- # Convert fps to a clean format
386
- if isinstance(fps, np.generic):
387
- fps = fps.item()
388
- fps = float(fps)
389
-
390
- # Ensure all frames are the same shape
391
- assert all(f.shape == frames[0].shape for f in frames), "All frames must have the same shape"
392
-
393
- # Convert to tensor (T, H, W, C)
394
- #frames = torch.from_numpy(np.asarray(frames))
395
-
396
- # Ensure output directory exists
397
- if not os.path.exists(os.path.dirname(output_path)):
398
- os.makedirs(os.path.dirname(output_path))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
 
400
- # Write the video
401
- #torchvision.io.write_video(output_path, frames, fps=fps, video_codec="libx264")
402
- #return output_path
403
- if bitrate is not None:
404
- writer = imageio.get_writer(output_path, fps=fps, codec='libx264', bitrate=bitrate)
405
- else:
406
- writer = imageio.get_writer(output_path, fps=fps, codec='libx264')
407
- for frame in frames:
408
- writer.append_data(frame.astype(np.uint8))
409
- writer.close()
410
  return output_path
411
 
412
  def restart():
 
365
 
366
 
367
  # generate video after vos inference
368
+ def generate_video_from_frames(frames, output_path, fps=30):
369
  """
370
+ Save high-quality video using ffmpeg and CRF.
 
 
 
 
 
371
  """
 
 
 
 
 
372
  import os
373
+ import cv2
374
+ import numpy as np
375
+ import subprocess
376
+ import tempfile
377
+
378
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
379
+
380
+ # Убедимся, что все кадры одинакового размера
381
+ h, w, _ = frames[0].shape
382
+ h, w = h // 2 * 2, w // 2 * 2
383
+ frames = [cv2.resize(f, (w, h)) for f in frames]
384
+
385
+ # Временная папка
386
+ with tempfile.TemporaryDirectory() as tmpdir:
387
+ frame_dir = os.path.join(tmpdir, "frames")
388
+ os.makedirs(frame_dir, exist_ok=True)
389
+
390
+ # Сохраняем каждый кадр как PNG
391
+ for idx, frame in enumerate(frames):
392
+ cv2.imwrite(os.path.join(frame_dir, f"{idx:05d}.png"), frame)
393
+
394
+ # Генерируем видео через ffmpeg
395
+ ffmpeg_cmd = [
396
+ "ffmpeg",
397
+ "-y",
398
+ "-framerate", str(fps),
399
+ "-i", os.path.join(frame_dir, "%05d.png"),
400
+ "-c:v", "libx264",
401
+ "-preset", "slow", # качество > скорость
402
+ "-crf", "18", # высокое качество (0 — без потерь)
403
+ "-pix_fmt", "yuv420p",
404
+ output_path
405
+ ]
406
+
407
+ print("Running ffmpeg:", " ".join(ffmpeg_cmd))
408
+ subprocess.run(ffmpeg_cmd, check=True)
409
 
 
 
 
 
 
 
 
 
 
 
410
  return output_path
411
 
412
  def restart():