yta-video-opengl 0.0.19__py3-none-any.whl → 0.0.21__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.
- yta_video_opengl/audio.py +219 -0
- yta_video_opengl/complete/frame_combinator.py +1 -90
- yta_video_opengl/complete/frame_generator.py +40 -0
- yta_video_opengl/complete/frame_wrapper.py +13 -0
- yta_video_opengl/complete/timeline.py +200 -116
- yta_video_opengl/complete/track/__init__.py +500 -0
- yta_video_opengl/complete/{video_on_track.py → track/media/__init__.py} +112 -47
- yta_video_opengl/complete/track/parts.py +267 -0
- yta_video_opengl/complete/track/utils.py +78 -0
- yta_video_opengl/reader/__init__.py +0 -19
- yta_video_opengl/reader/cache/__init__.py +9 -5
- yta_video_opengl/reader/cache/utils.py +1 -1
- yta_video_opengl/tests.py +29 -1
- yta_video_opengl/video.py +9 -13
- {yta_video_opengl-0.0.19.dist-info → yta_video_opengl-0.0.21.dist-info}/METADATA +1 -1
- yta_video_opengl-0.0.21.dist-info/RECORD +30 -0
- yta_video_opengl/complete/track.py +0 -562
- yta_video_opengl-0.0.19.dist-info/RECORD +0 -27
- {yta_video_opengl-0.0.19.dist-info → yta_video_opengl-0.0.21.dist-info}/LICENSE +0 -0
- {yta_video_opengl-0.0.19.dist-info → yta_video_opengl-0.0.21.dist-info}/WHEEL +0 -0
@@ -1,562 +0,0 @@
|
|
1
|
-
from yta_video_opengl.complete.video_on_track import VideoOnTrack
|
2
|
-
from yta_video_opengl.video import Video
|
3
|
-
from yta_video_opengl.t import T
|
4
|
-
from yta_video_opengl.complete.frame_wrapper import VideoFrameWrapped
|
5
|
-
from yta_video_opengl.utils import audio_frames_and_remainder_per_video_frame
|
6
|
-
from yta_video_opengl.t import fps_to_time_base
|
7
|
-
from yta_video_opengl.complete.frame_wrapper import AudioFrameWrapped
|
8
|
-
from yta_video_opengl.complete.frame_generator import VideoFrameGenerator, AudioFrameGenerator
|
9
|
-
from yta_validation.parameter import ParameterValidator
|
10
|
-
from quicktions import Fraction
|
11
|
-
from typing import Union
|
12
|
-
|
13
|
-
|
14
|
-
NON_LIMITED_EMPTY_PART_END = 999
|
15
|
-
"""
|
16
|
-
A value to indicate that the empty part
|
17
|
-
has no end because it is in the last
|
18
|
-
position and there is no video after it.
|
19
|
-
"""
|
20
|
-
class _Part:
|
21
|
-
"""
|
22
|
-
Class to represent an element that is on the
|
23
|
-
track, that can be an empty space or a video
|
24
|
-
(with audio).
|
25
|
-
"""
|
26
|
-
|
27
|
-
@property
|
28
|
-
def is_empty_part(
|
29
|
-
self
|
30
|
-
) -> bool:
|
31
|
-
"""
|
32
|
-
Flag to indicate if the part is an empty part,
|
33
|
-
which means that there is no video associated
|
34
|
-
but an empty space.
|
35
|
-
"""
|
36
|
-
return self.video is None
|
37
|
-
|
38
|
-
def __init__(
|
39
|
-
self,
|
40
|
-
track: 'Track',
|
41
|
-
start: Union[int, float, Fraction],
|
42
|
-
end: Union[int, float, Fraction],
|
43
|
-
video: Union[VideoOnTrack, None] = None
|
44
|
-
):
|
45
|
-
ParameterValidator.validate_mandatory_positive_number('start', start, do_include_zero = True)
|
46
|
-
ParameterValidator.validate_mandatory_positive_number('end', end, do_include_zero = False)
|
47
|
-
ParameterValidator.validate_instance_of('video', video, VideoOnTrack)
|
48
|
-
|
49
|
-
self._track: Track = track
|
50
|
-
"""
|
51
|
-
The instance of the track this part belongs
|
52
|
-
to.
|
53
|
-
"""
|
54
|
-
# TODO: I would like to avoid this 2 instances
|
55
|
-
# here, and I think I've done it with static
|
56
|
-
# properties in other project, but as I don't
|
57
|
-
# remember how and where by now, here it is...
|
58
|
-
self._video_frame_generator: VideoFrameGenerator = VideoFrameGenerator()
|
59
|
-
"""
|
60
|
-
Useful internal tool to generate background
|
61
|
-
frames for the empty parts.
|
62
|
-
"""
|
63
|
-
self._audio_frame_generator: AudioFrameGenerator = AudioFrameGenerator()
|
64
|
-
"""
|
65
|
-
Useful internal tool to generate silent
|
66
|
-
audio frames for the empty parts.
|
67
|
-
"""
|
68
|
-
self.start: Fraction = Fraction(start)
|
69
|
-
"""
|
70
|
-
The start 't' time moment of the part.
|
71
|
-
"""
|
72
|
-
self.end: Fraction = Fraction(end)
|
73
|
-
"""
|
74
|
-
The end 't' time moment of the part.
|
75
|
-
"""
|
76
|
-
self.video: Union[VideoOnTrack, None] = video
|
77
|
-
"""
|
78
|
-
The video associated, if existing, or
|
79
|
-
None if it is an empty space that we need
|
80
|
-
to fulfill with a black background and
|
81
|
-
silent audio.
|
82
|
-
"""
|
83
|
-
|
84
|
-
def get_frame_at(
|
85
|
-
self,
|
86
|
-
t: Union[int, float, Fraction]
|
87
|
-
) -> 'VideoFrameWrapped':
|
88
|
-
"""
|
89
|
-
Get the frame that must be displayed at
|
90
|
-
the given 't' time moment.
|
91
|
-
"""
|
92
|
-
frame = (
|
93
|
-
# TODO: What about the 'format' (?)
|
94
|
-
# TODO: Maybe I shouldn't set the 'time_base'
|
95
|
-
# here and do it just in the Timeline 'render'
|
96
|
-
#return get_black_background_video_frame(self._track.size)
|
97
|
-
# TODO: This 'time_base' maybe has to be related
|
98
|
-
# to a Timeline general 'time_base' and not the fps
|
99
|
-
VideoFrameWrapped(
|
100
|
-
frame = self._video_frame_generator.background.full_black(
|
101
|
-
size = self._track.size,
|
102
|
-
time_base = fps_to_time_base(self._track.fps)
|
103
|
-
),
|
104
|
-
is_from_empty_part = True
|
105
|
-
)
|
106
|
-
if self.is_empty_part else
|
107
|
-
VideoFrameWrapped(
|
108
|
-
frame = self.video.get_frame_at(t),
|
109
|
-
is_from_empty_part = False
|
110
|
-
)
|
111
|
-
|
112
|
-
)
|
113
|
-
|
114
|
-
# TODO: This should not happen because of
|
115
|
-
# the way we handle the videos here but the
|
116
|
-
# video could send us a None frame here, so
|
117
|
-
# do we raise exception (?)
|
118
|
-
if frame._frame is None:
|
119
|
-
#frame = get_black_background_video_frame(self._track.size)
|
120
|
-
# TODO: By now I'm raising exception to check if
|
121
|
-
# this happens or not because I think it would
|
122
|
-
# be malfunctioning
|
123
|
-
raise Exception(f'Video is returning None video frame at t={str(t)}.')
|
124
|
-
|
125
|
-
return frame
|
126
|
-
|
127
|
-
def get_audio_frames_at(
|
128
|
-
self,
|
129
|
-
t: Union[int, float, Fraction]
|
130
|
-
):
|
131
|
-
"""
|
132
|
-
Iterate over all the audio frames that
|
133
|
-
exist at the time moment 't' provided.
|
134
|
-
"""
|
135
|
-
if not self.is_empty_part:
|
136
|
-
for frame in self.video.get_audio_frames_at(t):
|
137
|
-
yield AudioFrameWrapped(
|
138
|
-
frame = frame,
|
139
|
-
is_from_empty_part = False
|
140
|
-
)
|
141
|
-
else:
|
142
|
-
frames = generate_silent_frames(
|
143
|
-
fps = self._track.fps,
|
144
|
-
audio_fps = self._track.audio_fps,
|
145
|
-
audio_samples_per_frame = self._track.audio_samples_per_frame,
|
146
|
-
# TODO: Where do this 2 formats come from (?)
|
147
|
-
layout = self._track.audio_layout,
|
148
|
-
format = self._track.audio_format
|
149
|
-
)
|
150
|
-
|
151
|
-
for frame in frames:
|
152
|
-
yield frame
|
153
|
-
|
154
|
-
|
155
|
-
# TODO: I don't like using t as float,
|
156
|
-
# we need to implement fractions.Fraction
|
157
|
-
# TODO: This is called Track but it is
|
158
|
-
# handling videos only. Should I have
|
159
|
-
# VideoTrack and AudioTrack (?)
|
160
|
-
class Track:
|
161
|
-
"""
|
162
|
-
Class to represent a track in which we place
|
163
|
-
videos, images and audio to build a video
|
164
|
-
project.
|
165
|
-
"""
|
166
|
-
|
167
|
-
@property
|
168
|
-
def parts(
|
169
|
-
self
|
170
|
-
) -> list[_Part]:
|
171
|
-
"""
|
172
|
-
The list of parts that build this track,
|
173
|
-
but with the empty parts detected to
|
174
|
-
be fulfilled with black frames and silent
|
175
|
-
audios.
|
176
|
-
|
177
|
-
A part can be a video or an empty space.
|
178
|
-
"""
|
179
|
-
if (
|
180
|
-
not hasattr(self, '_parts') or
|
181
|
-
self._parts is None
|
182
|
-
):
|
183
|
-
self._recalculate_parts()
|
184
|
-
|
185
|
-
return self._parts
|
186
|
-
|
187
|
-
@property
|
188
|
-
def end(
|
189
|
-
self
|
190
|
-
) -> Fraction:
|
191
|
-
"""
|
192
|
-
The end of the last video of this track,
|
193
|
-
which is also the end of the track. This
|
194
|
-
is the last time moment that has to be
|
195
|
-
rendered.
|
196
|
-
"""
|
197
|
-
return Fraction(
|
198
|
-
0.0
|
199
|
-
if len(self.videos) == 0 else
|
200
|
-
max(
|
201
|
-
video.end
|
202
|
-
for video in self.videos
|
203
|
-
)
|
204
|
-
)
|
205
|
-
|
206
|
-
@property
|
207
|
-
def videos(
|
208
|
-
self
|
209
|
-
) -> list[VideoOnTrack]:
|
210
|
-
"""
|
211
|
-
The list of videos we have in the track
|
212
|
-
but ordered using the 'start' attribute
|
213
|
-
from first to last.
|
214
|
-
"""
|
215
|
-
return sorted(self._videos, key = lambda video: video.start)
|
216
|
-
|
217
|
-
@property
|
218
|
-
def is_muted(
|
219
|
-
self
|
220
|
-
) -> bool:
|
221
|
-
"""
|
222
|
-
Flag to indicate if the track is muted or
|
223
|
-
not. Being muted means that no audio frames
|
224
|
-
will be retured from this track.
|
225
|
-
"""
|
226
|
-
return self._is_muted
|
227
|
-
|
228
|
-
def __init__(
|
229
|
-
self,
|
230
|
-
# TODO: I need the general settings of the
|
231
|
-
# project to be able to make audio also, not
|
232
|
-
# only the empty frames
|
233
|
-
index: int,
|
234
|
-
size: tuple[int, int],
|
235
|
-
fps: float,
|
236
|
-
audio_fps: float,
|
237
|
-
# TODO: Where does it come from (?)
|
238
|
-
audio_samples_per_frame: int,
|
239
|
-
audio_layout: str = 'stereo',
|
240
|
-
audio_format: str = 'fltp'
|
241
|
-
):
|
242
|
-
self._videos: list[VideoOnTrack] = []
|
243
|
-
"""
|
244
|
-
The list of 'VideoOnTrack' instances that
|
245
|
-
must play on this track.
|
246
|
-
"""
|
247
|
-
self._is_muted: bool = False
|
248
|
-
"""
|
249
|
-
Internal flag to indicate if the track is
|
250
|
-
muted or not.
|
251
|
-
"""
|
252
|
-
self.size: tuple[int, int] = size
|
253
|
-
"""
|
254
|
-
The size of the videos of this track.
|
255
|
-
"""
|
256
|
-
self.index: int = index
|
257
|
-
"""
|
258
|
-
The index of the track within the timeline.
|
259
|
-
"""
|
260
|
-
self.fps: float = float(fps)
|
261
|
-
"""
|
262
|
-
The fps of the track, needed to calculate
|
263
|
-
the base t time moments to be precise and
|
264
|
-
to obtain or generate the frames.
|
265
|
-
"""
|
266
|
-
self.audio_fps: float = float(audio_fps)
|
267
|
-
"""
|
268
|
-
The fps of the audio track, needed to
|
269
|
-
generate silent audios for the empty parts.
|
270
|
-
"""
|
271
|
-
self.audio_samples_per_frame: int = audio_samples_per_frame
|
272
|
-
"""
|
273
|
-
The number of samples per audio frame.
|
274
|
-
"""
|
275
|
-
self.audio_layout: str = audio_layout
|
276
|
-
"""
|
277
|
-
The layout of the audio, that can be 'mono'
|
278
|
-
or 'stereo'.
|
279
|
-
"""
|
280
|
-
self.audio_format: str = audio_format
|
281
|
-
"""
|
282
|
-
The format of the audio, that can be 's16',
|
283
|
-
'flt', 'fltp', etc.
|
284
|
-
"""
|
285
|
-
|
286
|
-
def _is_free(
|
287
|
-
self,
|
288
|
-
start: Union[int, float, Fraction],
|
289
|
-
end: Union[int, float, Fraction]
|
290
|
-
) -> bool:
|
291
|
-
"""
|
292
|
-
Check if the time range in between the
|
293
|
-
'start' and 'end' time given is free or
|
294
|
-
there is some video playing at any moment.
|
295
|
-
"""
|
296
|
-
return not any(
|
297
|
-
(
|
298
|
-
video.start < end and
|
299
|
-
video.end > start
|
300
|
-
)
|
301
|
-
for video in self.videos
|
302
|
-
)
|
303
|
-
|
304
|
-
def _get_part_at_t(
|
305
|
-
self,
|
306
|
-
t: Union[int, float, Fraction]
|
307
|
-
) -> _Part:
|
308
|
-
"""
|
309
|
-
Get the part at the given 't' time
|
310
|
-
moment, that will always exist because
|
311
|
-
we have an special non ended last
|
312
|
-
empty part that would be returned if
|
313
|
-
accessing to an empty 't'.
|
314
|
-
"""
|
315
|
-
for part in self.parts:
|
316
|
-
if part.start <= t < part.end:
|
317
|
-
return part
|
318
|
-
|
319
|
-
# TODO: This will only happen if they are
|
320
|
-
# asking for a value greater than the
|
321
|
-
# NON_LIMITED_EMPTY_PART_END...
|
322
|
-
raise Exception('NON_LIMITED_EMPTY_PART_END exceeded.')
|
323
|
-
return None
|
324
|
-
|
325
|
-
def mute(
|
326
|
-
self
|
327
|
-
) -> 'Track':
|
328
|
-
"""
|
329
|
-
Set the track as muted so no audio frame will
|
330
|
-
be played from this track.
|
331
|
-
"""
|
332
|
-
self._is_muted = True
|
333
|
-
|
334
|
-
def unmute(
|
335
|
-
self
|
336
|
-
) -> 'Track':
|
337
|
-
"""
|
338
|
-
Set the track as unmuted so the audio frames
|
339
|
-
will be played as normal.
|
340
|
-
"""
|
341
|
-
self._is_muted = False
|
342
|
-
|
343
|
-
def get_frame_at(
|
344
|
-
self,
|
345
|
-
t: Union[int, float, Fraction]
|
346
|
-
) -> 'VideoFrameWrapped':
|
347
|
-
"""
|
348
|
-
Get the frame that must be displayed at
|
349
|
-
the 't' time moment provided, which is
|
350
|
-
a frame from the video audio that is
|
351
|
-
being played at that time moment.
|
352
|
-
|
353
|
-
Remember, this 't' time moment provided
|
354
|
-
is about the track, and we make the
|
355
|
-
conversion to the actual video 't' to
|
356
|
-
get the frame.
|
357
|
-
"""
|
358
|
-
# TODO: What if the frame, that comes from
|
359
|
-
# a video, doesn't have the expected size (?)
|
360
|
-
return self._get_part_at_t(t).get_frame_at(t)
|
361
|
-
|
362
|
-
# TODO: This is not working well...
|
363
|
-
def get_audio_frames_at(
|
364
|
-
self,
|
365
|
-
t: Union[int, float, Fraction]
|
366
|
-
):
|
367
|
-
"""
|
368
|
-
Get the sequence of audio frames that
|
369
|
-
must be displayed at the 't' time
|
370
|
-
moment provided, which the collection
|
371
|
-
of audio frames corresponding to the
|
372
|
-
video frame that is being played at
|
373
|
-
that time moment.
|
374
|
-
|
375
|
-
Remember, this 't' time moment provided
|
376
|
-
is about the track, and we make the
|
377
|
-
conversion to the actual video 't' to
|
378
|
-
get the frame.
|
379
|
-
|
380
|
-
This is useful when we want to write a
|
381
|
-
video frame with its audio, so we obtain
|
382
|
-
all the audio frames associated to it
|
383
|
-
(remember that a video frame is associated
|
384
|
-
with more than 1 audio frame).
|
385
|
-
"""
|
386
|
-
frames = (
|
387
|
-
generate_silent_frames(
|
388
|
-
fps = self.fps,
|
389
|
-
audio_fps = self.audio_fps,
|
390
|
-
audio_samples_per_frame = self.audio_samples_per_frame,
|
391
|
-
layout = self.audio_layout,
|
392
|
-
format = self.audio_format
|
393
|
-
)
|
394
|
-
if self.is_muted else
|
395
|
-
self._get_part_at_t(t).get_audio_frames_at(t)
|
396
|
-
)
|
397
|
-
|
398
|
-
for frame in frames:
|
399
|
-
yield frame
|
400
|
-
|
401
|
-
def add_video(
|
402
|
-
self,
|
403
|
-
video: Video,
|
404
|
-
t: Union[int, float, Fraction, None] = None
|
405
|
-
) -> 'Track':
|
406
|
-
"""
|
407
|
-
Add the 'video' provided to the track. If
|
408
|
-
a 't' time moment is provided, the video
|
409
|
-
will be added to that time moment if
|
410
|
-
possible. If there is no other video
|
411
|
-
placed in the time gap between the given
|
412
|
-
't' and the provided 'video' duration, it
|
413
|
-
will be added succesfully. In the other
|
414
|
-
case, an exception will be raised.
|
415
|
-
|
416
|
-
If 't' is None, the first available 't'
|
417
|
-
time moment will be used, that will be 0.0
|
418
|
-
if no video, or the end of the last video.
|
419
|
-
"""
|
420
|
-
ParameterValidator.validate_mandatory_instance_of('video', video, Video)
|
421
|
-
ParameterValidator.validate_positive_number('t', t, do_include_zero = True)
|
422
|
-
|
423
|
-
if t is not None:
|
424
|
-
# TODO: We can have many different strategies
|
425
|
-
# that we could define in the '__init__' maybe
|
426
|
-
t: T = T.from_fps(t, self.fps)
|
427
|
-
#if not self._is_free(t.truncated, t.next(1).truncated):
|
428
|
-
if not self._is_free(t.truncated, t.truncated + video.duration):
|
429
|
-
raise Exception('The video cannot be added at the "t" time moment, something blocks it.')
|
430
|
-
t = t.truncated
|
431
|
-
else:
|
432
|
-
t = self.end
|
433
|
-
|
434
|
-
self._videos.append(VideoOnTrack(
|
435
|
-
video,
|
436
|
-
t
|
437
|
-
))
|
438
|
-
|
439
|
-
self._recalculate_parts()
|
440
|
-
|
441
|
-
# TODO: Maybe return the VideoOnTrack instead (?)
|
442
|
-
return self
|
443
|
-
|
444
|
-
def _recalculate_parts(
|
445
|
-
self
|
446
|
-
) -> 'Track':
|
447
|
-
"""
|
448
|
-
Check the track and get all the parts. A
|
449
|
-
part can be empty (non video nor audio on
|
450
|
-
that time period, which means black
|
451
|
-
background and silence audio), or a video
|
452
|
-
with (or without) audio.
|
453
|
-
"""
|
454
|
-
parts = []
|
455
|
-
cursor = 0.0
|
456
|
-
|
457
|
-
for video in self.videos:
|
458
|
-
# Empty space between cursor and start of
|
459
|
-
# the next clip
|
460
|
-
if video.start > cursor:
|
461
|
-
parts.append(_Part(
|
462
|
-
track = self,
|
463
|
-
start = cursor,
|
464
|
-
end = video.start,
|
465
|
-
video = None
|
466
|
-
))
|
467
|
-
|
468
|
-
# The video itself
|
469
|
-
parts.append(_Part(
|
470
|
-
track = self,
|
471
|
-
start = video.start,
|
472
|
-
end = video.end,
|
473
|
-
video = video
|
474
|
-
))
|
475
|
-
|
476
|
-
cursor = video.end
|
477
|
-
|
478
|
-
# Add the non limited last empty part
|
479
|
-
parts.append(_Part(
|
480
|
-
track = self,
|
481
|
-
start = cursor,
|
482
|
-
end = NON_LIMITED_EMPTY_PART_END,
|
483
|
-
video = None
|
484
|
-
))
|
485
|
-
|
486
|
-
self._parts = parts
|
487
|
-
|
488
|
-
return self
|
489
|
-
|
490
|
-
# TODO: Is this method here ok (?)
|
491
|
-
def generate_silent_frames(
|
492
|
-
fps: int,
|
493
|
-
audio_fps: int,
|
494
|
-
audio_samples_per_frame: int,
|
495
|
-
layout: str = 'stereo',
|
496
|
-
format: str = 'fltp'
|
497
|
-
) -> list[AudioFrameWrapped]:
|
498
|
-
"""
|
499
|
-
Get the audio silent frames we need for
|
500
|
-
a video with the given 'fps', 'audio_fps'
|
501
|
-
and 'audio_samples_per_frame', using the
|
502
|
-
also provided 'layout' and 'format' for
|
503
|
-
the audio frames.
|
504
|
-
|
505
|
-
This method is used when we have empty
|
506
|
-
parts on our tracks and we need to
|
507
|
-
provide the frames, that are passed as
|
508
|
-
AudioFrameWrapped instances and tagged as
|
509
|
-
coming from empty parts.
|
510
|
-
"""
|
511
|
-
audio_frame_generator: AudioFrameGenerator = AudioFrameGenerator()
|
512
|
-
|
513
|
-
# Check how many full and partial silent
|
514
|
-
# audio frames we need
|
515
|
-
number_of_frames, number_of_remaining_samples = audio_frames_and_remainder_per_video_frame(
|
516
|
-
video_fps = fps,
|
517
|
-
sample_rate = audio_fps,
|
518
|
-
number_of_samples_per_audio_frame = audio_samples_per_frame
|
519
|
-
)
|
520
|
-
|
521
|
-
# The complete silent frames we need
|
522
|
-
silent_frame = audio_frame_generator.silent(
|
523
|
-
sample_rate = audio_fps,
|
524
|
-
layout = layout,
|
525
|
-
number_of_samples = audio_samples_per_frame,
|
526
|
-
format = format,
|
527
|
-
pts = None,
|
528
|
-
time_base = None
|
529
|
-
)
|
530
|
-
|
531
|
-
frames = (
|
532
|
-
[
|
533
|
-
AudioFrameWrapped(
|
534
|
-
frame = silent_frame,
|
535
|
-
is_from_empty_part = True
|
536
|
-
)
|
537
|
-
] * number_of_frames
|
538
|
-
if number_of_frames > 0 else
|
539
|
-
[]
|
540
|
-
)
|
541
|
-
|
542
|
-
# The remaining partial silent frames we need
|
543
|
-
if number_of_remaining_samples > 0:
|
544
|
-
silent_frame = audio_frame_generator.silent(
|
545
|
-
sample_rate = audio_fps,
|
546
|
-
# TODO: Check where do we get this value from
|
547
|
-
layout = layout,
|
548
|
-
number_of_samples = number_of_remaining_samples,
|
549
|
-
# TODO: Check where do we get this value from
|
550
|
-
format = format,
|
551
|
-
pts = None,
|
552
|
-
time_base = None
|
553
|
-
)
|
554
|
-
|
555
|
-
frames.append(
|
556
|
-
AudioFrameWrapped(
|
557
|
-
frame = silent_frame,
|
558
|
-
is_from_empty_part = True
|
559
|
-
)
|
560
|
-
)
|
561
|
-
|
562
|
-
return frames
|
@@ -1,27 +0,0 @@
|
|
1
|
-
yta_video_opengl/__init__.py,sha256=ycAx_XYMVDfkuObSvtW6irQ0Wo-fgxEz3fjIRMe8PpY,205
|
2
|
-
yta_video_opengl/classes.py,sha256=t5-Tfc7ecvHl8JlVBp_FVzZT6ole6Ly5-FeBBH7wcxo,37742
|
3
|
-
yta_video_opengl/complete/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
yta_video_opengl/complete/frame_combinator.py,sha256=uYg7907knjBlmZUZCCzkxDcj0Nown0muvL5PNVS707A,9413
|
5
|
-
yta_video_opengl/complete/frame_generator.py,sha256=VRcPgpqfxQWMeLzgEJObbM0xu7_85I1y_YyQVhcEswc,7853
|
6
|
-
yta_video_opengl/complete/frame_wrapper.py,sha256=g0aTcUVmF5uQtxs95_XsxlwL0QUj-fNOSRHvK4ENqg4,3347
|
7
|
-
yta_video_opengl/complete/timeline.py,sha256=d6_5Yd5n6TTjwo0ozKNDsd3GAfL12ATx0w-TVkIr0Eo,16767
|
8
|
-
yta_video_opengl/complete/track.py,sha256=NCfNLOjg_7AWX5g5moYgAjmgAJ22Hp92TLa5pdoW6RM,17910
|
9
|
-
yta_video_opengl/complete/video_on_track.py,sha256=laxDvMr1rrmnDfHpk825j42f4pj9I1X8vOFmzwteuM8,4824
|
10
|
-
yta_video_opengl/nodes/__init__.py,sha256=TZ-ZO05PZ0_ABq675E22_PngLWOe-_w5s1cLlV3NbWM,3469
|
11
|
-
yta_video_opengl/nodes/audio/__init__.py,sha256=4nKkC70k1UgLcCSPqFWm3cKdaJM0KUmQTwGWv1xFarQ,2926
|
12
|
-
yta_video_opengl/nodes/video/__init__.py,sha256=gSoaoEmjdQmyRwH18mf5z3NAhap3S0RgbeBbfBXi4jc,132
|
13
|
-
yta_video_opengl/nodes/video/opengl.py,sha256=K2pyCJEd9z4gnZqJetKyGPbtHuBzFsx74ZYyzhSqYPo,8510
|
14
|
-
yta_video_opengl/reader/__init__.py,sha256=kKvOAEeDjIwAaWtpDEQHdAd_Gwk3Ssz2tv6gpNwVkQo,19644
|
15
|
-
yta_video_opengl/reader/cache/__init__.py,sha256=PAfGM2J-8Vv6p6Cd9aAUvyBcw3rjx2gy_2pJO22VtDM,7020
|
16
|
-
yta_video_opengl/reader/cache/audio.py,sha256=cm_1D5f5RnmJgaidA1pnEhTPF8DE0mU2MofmwjU_b5k,6781
|
17
|
-
yta_video_opengl/reader/cache/utils.py,sha256=9aJ6qyUFRvoh2jRbIvtF_-1MOm_sgQtPiy0WXLCZYcA,1402
|
18
|
-
yta_video_opengl/reader/cache/video.py,sha256=3sT9cE0sdTty5AE9yFAPJrJNxCX5vWVATK8OeJInr8I,3496
|
19
|
-
yta_video_opengl/t.py,sha256=xOhT1xBEwChlXf-Tuy-WxA_08iRJWVlnL_Hyzr-9-sk,6633
|
20
|
-
yta_video_opengl/tests.py,sha256=eyFnz7yBDJyIoti-cV7Dz1bMTeF61Z4_JrFkLXuZQl4,28019
|
21
|
-
yta_video_opengl/utils.py,sha256=yUi17EjNR4SVpvdDUwUaKl4mBCb1uyFCSGoIX3Zr2F0,15586
|
22
|
-
yta_video_opengl/video.py,sha256=Fgu_BzuDlMbfl1Hwjk8Yzo3ZxO73wPuyTUjTbf9OSLw,8951
|
23
|
-
yta_video_opengl/writer.py,sha256=QwvjQcEkzn1WAVqVTFiI6tYIXJO67LKKUTJGO_eflFM,8893
|
24
|
-
yta_video_opengl-0.0.19.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
25
|
-
yta_video_opengl-0.0.19.dist-info/METADATA,sha256=wLhgCKzFD4EJiPuuCnNv40dimACB-Zkg8A7otla6ins,714
|
26
|
-
yta_video_opengl-0.0.19.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
27
|
-
yta_video_opengl-0.0.19.dist-info/RECORD,,
|
File without changes
|
File without changes
|