yta-video-frame-time 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yta-video-frame-time might be problematic. Click here for more details.
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module to handle frame indexes and times.
|
|
3
|
+
"""
|
|
4
|
+
from yta_validation.parameter import ParameterValidator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
SMALL_AMOUNT_TO_FIX = 0.0000000001
|
|
8
|
+
"""
|
|
9
|
+
Small amount we need to add to fix some floating
|
|
10
|
+
point number issues we've found. Something like
|
|
11
|
+
0.3333333333333326 will turn into 9 frames for a
|
|
12
|
+
fps = 30 video, but this is wrong, as it should
|
|
13
|
+
be 10 frames and it is happening due to a minimal
|
|
14
|
+
floating point difference.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class T:
|
|
19
|
+
"""
|
|
20
|
+
Class to wrap the functionality related
|
|
21
|
+
to handling a video frame time moment 't'.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def get_frame_time_base(
|
|
25
|
+
t: float,
|
|
26
|
+
fps: float
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Get the base frame time moment t
|
|
30
|
+
(the one who is the start of the
|
|
31
|
+
frame time interval plus a small
|
|
32
|
+
amount to fix issues) from the
|
|
33
|
+
given time moment 't' of the video
|
|
34
|
+
with the also provided 'fps'.
|
|
35
|
+
"""
|
|
36
|
+
ParameterValidator.validate_mandatory_positive_number('t', t, do_include_zero = True)
|
|
37
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
38
|
+
|
|
39
|
+
return T.frame_time_to_frame_index(t, fps) / fps + SMALL_AMOUNT_TO_FIX
|
|
40
|
+
|
|
41
|
+
def get_frame_indexes(
|
|
42
|
+
duration: float,
|
|
43
|
+
fps: float,
|
|
44
|
+
do_invert_order: bool = False
|
|
45
|
+
):
|
|
46
|
+
"""
|
|
47
|
+
Get the list of the frame indexes of
|
|
48
|
+
the video with the given 'duration'
|
|
49
|
+
and 'fps'.
|
|
50
|
+
|
|
51
|
+
If a video lasts 1 second and has 5
|
|
52
|
+
fps, this method will return: 0, 1,
|
|
53
|
+
2, 3, 4.
|
|
54
|
+
"""
|
|
55
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
56
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
57
|
+
ParameterValidator.validate_mandatory_bool('do_invert_order', do_invert_order)
|
|
58
|
+
|
|
59
|
+
# If you remove 'list' you get a generator instead
|
|
60
|
+
frame_indexes = list(range(get_number_of_frames(duration, fps)))
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
frame_indexes[::-1]
|
|
64
|
+
if do_invert_order else
|
|
65
|
+
frame_indexes
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def get_frame_indexes_from_number_of_frames(
|
|
69
|
+
number_of_frames: int,
|
|
70
|
+
do_invert_order: bool = False
|
|
71
|
+
):
|
|
72
|
+
"""
|
|
73
|
+
Get all the video frame indexes that
|
|
74
|
+
a video with the 'number_of_frames'
|
|
75
|
+
given, ordered from first to last if
|
|
76
|
+
'do_invert_order' is False, or from
|
|
77
|
+
last to first if it is True.
|
|
78
|
+
"""
|
|
79
|
+
ParameterValidator.validate_mandatory_positive_int('number_of_frames', number_of_frames, do_include_zero = True)
|
|
80
|
+
ParameterValidator.validate_mandatory_bool('do_invert_order', do_invert_order)
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
list(range(number_of_frames - 1, -1, -1))
|
|
84
|
+
if do_invert_order else
|
|
85
|
+
list(range(number_of_frames))
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def get_first_n_frames_indexes(
|
|
89
|
+
duration: float,
|
|
90
|
+
fps: float,
|
|
91
|
+
n: int
|
|
92
|
+
):
|
|
93
|
+
"""
|
|
94
|
+
Obtain the first 'n' frames indexes of the current
|
|
95
|
+
video to be able to use them within a condition
|
|
96
|
+
with the '.get_frame(t)' method.
|
|
97
|
+
|
|
98
|
+
This list can be used to check if the current frame
|
|
99
|
+
number (index) is on it or not, to apply the frame
|
|
100
|
+
image effect or to leave it as it is.
|
|
101
|
+
|
|
102
|
+
Each frame time moment has been increased by
|
|
103
|
+
a small amount to ensure it is greater than
|
|
104
|
+
the base frame time value (due to decimals
|
|
105
|
+
issue).
|
|
106
|
+
"""
|
|
107
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
108
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
109
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
110
|
+
|
|
111
|
+
return T.get_odd_frames_indexes(duration, fps)[:n]
|
|
112
|
+
|
|
113
|
+
def get_last_n_frames_indexes(
|
|
114
|
+
duration: float,
|
|
115
|
+
fps: float,
|
|
116
|
+
n: int
|
|
117
|
+
):
|
|
118
|
+
"""
|
|
119
|
+
Obtain the last 'n' frames indexes of the current
|
|
120
|
+
video to be able to use them within a condition
|
|
121
|
+
with the '.get_frame(t)' method.
|
|
122
|
+
|
|
123
|
+
This list can be used to check if the current frame
|
|
124
|
+
number (index) is on it or not, to apply the frame
|
|
125
|
+
image effect or to leave it as it is.
|
|
126
|
+
|
|
127
|
+
Each frame time moment has been increased by
|
|
128
|
+
a small amount to ensure it is greater than
|
|
129
|
+
the base frame time value (due to decimals
|
|
130
|
+
issue).
|
|
131
|
+
"""
|
|
132
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
133
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
134
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
135
|
+
|
|
136
|
+
return T.get_odd_frames_indexes(duration, fps)[-n:]
|
|
137
|
+
|
|
138
|
+
def get_even_frames_indexes(
|
|
139
|
+
duration: float,
|
|
140
|
+
fps: float
|
|
141
|
+
):
|
|
142
|
+
"""
|
|
143
|
+
Array containing all the even indexes of video
|
|
144
|
+
frames that can be used to obtain its corresponding
|
|
145
|
+
frame time moment, or to simplify calculations.
|
|
146
|
+
"""
|
|
147
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
148
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
149
|
+
|
|
150
|
+
frame_indexes = T.get_frame_indexes(duration, fps)
|
|
151
|
+
|
|
152
|
+
return frame_indexes[frame_indexes % 2 == 0]
|
|
153
|
+
|
|
154
|
+
def get_first_n_even_frames_indexes(
|
|
155
|
+
duration: float,
|
|
156
|
+
fps: float,
|
|
157
|
+
n: int
|
|
158
|
+
):
|
|
159
|
+
"""
|
|
160
|
+
Obtain the first 'n' even frames indexes of the
|
|
161
|
+
current video to be able to use them within a
|
|
162
|
+
condition with the '.get_frame(t)' method.
|
|
163
|
+
|
|
164
|
+
This list can be used to check if the current frame
|
|
165
|
+
number (index) is on it or not, to apply the frame
|
|
166
|
+
image effect or to leave it as it is.
|
|
167
|
+
|
|
168
|
+
If 'n' is greater than the real number of even
|
|
169
|
+
frames, 'n' will get that value so the result will
|
|
170
|
+
be all the even frames indexes.
|
|
171
|
+
|
|
172
|
+
Each frame time moment has been increased by
|
|
173
|
+
a small amount to ensure it is greater than
|
|
174
|
+
the base frame time value (due to decimals
|
|
175
|
+
issue).
|
|
176
|
+
"""
|
|
177
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
178
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
179
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
180
|
+
|
|
181
|
+
return T.get_even_frames_indexes(duration, fps)[:n]
|
|
182
|
+
|
|
183
|
+
def get_last_n_even_frames_indexes(
|
|
184
|
+
duration: float,
|
|
185
|
+
fps: float,
|
|
186
|
+
n: int
|
|
187
|
+
):
|
|
188
|
+
"""
|
|
189
|
+
Obtain the last 'n' even frames indexes of the
|
|
190
|
+
current video to be able to use them within a
|
|
191
|
+
condition with the '.get_frame(t)' method.
|
|
192
|
+
|
|
193
|
+
This list can be used to check if the current frame
|
|
194
|
+
number (index) is on it or not, to apply the frame
|
|
195
|
+
image effect or to leave it as it is.
|
|
196
|
+
|
|
197
|
+
If 'n' is greater than the real number of even
|
|
198
|
+
frames, 'n' will get that value so the result will
|
|
199
|
+
be all the even frames indexes.
|
|
200
|
+
|
|
201
|
+
Each frame time moment has been increased by
|
|
202
|
+
a small amount to ensure it is greater than
|
|
203
|
+
the base frame time value (due to decimals
|
|
204
|
+
issue).
|
|
205
|
+
"""
|
|
206
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
207
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
208
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
209
|
+
|
|
210
|
+
return T.get_even_frames_indexes(duration, fps)[-n:]
|
|
211
|
+
|
|
212
|
+
def get_odd_frames_indexes(
|
|
213
|
+
duration: float,
|
|
214
|
+
fps: float,
|
|
215
|
+
):
|
|
216
|
+
"""
|
|
217
|
+
Array containing all the odd indexes of video
|
|
218
|
+
frames that can be used to obtain its corresponding
|
|
219
|
+
frame time moment, or to simplify calculations.
|
|
220
|
+
"""
|
|
221
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
222
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
223
|
+
|
|
224
|
+
frame_indexes = T.get_frame_indexes(duration, fps)
|
|
225
|
+
|
|
226
|
+
return frame_indexes[frame_indexes % 2 != 0]
|
|
227
|
+
|
|
228
|
+
def get_last_n_odd_frames_indexes(
|
|
229
|
+
duration: float,
|
|
230
|
+
fps: float,
|
|
231
|
+
n: int
|
|
232
|
+
):
|
|
233
|
+
"""
|
|
234
|
+
Obtain the last 'n' odd frames indexes of the
|
|
235
|
+
current video to be able to use them within a
|
|
236
|
+
condition with the '.get_frame(t)' method.
|
|
237
|
+
|
|
238
|
+
This list can be used to check if the current frame
|
|
239
|
+
number (index) is on it or not, to apply the frame
|
|
240
|
+
image effect or to leave it as it is.
|
|
241
|
+
|
|
242
|
+
If 'n' is greater than the real number of odd
|
|
243
|
+
frames, 'n' will get that value so the result will
|
|
244
|
+
be all the odd frames indexes.
|
|
245
|
+
|
|
246
|
+
Each frame time moment has been increased by
|
|
247
|
+
a small amount to ensure it is greater than
|
|
248
|
+
the base frame time value (due to decimals
|
|
249
|
+
issue).
|
|
250
|
+
"""
|
|
251
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
252
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
253
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
254
|
+
|
|
255
|
+
return T.get_odd_frames_indexes(duration, fps)[-n:]
|
|
256
|
+
|
|
257
|
+
def get_first_n_odd_frames_indexes(
|
|
258
|
+
duration: float,
|
|
259
|
+
fps: float,
|
|
260
|
+
n: int
|
|
261
|
+
):
|
|
262
|
+
"""
|
|
263
|
+
Obtain the first 'n' odd frames indexes of the
|
|
264
|
+
current video to be able to use them within a
|
|
265
|
+
condition with the '.get_frame(t)' method.
|
|
266
|
+
|
|
267
|
+
This list can be used to check if the current frame
|
|
268
|
+
number (index) is on it or not, to apply the frame
|
|
269
|
+
image effect or to leave it as it is.
|
|
270
|
+
|
|
271
|
+
If 'n' is greater than the real number of odd
|
|
272
|
+
frames, 'n' will get that value so the result will
|
|
273
|
+
be all the odd frames indexes.
|
|
274
|
+
|
|
275
|
+
Each frame time moment has been increased by
|
|
276
|
+
a small amount to ensure it is greater than
|
|
277
|
+
the base frame time value (due to decimals
|
|
278
|
+
issue).
|
|
279
|
+
"""
|
|
280
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
281
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
282
|
+
ParameterValidator.validate_mandatory_positive_int('n', n, do_include_zero = False)
|
|
283
|
+
|
|
284
|
+
return T.get_odd_frames_indexes(duration, fps)[:n]
|
|
285
|
+
|
|
286
|
+
def get_frame_time_moments(
|
|
287
|
+
duration: float,
|
|
288
|
+
fps: float,
|
|
289
|
+
do_invert_order: bool = False
|
|
290
|
+
):
|
|
291
|
+
"""
|
|
292
|
+
Get the time moment of each video
|
|
293
|
+
frame according to the provided video
|
|
294
|
+
'duration' and 'fps'. This will always
|
|
295
|
+
include the second 0 and the
|
|
296
|
+
inmediately before the duration.
|
|
297
|
+
|
|
298
|
+
If a video lasts 1 second and has 5
|
|
299
|
+
fps, this method will return: 0, 0.2,
|
|
300
|
+
0.4, 0.6, 0.8.
|
|
301
|
+
|
|
302
|
+
This method can return non-exact
|
|
303
|
+
decimal values so we recommend you to
|
|
304
|
+
add a small amount to ensure it is
|
|
305
|
+
above the expected base frame time.
|
|
306
|
+
"""
|
|
307
|
+
ParameterValidator.validate_mandatory_positive_number('duration', duration, do_include_zero = False)
|
|
308
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
309
|
+
ParameterValidator.validate_mandatory_bool('do_invert_order', do_invert_order)
|
|
310
|
+
|
|
311
|
+
frame_time_moments = [
|
|
312
|
+
(get_frame_duration(fps) * i) + SMALL_AMOUNT_TO_FIX
|
|
313
|
+
for i in range(get_number_of_frames(duration, fps) + 1)
|
|
314
|
+
][:-1]
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
frame_time_moments[::-1]
|
|
318
|
+
if do_invert_order else
|
|
319
|
+
frame_time_moments
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
def get_frame_time_moments_from_number_of_frames(
|
|
323
|
+
number_of_frames: int,
|
|
324
|
+
fps: float,
|
|
325
|
+
do_invert_order: bool = False
|
|
326
|
+
):
|
|
327
|
+
"""
|
|
328
|
+
Get all the video frame time moments
|
|
329
|
+
t for a video with the provided
|
|
330
|
+
'number_of_frames'. Each 't' includes
|
|
331
|
+
a small amount increased to fix some
|
|
332
|
+
issues.
|
|
333
|
+
"""
|
|
334
|
+
ParameterValidator.validate_mandatory_positive_int('number_of_frames', number_of_frames, do_include_zero = False)
|
|
335
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
336
|
+
ParameterValidator.validate_mandatory_bool('do_invert_order', do_invert_order)
|
|
337
|
+
|
|
338
|
+
return [
|
|
339
|
+
T.frame_index_to_frame_time(i, fps)
|
|
340
|
+
for i in T.get_frame_indexes_from_number_of_frames(number_of_frames)
|
|
341
|
+
]
|
|
342
|
+
|
|
343
|
+
def video_frame_time_to_video_frame_index(
|
|
344
|
+
t: float,
|
|
345
|
+
fps: float
|
|
346
|
+
):
|
|
347
|
+
"""
|
|
348
|
+
Transform the provided 't' frame time to
|
|
349
|
+
its corresponding frame index according
|
|
350
|
+
to the 'fps' provided.
|
|
351
|
+
|
|
352
|
+
This method applies the next formula:
|
|
353
|
+
|
|
354
|
+
int(t * fps + SMALL_AMOUNT_TO_FIX)
|
|
355
|
+
"""
|
|
356
|
+
ParameterValidator.validate_mandatory_positive_number('t', t, do_include_zero = True)
|
|
357
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
358
|
+
|
|
359
|
+
return int((t + SMALL_AMOUNT_TO_FIX) * fps)
|
|
360
|
+
|
|
361
|
+
def video_frame_index_to_video_frame_time(
|
|
362
|
+
i: int,
|
|
363
|
+
fps: float
|
|
364
|
+
):
|
|
365
|
+
"""
|
|
366
|
+
Transform the provided 'i' frame index to
|
|
367
|
+
its corresponding frame time according to
|
|
368
|
+
the 'fps' provided.
|
|
369
|
+
|
|
370
|
+
This method applies the next formula:
|
|
371
|
+
|
|
372
|
+
i * 1 / fps + SMALL_AMOUNT_TO_FIX
|
|
373
|
+
"""
|
|
374
|
+
ParameterValidator.validate_mandatory_positive_int('i', i, do_include_zero = True)
|
|
375
|
+
ParameterValidator.validate_mandatory_positive_number('fps', fps, do_include_zero = False)
|
|
376
|
+
|
|
377
|
+
return i * get_frame_duration(fps) + SMALL_AMOUNT_TO_FIX
|
|
378
|
+
|
|
379
|
+
# Audio below
|
|
380
|
+
def video_frame_time_to_audio_frame_times(
|
|
381
|
+
video_t: float,
|
|
382
|
+
video_fps: float,
|
|
383
|
+
audio_fps: float,
|
|
384
|
+
do_invert_order: bool = False
|
|
385
|
+
):
|
|
386
|
+
"""
|
|
387
|
+
Get all the audio time moments (tts)
|
|
388
|
+
attached to the given video time
|
|
389
|
+
moment 't', as an array.
|
|
390
|
+
|
|
391
|
+
One video time moment 't' includes
|
|
392
|
+
a lot of video audio 't' time
|
|
393
|
+
moments. The amount of video audio
|
|
394
|
+
frames per video frame is calculated
|
|
395
|
+
with the division of the audio fps
|
|
396
|
+
by the video fps.
|
|
397
|
+
|
|
398
|
+
The result is an array of 't' video
|
|
399
|
+
audio time moments. Maybe you need
|
|
400
|
+
to turn it into a numpy array.
|
|
401
|
+
|
|
402
|
+
This is useful to obtain all the
|
|
403
|
+
video audio time moments attached to
|
|
404
|
+
the given video time moment
|
|
405
|
+
'video_t'.
|
|
406
|
+
"""
|
|
407
|
+
ParameterValidator.validate_mandatory_positive_number('video_t', video_t, do_include_zero = True)
|
|
408
|
+
ParameterValidator.validate_mandatory_positive_number('video_fps', video_fps, do_include_zero = False)
|
|
409
|
+
ParameterValidator.validate_mandatory_positive_number('audio_fps', audio_fps, do_include_zero = False)
|
|
410
|
+
ParameterValidator.validate_mandatory_bool('do_invert_order', do_invert_order)
|
|
411
|
+
|
|
412
|
+
from yta_general_utils.math.progression import Progression
|
|
413
|
+
|
|
414
|
+
audio_frames_per_video_frame = int(audio_fps / video_fps)
|
|
415
|
+
audio_frame_duration = 1 / audio_fps
|
|
416
|
+
video_frame_duration = 1 / video_fps
|
|
417
|
+
|
|
418
|
+
t = T.get_frame_time_base(video_t, video_fps)
|
|
419
|
+
|
|
420
|
+
audio_time_moments = Progression(
|
|
421
|
+
start = t,
|
|
422
|
+
end = t + video_frame_duration - audio_frame_duration,
|
|
423
|
+
n = audio_frames_per_video_frame
|
|
424
|
+
).values
|
|
425
|
+
|
|
426
|
+
return (
|
|
427
|
+
audio_time_moments[::-1]
|
|
428
|
+
if do_invert_order else
|
|
429
|
+
audio_time_moments
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
def audio_frame_time_to_video_frame_time(
|
|
433
|
+
audio_t: float,
|
|
434
|
+
video_fps: float
|
|
435
|
+
):
|
|
436
|
+
"""
|
|
437
|
+
Get the video frame time moment t
|
|
438
|
+
from the given video udio frame time
|
|
439
|
+
moment 'audio_t', according to its
|
|
440
|
+
'video_fps' frames per second.
|
|
441
|
+
|
|
442
|
+
This method is useful to obtain the
|
|
443
|
+
video frame attached to the given
|
|
444
|
+
audio time moment 'audio_t'.
|
|
445
|
+
"""
|
|
446
|
+
ParameterValidator.validate_mandatory_positive_number('audio_t', audio_t, do_include_zero = True)
|
|
447
|
+
ParameterValidator.validate_mandatory_positive_number('video_fps', video_fps, do_include_zero = False)
|
|
448
|
+
|
|
449
|
+
return T.get_frame_time_base(audio_t , video_fps)
|
|
450
|
+
|
|
451
|
+
def audio_frame_index_to_video_frame_index(
|
|
452
|
+
audio_index: int,
|
|
453
|
+
video_fps: float,
|
|
454
|
+
audio_fps: float
|
|
455
|
+
):
|
|
456
|
+
"""
|
|
457
|
+
Get the video frame index from the
|
|
458
|
+
provided video audio frame index
|
|
459
|
+
'audio_index', using the also given
|
|
460
|
+
'video_fps' and 'audio_fps'.
|
|
461
|
+
"""
|
|
462
|
+
ParameterValidator.validate_mandatory_positive_int('audio_index', audio_index, do_include_zero = True)
|
|
463
|
+
ParameterValidator.validate_mandatory_positive_number('video_fps', video_fps, do_include_zero = False)
|
|
464
|
+
ParameterValidator.validate_mandatory_positive_number('audio_fps', audio_fps, do_include_zero = False)
|
|
465
|
+
|
|
466
|
+
return round(audio_index * (video_fps / audio_fps))
|
|
467
|
+
|
|
468
|
+
def audio_frame_index_to_video_frame_time(
|
|
469
|
+
audio_index: int,
|
|
470
|
+
video_fps: float,
|
|
471
|
+
audio_fps: float
|
|
472
|
+
):
|
|
473
|
+
"""
|
|
474
|
+
Get the video frame time moment t
|
|
475
|
+
from the given video audio frame
|
|
476
|
+
index 'audio_index', using the also
|
|
477
|
+
provided 'video_fps' and
|
|
478
|
+
'audio_fps'.
|
|
479
|
+
"""
|
|
480
|
+
ParameterValidator.validate_mandatory_positive_int('audio_index', audio_index, do_include_zero = True)
|
|
481
|
+
ParameterValidator.validate_mandatory_positive_number('video_fps', video_fps, do_include_zero = False)
|
|
482
|
+
ParameterValidator.validate_mandatory_positive_number('audio_fps', audio_fps, do_include_zero = False)
|
|
483
|
+
|
|
484
|
+
return T.video_frame_index_to_video_frame_time(
|
|
485
|
+
T.audio_frame_index_to_video_frame_index(
|
|
486
|
+
audio_index,
|
|
487
|
+
video_fps,
|
|
488
|
+
audio_fps
|
|
489
|
+
),
|
|
490
|
+
video_fps
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
def audio_frame_time_to_video_frame_index(
|
|
494
|
+
audio_t: float,
|
|
495
|
+
video_fps: float,
|
|
496
|
+
audio_fps: float
|
|
497
|
+
):
|
|
498
|
+
"""
|
|
499
|
+
Get the video frame index from the
|
|
500
|
+
the given video audio frame time
|
|
501
|
+
moment 'audio_t', using the also
|
|
502
|
+
provided 'video_fps' and 'audio_fps'.
|
|
503
|
+
"""
|
|
504
|
+
ParameterValidator.validate_mandatory_positive_number('audio_t', audio_t, do_include_zero = True)
|
|
505
|
+
ParameterValidator.validate_mandatory_positive_number('video_fps', video_fps, do_include_zero = False)
|
|
506
|
+
ParameterValidator.validate_mandatory_positive_number('audio_fps', audio_fps, do_include_zero = False)
|
|
507
|
+
|
|
508
|
+
return T.audio_frame_index_to_video_frame_index(
|
|
509
|
+
T.video_frame_time_to_video_frame_index(
|
|
510
|
+
audio_t,
|
|
511
|
+
audio_fps
|
|
512
|
+
),
|
|
513
|
+
video_fps,
|
|
514
|
+
audio_fps
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
def get_frame_duration(
|
|
518
|
+
fps: float
|
|
519
|
+
) -> float:
|
|
520
|
+
"""
|
|
521
|
+
Get the frame duration based on the
|
|
522
|
+
video frames per second ('fps')
|
|
523
|
+
provided.
|
|
524
|
+
|
|
525
|
+
The formula is:
|
|
526
|
+
- `1 / fps`
|
|
527
|
+
"""
|
|
528
|
+
return 1 / fps
|
|
529
|
+
|
|
530
|
+
def get_number_of_frames(
|
|
531
|
+
duration: float,
|
|
532
|
+
fps: float
|
|
533
|
+
) -> int:
|
|
534
|
+
"""
|
|
535
|
+
Get the number of frames of the video
|
|
536
|
+
with the given 'duration' and 'fps'
|
|
537
|
+
and using a small amount to fix the
|
|
538
|
+
rounding bug.
|
|
539
|
+
|
|
540
|
+
The formula is:
|
|
541
|
+
- `int(duration * fps + SMALL_AMOUNT)`
|
|
542
|
+
"""
|
|
543
|
+
return int(duration * fps + SMALL_AMOUNT_TO_FIX)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: yta-video-frame-time
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Youtube Autonomous Video Frame Time Module
|
|
5
|
+
Author: danialcala94
|
|
6
|
+
Author-email: danielalcalavalera@gmail.com
|
|
7
|
+
Requires-Python: ==3.9
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Requires-Dist: yta_validation (>=0.0.1,<1.0.0)
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# Youtube Autonomous Video Frame Time Module
|
|
14
|
+
|
|
15
|
+
The way to handle video frame timing
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
yta_video_frame_time/__init__.py,sha256=iN9nRtV3Rjpp6vCcz1fckjVDijHLHzLdTfGN9l4cG6w,20019
|
|
2
|
+
yta_video_frame_time-0.0.1.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
|
3
|
+
yta_video_frame_time-0.0.1.dist-info/METADATA,sha256=uYL_vqtsJSQ7DqSxGf8YXWRyIX1kQDcfYbCLPWH28v8,472
|
|
4
|
+
yta_video_frame_time-0.0.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
5
|
+
yta_video_frame_time-0.0.1.dist-info/RECORD,,
|