Coverage for pyguymer3/media/return_video_ratios.py: 83%

35 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-08 18:47 +0000

1#!/usr/bin/env python3 

2 

3# Define function ... 

4def return_video_ratios( 

5 fname, 

6 /, 

7 *, 

8 cwd = None, 

9 debug = __debug__, 

10 ensureNFC = True, 

11 ffprobePath = None, 

12 playlist = -1, 

13 timeout = 60.0, 

14): 

15 # Import standard modules ... 

16 import shutil 

17 

18 # Import sub-functions ... 

19 from .__ffprobe__ import __ffprobe__ 

20 from .ffprobe import ffprobe 

21 from ..find_integer_divisors import find_integer_divisors 

22 from .return_video_display_aspect_ratio import return_video_display_aspect_ratio 

23 from .return_video_height import return_video_height 

24 from .return_video_pixel_aspect_ratio import return_video_pixel_aspect_ratio 

25 from .return_video_width import return_video_width 

26 

27 # ************************************************************************** 

28 

29 # Try to find the paths if the user did not provide them ... 

30 if ffprobePath is None: 

31 ffprobePath = shutil.which("ffprobe") 

32 assert ffprobePath is not None, "\"ffprobe\" is not installed" 

33 

34 # ************************************************************************** 

35 

36 # Make sure that this fname/playlist combination is in the global dictionary ... 

37 if fname not in __ffprobe__: 

38 __ffprobe__[fname] = {} 

39 if playlist not in __ffprobe__[fname]: 

40 if debug: 

41 print(f"INFO: Running ffprobe(\"{fname}\", {playlist:d}) ...") 

42 __ffprobe__[fname][playlist] = ffprobe( 

43 fname, 

44 cwd = cwd, 

45 ensureNFC = ensureNFC, 

46 ffprobePath = ffprobePath, 

47 playlist = playlist, 

48 timeout = timeout, 

49 ) 

50 

51 # Loop over streams ... 

52 for stream in __ffprobe__[fname][playlist]["streams"]: 

53 # Skip stream if it is not video ... 

54 if stream["codec_type"].strip().lower() != "video": 

55 continue 

56 

57 # Find common dimensions divisors ... 

58 w = return_video_width( 

59 fname, 

60 cwd = cwd, 

61 debug = debug, 

62 ensureNFC = ensureNFC, 

63 ffprobePath = ffprobePath, 

64 playlist = playlist, 

65 timeout = timeout, 

66 ) # [px] 

67 h = return_video_height( 

68 fname, 

69 cwd = cwd, 

70 debug = debug, 

71 ensureNFC = ensureNFC, 

72 ffprobePath = ffprobePath, 

73 playlist = playlist, 

74 timeout = timeout, 

75 ) # [px] 

76 w_divs = find_integer_divisors(w) 

77 h_divs = find_integer_divisors(h) 

78 fact = 1 

79 for w_div in reversed(w_divs): 

80 if w_div in h_divs: 

81 fact = w_div 

82 break 

83 

84 # Create short-hands and then return them ... 

85 dar = return_video_display_aspect_ratio( 

86 fname, 

87 cwd = cwd, 

88 debug = debug, 

89 ensureNFC = ensureNFC, 

90 ffprobePath = ffprobePath, 

91 playlist = playlist, 

92 timeout = timeout, 

93 ) 

94 par = return_video_pixel_aspect_ratio( 

95 fname, 

96 cwd = cwd, 

97 debug = debug, 

98 ensureNFC = ensureNFC, 

99 ffprobePath = ffprobePath, 

100 playlist = playlist, 

101 timeout = timeout, 

102 ) 

103 sar = f"{w // fact:d}:{h // fact:d}" 

104 return dar, par, sar 

105 

106 # Return error ... 

107 return "ERROR", "ERROR", "ERROR"