Coverage for apps/video.py: 92%
24 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
1import math
3from enum import Enum
5# FPS
6WAN_FPS = 16.0
7FANTASYTALKING_FPS = 23.0
8HUNYUANFRAMEPACK_FPS = 30.0
9# VAE
10VAE_T = 4
11FANTASYTALKING_VAE_T = VAE_T
12HUNYUANFRAMEPACK_VAE_T = VAE_T
13VAE_STRIDE = (VAE_T, 8, 8) # (T, H, W)
15# Quality as number of steps:
16# Low: 10
17# Medium: 20
18# High: 30
19NUM_STEPS = 20
21# This duration is the mismatch with 1 + (frames - 1 // 4) * 4
22# We can probably extend this number beyond 1+80 frames
23# MAX_FT_DURATION_SECS = (1 + 80) / 23.0 # 1+10 frames / 23 FPS
24MAX_FT_DURATION_SECS = (1 + 116) / 23.0 # 1+10 frames / 23 FPS
27class VideoQuality(Enum):
28 """Quality of the video."""
29 LOW = "low" # 5 steps
30 MEDIUM = "medium" # 15 steps
31 HIGH = "high" # 25 steps
34QUALITY_TO_NUM_STEPS = {
35 VideoQuality.LOW.value: 10,
36 VideoQuality.MEDIUM.value: 15,
37 VideoQuality.HIGH.value: 25,
38}
41def get_num_video_frames_from_duration(
42 duration_seconds: float,
43 fps: float = FANTASYTALKING_FPS,
44 vae_t: int = FANTASYTALKING_VAE_T
45) -> int:
46 """
47 Get number of frames for the video based on audio duration and FPS.
48 This is based on what Fantasy Talking does.
49 This rounds based on the latent of the VAE.
50 """
51 audio_num_frames = int(math.ceil(duration_seconds * fps))
52 num_video_frames = int(1 + math.ceil((audio_num_frames - 1) / vae_t) * vae_t) # Round up to VAE (1+4n)
53 return num_video_frames
56def to_num_latent_frames(
57 num_frames: int,
58 vae_t: int = FANTASYTALKING_VAE_T
59) -> int:
60 return (num_frames - 1) // vae_t + 1
63def to_num_frames(
64 num_latent_frames: int,
65 vae_t: int = FANTASYTALKING_VAE_T
66) -> int:
67 return num_latent_frames * vae_t + 1