yta-video-opengl 0.0.22__py3-none-any.whl → 0.0.24__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/editor.py +333 -0
- yta_video_opengl/nodes/__init__.py +32 -28
- yta_video_opengl/nodes/audio/__init__.py +164 -55
- yta_video_opengl/nodes/video/__init__.py +27 -1
- yta_video_opengl/nodes/video/{opengl.py → opengl/__init__.py} +8 -4
- yta_video_opengl/nodes/video/opengl/experimental.py +760 -0
- yta_video_opengl/tests.py +236 -358
- yta_video_opengl/utils.py +9 -421
- {yta_video_opengl-0.0.22.dist-info → yta_video_opengl-0.0.24.dist-info}/METADATA +2 -6
- yta_video_opengl-0.0.24.dist-info/RECORD +13 -0
- yta_video_opengl/audio.py +0 -219
- yta_video_opengl/classes.py +0 -1276
- yta_video_opengl/complete/__init__.py +0 -0
- yta_video_opengl/complete/frame_combinator.py +0 -204
- yta_video_opengl/complete/frame_generator.py +0 -319
- yta_video_opengl/complete/frame_wrapper.py +0 -135
- yta_video_opengl/complete/timeline.py +0 -571
- yta_video_opengl/complete/track/__init__.py +0 -500
- yta_video_opengl/complete/track/media/__init__.py +0 -222
- yta_video_opengl/complete/track/parts.py +0 -267
- yta_video_opengl/complete/track/utils.py +0 -78
- yta_video_opengl/media.py +0 -347
- yta_video_opengl/reader/__init__.py +0 -710
- yta_video_opengl/reader/cache/__init__.py +0 -253
- yta_video_opengl/reader/cache/audio.py +0 -195
- yta_video_opengl/reader/cache/utils.py +0 -48
- yta_video_opengl/reader/cache/video.py +0 -113
- yta_video_opengl/t.py +0 -233
- yta_video_opengl/video.py +0 -277
- yta_video_opengl/writer.py +0 -278
- yta_video_opengl-0.0.22.dist-info/RECORD +0 -31
- {yta_video_opengl-0.0.22.dist-info → yta_video_opengl-0.0.24.dist-info}/LICENSE +0 -0
- {yta_video_opengl-0.0.22.dist-info → yta_video_opengl-0.0.24.dist-info}/WHEEL +0 -0
yta_video_opengl/writer.py
DELETED
@@ -1,278 +0,0 @@
|
|
1
|
-
from yta_validation.parameter import ParameterValidator
|
2
|
-
from av.stream import Stream
|
3
|
-
from av.packet import Packet
|
4
|
-
from av.video.frame import VideoFrame
|
5
|
-
from av.audio.frame import AudioFrame
|
6
|
-
from av.video.stream import VideoStream
|
7
|
-
from av.audio.stream import AudioStream
|
8
|
-
from av.container.output import OutputContainer
|
9
|
-
from av import open as av_open
|
10
|
-
from quicktions import Fraction
|
11
|
-
from typing import Union
|
12
|
-
|
13
|
-
|
14
|
-
class VideoWriter:
|
15
|
-
"""
|
16
|
-
Class to write video files with the PyAv (av)
|
17
|
-
library that uses ffmpeg on the background.
|
18
|
-
"""
|
19
|
-
|
20
|
-
def __init__(
|
21
|
-
self,
|
22
|
-
filename: str,
|
23
|
-
):
|
24
|
-
self.filename: str = filename
|
25
|
-
"""
|
26
|
-
The filename we want to use to save the video
|
27
|
-
file.
|
28
|
-
"""
|
29
|
-
# TODO: What about this 'libx264' (?)
|
30
|
-
self.output: OutputContainer = av_open(filename, mode = 'w')
|
31
|
-
"""
|
32
|
-
An OutputContainer to control the writing process.
|
33
|
-
"""
|
34
|
-
self.video_stream: VideoStream = None
|
35
|
-
"""
|
36
|
-
The video stream.
|
37
|
-
"""
|
38
|
-
self.audio_stream: AudioStream = None
|
39
|
-
"""
|
40
|
-
The audio stream.
|
41
|
-
"""
|
42
|
-
|
43
|
-
def set_video_stream(
|
44
|
-
self,
|
45
|
-
codec_name: Union[str, None],
|
46
|
-
# TODO: Maybe force fps to 'int' (?)
|
47
|
-
fps: Union[Fraction, int, float, None],
|
48
|
-
size: Union[tuple[int, int], None] = None,
|
49
|
-
pixel_format: Union[str, None] = None,
|
50
|
-
options: Union[dict[str, str], None] = None
|
51
|
-
) -> 'VideoWriter':
|
52
|
-
"""
|
53
|
-
Set the video stream, that will overwrite any other
|
54
|
-
previous video stream set.
|
55
|
-
"""
|
56
|
-
# TODO: They say that pyav accepts fps as
|
57
|
-
# Fraction...
|
58
|
-
fps = int(fps)
|
59
|
-
|
60
|
-
self.video_stream: VideoStream = self.output.add_stream(
|
61
|
-
# TODO: Maybe 'libx264' as default 'codec_name' (?)
|
62
|
-
codec_name = codec_name,
|
63
|
-
rate = fps,
|
64
|
-
options = options
|
65
|
-
)
|
66
|
-
|
67
|
-
# We need to force this or it will not work
|
68
|
-
self.video_stream.time_base = Fraction(1, fps)
|
69
|
-
|
70
|
-
if size is not None:
|
71
|
-
self.video_stream.width = size[0]
|
72
|
-
self.video_stream.height = size[1]
|
73
|
-
|
74
|
-
if pixel_format is not None:
|
75
|
-
# TODO: Maybe 'yuv420p' as default 'pixel_format' (?)
|
76
|
-
self.video_stream.pix_fmt = pixel_format
|
77
|
-
|
78
|
-
return self
|
79
|
-
|
80
|
-
def set_video_stream_from_template(
|
81
|
-
self,
|
82
|
-
template: Stream
|
83
|
-
) -> 'VideoWriter':
|
84
|
-
"""
|
85
|
-
Set the video stream, that will overwrite any other
|
86
|
-
previous video stream set.
|
87
|
-
|
88
|
-
You can pass the video stream as it was
|
89
|
-
obtained from the reader.
|
90
|
-
"""
|
91
|
-
self.video_stream: VideoStream = self.output.add_stream_from_template(
|
92
|
-
template
|
93
|
-
)
|
94
|
-
|
95
|
-
return self
|
96
|
-
|
97
|
-
def set_audio_stream(
|
98
|
-
self,
|
99
|
-
codec_name: Union[str, None],
|
100
|
-
fps: Union[int, float, Fraction] = 44_100.0
|
101
|
-
# TODO: Add more if needed
|
102
|
-
) -> 'VideoWriter':
|
103
|
-
"""
|
104
|
-
Set the audio stream, that will overwrite any other
|
105
|
-
previous audio stream set.
|
106
|
-
"""
|
107
|
-
# TODO: Check what else we can set
|
108
|
-
self.audio_stream: AudioStream = self.output.add_stream(
|
109
|
-
codec_name = codec_name,
|
110
|
-
rate = int(fps)
|
111
|
-
)
|
112
|
-
|
113
|
-
# audio_stream = output.add_stream("aac", rate=48000) # codec AAC, 48kHz
|
114
|
-
# # Configurar stream
|
115
|
-
# audio_stream.channels = 2 # número de canales
|
116
|
-
# audio_stream.layout = "stereo" # layout
|
117
|
-
# audio_stream.sample_rate = 48000 # sample rate
|
118
|
-
# audio_stream.format = "s16" # formato de las muestras (PCM signed 16-bit)
|
119
|
-
|
120
|
-
# TODO: Add more if needed
|
121
|
-
|
122
|
-
return self
|
123
|
-
|
124
|
-
def set_audio_stream_from_template(
|
125
|
-
self,
|
126
|
-
template: Stream
|
127
|
-
) -> 'VideoWriter':
|
128
|
-
"""
|
129
|
-
Set the audio stream, that will overwrite any other
|
130
|
-
previous audio stream set.
|
131
|
-
|
132
|
-
You can pass the audio stream as it was
|
133
|
-
obtained from the reader.
|
134
|
-
"""
|
135
|
-
self.audio_stream: AudioStream = self.output.add_stream(
|
136
|
-
codec_name = template.codec_context.name,
|
137
|
-
rate = template.codec_context.rate
|
138
|
-
)
|
139
|
-
self.audio_stream.codec_context.format = template.codec_context.format
|
140
|
-
self.audio_stream.codec_context.layout = template.codec_context.layout
|
141
|
-
self.audio_stream.time_base = Fraction(1, template.codec_context.rate)
|
142
|
-
|
143
|
-
return self
|
144
|
-
|
145
|
-
def encode_video_frame(
|
146
|
-
self,
|
147
|
-
frame: Union[VideoFrame, None] = None
|
148
|
-
) -> list[Packet]:
|
149
|
-
"""
|
150
|
-
Get the provided 'frame' but encoded for the
|
151
|
-
video stream, or the remaining packets if the
|
152
|
-
'frame' parameter given is None.
|
153
|
-
|
154
|
-
The `.encode()` method with a `None` parameter
|
155
|
-
will tell the encoder that we will not send
|
156
|
-
more frames to encode so the remaining ones can
|
157
|
-
be processed, emptying the buffers.
|
158
|
-
"""
|
159
|
-
ParameterValidator.validate_instance_of('frame', frame, VideoFrame)
|
160
|
-
|
161
|
-
return self.video_stream.encode(frame)
|
162
|
-
|
163
|
-
def encode_audio_frame(
|
164
|
-
self,
|
165
|
-
frame: Union[AudioFrame, None] = None
|
166
|
-
) -> list[Packet]:
|
167
|
-
"""
|
168
|
-
Get the provided 'frame' but encoded for the
|
169
|
-
audio stream, or the remaining packets if the
|
170
|
-
'frame' parameter given is None.
|
171
|
-
|
172
|
-
The `.encode()` method with a `None` parameter
|
173
|
-
will tell the encoder that we will not send
|
174
|
-
more frames to encode so the remaining ones can
|
175
|
-
be processed, emptying the buffers.
|
176
|
-
"""
|
177
|
-
ParameterValidator.validate_instance_of('frame', frame, AudioFrame)
|
178
|
-
|
179
|
-
return self.audio_stream.encode(frame)
|
180
|
-
|
181
|
-
def mux(
|
182
|
-
self,
|
183
|
-
packet: Packet
|
184
|
-
) -> 'VideoWriter':
|
185
|
-
"""
|
186
|
-
Add the provided video or audio 'packet'
|
187
|
-
to the mux.
|
188
|
-
|
189
|
-
Packets with a size of 0 will be discarded,
|
190
|
-
as they are indicators of the end.
|
191
|
-
"""
|
192
|
-
ParameterValidator.validate_mandatory_instance_of('packet', packet, Packet)
|
193
|
-
|
194
|
-
# We are ignoring empty packets because they
|
195
|
-
# are used to indicate the end or things like
|
196
|
-
# that, not actual data... But maybe we are
|
197
|
-
# wrong...
|
198
|
-
if packet.size > 0:
|
199
|
-
try:
|
200
|
-
self.output.mux(packet)
|
201
|
-
except Exception as e:
|
202
|
-
# TODO: What strategy should we adopt with
|
203
|
-
# the packets that cannot be handled
|
204
|
-
# properly (?)
|
205
|
-
print('Invalid packet')
|
206
|
-
print(packet)
|
207
|
-
pass
|
208
|
-
|
209
|
-
return self
|
210
|
-
|
211
|
-
# TODO: This below is to test fails
|
212
|
-
if (
|
213
|
-
packet.size > 0 and
|
214
|
-
# This is a new special case
|
215
|
-
packet.dts % 1024 == 0 and
|
216
|
-
packet.dts > 0
|
217
|
-
):
|
218
|
-
# av.Packet of #0, dts=-2, pts=0; 1225 bytes at 0x1ef2d8e0680>
|
219
|
-
# av.Packet of #0, dts=0, pts=2; 110 bytes at 0x1e1feb8c6d0>
|
220
|
-
# av.Packet of #0, dts=1, pts=1; 182 bytes at 0x153f6b3b400>
|
221
|
-
# are failing
|
222
|
-
print(packet)
|
223
|
-
print(packet.stream.type)
|
224
|
-
self.output.mux(packet)
|
225
|
-
|
226
|
-
return self
|
227
|
-
|
228
|
-
def mux_video_frame(
|
229
|
-
self,
|
230
|
-
frame: Union[VideoFrame, None] = None
|
231
|
-
) -> 'VideoWriter':
|
232
|
-
"""
|
233
|
-
Encode the provided 'frame' and add the
|
234
|
-
obtained packets to the multiplexing (mux)
|
235
|
-
process.
|
236
|
-
|
237
|
-
If `None` provided, it will obtain the
|
238
|
-
remaining packets and add those ones to
|
239
|
-
the multiplexing (mux) process.
|
240
|
-
|
241
|
-
Packets with a size of 0 will be discarded,
|
242
|
-
as they are indicators of the end.
|
243
|
-
"""
|
244
|
-
ParameterValidator.validate_instance_of('frame', frame, VideoFrame)
|
245
|
-
|
246
|
-
for packet in self.encode_video_frame(frame):
|
247
|
-
self.mux(packet)
|
248
|
-
|
249
|
-
return self
|
250
|
-
|
251
|
-
def mux_audio_frame(
|
252
|
-
self,
|
253
|
-
frame: Union[AudioFrame, None] = None
|
254
|
-
) -> 'VideoWriter':
|
255
|
-
"""
|
256
|
-
Encode the provided 'frame' and add the
|
257
|
-
obtained packets to the multiplexing (mux)
|
258
|
-
process.
|
259
|
-
|
260
|
-
If `None` provided, it will obtain the
|
261
|
-
remaining packets and add those ones to
|
262
|
-
the multiplexing (mux) process.
|
263
|
-
|
264
|
-
Packets with a size of 0 will be discarded,
|
265
|
-
as they are indicators of the end.
|
266
|
-
"""
|
267
|
-
ParameterValidator.validate_instance_of('frame', frame, AudioFrame)
|
268
|
-
|
269
|
-
for packet in self.encode_audio_frame(frame):
|
270
|
-
self.mux(packet)
|
271
|
-
|
272
|
-
return self
|
273
|
-
|
274
|
-
|
275
|
-
"""
|
276
|
-
# TODO: Check 'https://www.youtube.com/watch?v=OlNWCpFdVMA'
|
277
|
-
# for ffmpeg with mp3 access
|
278
|
-
"""
|
@@ -1,31 +0,0 @@
|
|
1
|
-
yta_video_opengl/__init__.py,sha256=ycAx_XYMVDfkuObSvtW6irQ0Wo-fgxEz3fjIRMe8PpY,205
|
2
|
-
yta_video_opengl/audio.py,sha256=BWXa7nfFFabRe4e6TuGDTjMyevsV9R7BLOWEUXwpLns,6947
|
3
|
-
yta_video_opengl/classes.py,sha256=t5-Tfc7ecvHl8JlVBp_FVzZT6ole6Ly5-FeBBH7wcxo,37742
|
4
|
-
yta_video_opengl/complete/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
yta_video_opengl/complete/frame_combinator.py,sha256=FqWIZECYRS1V8VU8ZkVlzWvDYofE0p44zjVNlx_i2tE,6466
|
6
|
-
yta_video_opengl/complete/frame_generator.py,sha256=nLT39owK_d4DaGQTJ3JtNMaYvRO9zl8tSmjneTzRSPA,9073
|
7
|
-
yta_video_opengl/complete/frame_wrapper.py,sha256=As5e8Yq9yKd9arJFczzTkV7FLL-h5ub1kEUBNzxuMf8,3664
|
8
|
-
yta_video_opengl/complete/timeline.py,sha256=Sms7lJarEU3LxqYeEN7cs1zR8WYfKHaqOowiQ77-7sY,18372
|
9
|
-
yta_video_opengl/complete/track/__init__.py,sha256=a_iXuVvd_LvvQ7wETTUJTeAQi4yau7eVwHz4aBmlJKA,14527
|
10
|
-
yta_video_opengl/complete/track/media/__init__.py,sha256=raIbTh5kreFJcnrtxUE1s8Un0N614KzWDWUkS3-OglY,6368
|
11
|
-
yta_video_opengl/complete/track/parts.py,sha256=6yTLCBd4xz76VTrpZyp7Kbwo6Ok0OmbLJUNwSAoRJkc,8829
|
12
|
-
yta_video_opengl/complete/track/utils.py,sha256=nKJT0GqfSnUoATPGCAXinIM9skhtH6v9_MsBZlHYNeg,2486
|
13
|
-
yta_video_opengl/media.py,sha256=vw1W63i3FQ7FvXXwMOGB8GebL-vzXmbdLoJKV_xINZs,9594
|
14
|
-
yta_video_opengl/nodes/__init__.py,sha256=TZ-ZO05PZ0_ABq675E22_PngLWOe-_w5s1cLlV3NbWM,3469
|
15
|
-
yta_video_opengl/nodes/audio/__init__.py,sha256=4nKkC70k1UgLcCSPqFWm3cKdaJM0KUmQTwGWv1xFarQ,2926
|
16
|
-
yta_video_opengl/nodes/video/__init__.py,sha256=gSoaoEmjdQmyRwH18mf5z3NAhap3S0RgbeBbfBXi4jc,132
|
17
|
-
yta_video_opengl/nodes/video/opengl.py,sha256=K2pyCJEd9z4gnZqJetKyGPbtHuBzFsx74ZYyzhSqYPo,8510
|
18
|
-
yta_video_opengl/reader/__init__.py,sha256=fZVb4mwVz9Bb5pawuFXIS-LGPXOLk-9xznAGMoivqTA,19216
|
19
|
-
yta_video_opengl/reader/cache/__init__.py,sha256=ZGjHCknb7q1Mc8hiDD50m8yHAw8MSd2PY6GVVByDsq4,7126
|
20
|
-
yta_video_opengl/reader/cache/audio.py,sha256=cm_1D5f5RnmJgaidA1pnEhTPF8DE0mU2MofmwjU_b5k,6781
|
21
|
-
yta_video_opengl/reader/cache/utils.py,sha256=a3aeiQ8LJpAFvPeoGEk1cn88NZ6c4Eveka7bTP-58VY,1409
|
22
|
-
yta_video_opengl/reader/cache/video.py,sha256=3sT9cE0sdTty5AE9yFAPJrJNxCX5vWVATK8OeJInr8I,3496
|
23
|
-
yta_video_opengl/t.py,sha256=xOhT1xBEwChlXf-Tuy-WxA_08iRJWVlnL_Hyzr-9-sk,6633
|
24
|
-
yta_video_opengl/tests.py,sha256=mRU1PtG8q5_bWv_YJxGAwxlRd5zwrl4fspGsnlmLYzU,29849
|
25
|
-
yta_video_opengl/utils.py,sha256=yUi17EjNR4SVpvdDUwUaKl4mBCb1uyFCSGoIX3Zr2F0,15586
|
26
|
-
yta_video_opengl/video.py,sha256=Og_SOJwb8Dzbx8c-P75cjT9O8QgITru-4LD5wHC_JDM,8785
|
27
|
-
yta_video_opengl/writer.py,sha256=QwvjQcEkzn1WAVqVTFiI6tYIXJO67LKKUTJGO_eflFM,8893
|
28
|
-
yta_video_opengl-0.0.22.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
29
|
-
yta_video_opengl-0.0.22.dist-info/METADATA,sha256=6mKsXJtXDo2kVaQ2njwMZmN0dPzakFm_LJHjOiK7-BI,754
|
30
|
-
yta_video_opengl-0.0.22.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
31
|
-
yta_video_opengl-0.0.22.dist-info/RECORD,,
|
File without changes
|
File without changes
|