Coverage for apps/video.py: 92%

24 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-09 04:47 +0000

1import math 

2 

3from enum import Enum 

4 

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) 

14 

15# Quality as number of steps: 

16# Low: 10 

17# Medium: 20 

18# High: 30 

19NUM_STEPS = 20 

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 

25 

26 

27class VideoQuality(Enum): 

28 """Quality of the video.""" 

29 LOW = "low" # 5 steps 

30 MEDIUM = "medium" # 15 steps 

31 HIGH = "high" # 25 steps 

32 

33 

34QUALITY_TO_NUM_STEPS = { 

35 VideoQuality.LOW.value: 10, 

36 VideoQuality.MEDIUM.value: 15, 

37 VideoQuality.HIGH.value: 25, 

38} 

39 

40 

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 

54 

55 

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 

61 

62 

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