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
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
1#!/usr/bin/env python3
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
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
27 # **************************************************************************
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"
34 # **************************************************************************
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 )
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
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
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
106 # Return error ...
107 return "ERROR", "ERROR", "ERROR"