Coverage for pyguymer3/media/return_video_source_aspect_ratio.py: 80%
30 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_source_aspect_ratio(
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_height import return_video_height
23 from .return_video_width import return_video_width
25 # **************************************************************************
27 # Try to find the paths if the user did not provide them ...
28 if ffprobePath is None:
29 ffprobePath = shutil.which("ffprobe")
30 assert ffprobePath is not None, "\"ffprobe\" is not installed"
32 # **************************************************************************
34 # Make sure that this fname/playlist combination is in the global dictionary ...
35 if fname not in __ffprobe__:
36 __ffprobe__[fname] = {}
37 if playlist not in __ffprobe__[fname]:
38 if debug:
39 print(f"INFO: Running ffprobe(\"{fname}\", {playlist:d}) ...")
40 __ffprobe__[fname][playlist] = ffprobe(
41 fname,
42 cwd = cwd,
43 ensureNFC = ensureNFC,
44 ffprobePath = ffprobePath,
45 playlist = playlist,
46 timeout = timeout,
47 )
49 # Loop over streams ...
50 for stream in __ffprobe__[fname][playlist]["streams"]:
51 # Skip stream if it is not video ...
52 if stream["codec_type"].strip().lower() != "video":
53 continue
55 # Find common dimensions divisors ...
56 w = return_video_width(
57 fname,
58 cwd = cwd,
59 debug = debug,
60 ensureNFC = ensureNFC,
61 ffprobePath = ffprobePath,
62 playlist = playlist,
63 timeout = timeout,
64 ) # [px]
65 h = return_video_height(
66 fname,
67 cwd = cwd,
68 debug = debug,
69 ensureNFC = ensureNFC,
70 ffprobePath = ffprobePath,
71 playlist = playlist,
72 timeout = timeout,
73 ) # [px]
74 w_divs = find_integer_divisors(w)
75 h_divs = find_integer_divisors(h)
76 fact = 1
77 for w_div in reversed(w_divs):
78 if w_div in h_divs:
79 fact = w_div
80 break
82 # Return scaled dimensions as source aspect ratio ...
83 return f"{w // fact:d}:{h // fact:d}"
85 # Return error ...
86 return "ERROR"