-
-
Notifications
You must be signed in to change notification settings - Fork 141
/
Copy path_media_property.py
159 lines (123 loc) · 3.91 KB
/
_media_property.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
ffmpeg_streaming.media
~~~~~~~~~~~~
Size and Bitrate Objects
:copyright: (c) 2020 by Amin Yazdanpanah.
:website: https://www.aminyazdanpanah.com
:email: [email protected]
:license: MIT, see LICENSE for more details.
"""
import math
OVERALL_TO_VIDEO_COEFFICIENT = 1
MAX_RATE_COEFFICIENT = 1.2
BUFFER_SIZE = 65536
def cnv_bitrate(bitrate: int, _type: str) -> str:
if _type == "k":
bitrate = round(bitrate / 1024)
elif _type == "m":
bitrate = round(bitrate / 1024 * 1024)
else:
raise ValueError("Unknown type!")
return str(bitrate) + _type
class Bitrate:
def __init__(self, video: int = None, audio: int = None, overall: int = None, **kwargs):
"""
@TODO: add documentation
"""
if video is None and overall is None:
raise ValueError("You must at least specify value of the video or overall format")
self.overall_ = overall
self.video_ = video
self.audio_ = audio
self.kwargs = kwargs
self.type = kwargs.pop("type", "k")
@property
def overall(self):
"""
@TODO: add documentation
"""
return cnv_bitrate(self.overall_, self.type) if self.overall_ is not None else None
@property
def video(self):
"""
@TODO: add documentation
"""
return cnv_bitrate(self.video_, self.type) if self.video_ is not None else None
@property
def audio(self):
"""
@TODO: add documentation
"""
return cnv_bitrate(self.audio_, self.type) if self.audio_ is not None else 'copy'
def calc_video(self, convert: bool = True):
"""
@TODO: add documentation
"""
if self.video_ is not None and self.video_ != 0:
val = self.video_
else:
val = int(self.overall_ * OVERALL_TO_VIDEO_COEFFICIENT)
return cnv_bitrate(val, self.type) if convert else val
@property
def calc_overall(self):
"""
@TODO: add documentation
"""
return self.overall_ if self.overall_ is not None else self.video_ + self.audio_
def multiple_up(value, multiple):
while 0 != value % multiple:
value += 1
return value
def multiple_down(value, multiple):
while 0 != value % multiple:
value -= 1
return value
class Ratio:
def __init__(self, width: int, height: int):
"""
@TODO: add documentation
"""
self.width = width
self.height = height
def get_value(self) -> float:
return self.width / self.height
def calculate_width(self, height: int, multiple: int = 1) -> int:
"""
@TODO: add documentation
"""
max_w = multiple_up(math.ceil(self.get_value() * height), multiple)
min_w = multiple_down(math.floor(self.get_value() * height), multiple)
max_r = abs(self.get_value() - (max_w / height))
min_r = abs(self.get_value() - (min_w / height))
return max_w if max_r < min_r else min_w
def calculate_height(self, width: int, multiple: int = 1) -> int:
"""
@TODO: add documentation
"""
max_h = multiple_up(math.ceil(width / self.get_value()), multiple)
min_h = multiple_down(math.floor(width / self.get_value()), multiple)
max_r = abs(self.get_value() - (width / max_h))
min_r = abs(self.get_value() - (width / min_h))
return max_h if max_r < min_r else min_h
class Size:
def __init__(self, width: int, height: int):
"""
@TODO: add documentation
"""
self.width = width
self.height = height
@property
def ratio(self) -> Ratio:
"""
@TODO: add documentation
"""
return Ratio(self.width, self.height)
def __str__(self) -> str:
"""
@TODO: add documentation
"""
return f"{self.width}x{self.height}"
__all__ = [
'Size',
'Bitrate'
]