yta-video-opengl 0.0.13__py3-none-any.whl → 0.0.15__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.
@@ -0,0 +1,110 @@
1
+
2
+ from yta_video_opengl.reader.cache import FrameCache
3
+ from yta_video_opengl.t import T
4
+ from yta_validation.parameter import ParameterValidator
5
+ from av.container import InputContainer
6
+ from av.video.stream import VideoStream
7
+ from av.video.frame import VideoFrame
8
+ from quicktions import Fraction
9
+ from typing import Union
10
+
11
+
12
+ class VideoFrameCache(FrameCache):
13
+ """
14
+ Cache for the video frames.
15
+ """
16
+
17
+ @property
18
+ def fps(
19
+ self
20
+ ) -> Union[Fraction, None]:
21
+ """
22
+ The frames per second.
23
+ """
24
+ return self.stream.average_rate
25
+
26
+ @property
27
+ def frame_duration(
28
+ self
29
+ ) -> int:
30
+ """
31
+ The frame duration in ticks, which is the
32
+ minimum amount of time, 1 / time_base.
33
+ """
34
+ return self.stream.duration / self.stream.frames
35
+
36
+ def __init__(
37
+ self,
38
+ container: InputContainer,
39
+ stream: VideoStream,
40
+ size: Union[int, None] = None
41
+ ):
42
+ ParameterValidator.validate_mandatory_instance_of('stream', stream, VideoStream)
43
+
44
+ super().__init__(container, stream, size)
45
+
46
+ def get_frame(
47
+ self,
48
+ t: Union[int, float, Fraction]
49
+ ) -> VideoFrame:
50
+ """
51
+ Get the video frame that is in the 't'
52
+ time moment provided.
53
+ """
54
+ t: T = T.from_fps(t, self.fps)
55
+ for frame in self.get_frames(t.truncated, t.next(1).truncated):
56
+ return frame
57
+
58
+ def get_frames(
59
+ self,
60
+ start: Union[int, float, Fraction],
61
+ end: Union[int, float, Fraction]
62
+ ):
63
+ """
64
+ Get all the frames in the range between
65
+ the provided 'start' and 'end' time in
66
+ seconds.
67
+
68
+ This method is an iterator that yields
69
+ the frame, its t and its index.
70
+ """
71
+ # TODO: Validate 'start' and 'end' are mandatory
72
+ # positive numbers
73
+ # Make sure the 'start' and 'end' time moments
74
+ # provided are truncated values based on the
75
+ # stream time base
76
+ start = T(start, self.time_base).truncated
77
+ end = T(end, self.time_base).truncated
78
+
79
+ if end <= start:
80
+ raise Exception(f'The time range start:{str(float(start))} - end:{str(float(end))}) is not valid.')
81
+
82
+ key_frame_pts = self._get_nearest_keyframe_pts(start / self.time_base)
83
+
84
+ if (
85
+ self._last_packet_accessed is None or
86
+ self._last_packet_accessed.pts != key_frame_pts
87
+ ):
88
+ self._seek(key_frame_pts)
89
+
90
+ for packet in self.container.demux(self.stream):
91
+ if packet.pts is None:
92
+ continue
93
+
94
+ self._last_packet_accessed = packet
95
+
96
+ for frame in packet.decode():
97
+ if frame.pts is None:
98
+ continue
99
+
100
+ # We store all the frames in cache
101
+ self._store_frame_in_cache(frame)
102
+
103
+ current_frame_time = frame.pts * self.time_base
104
+
105
+ # We want the range [start, end)
106
+ if start <= current_frame_time < end:
107
+ yield frame
108
+
109
+ if current_frame_time >= end:
110
+ break
yta_video_opengl/t.py CHANGED
@@ -1,3 +1,14 @@
1
+ """
2
+ This is an example of what a video has:
3
+ - fps = 60
4
+ - time_base = 1 / 15360
5
+ - tick = fps * time_base = 256
6
+
7
+ So, the first pts is 0 and the second
8
+ one is 256. The frame 16 will be 3840,
9
+ that is 256 * 15 (because first index
10
+ is 0).
11
+ """
1
12
  from yta_validation.parameter import ParameterValidator
2
13
  from yta_validation import PythonValidator
3
14
  from yta_validation.number import NumberValidator
@@ -36,7 +47,7 @@ class T:
36
47
  The 't' but as a Fraction that is multiple
37
48
  of the given 'time_base' and rounded (the
38
49
  value could be the same as truncated if it
39
- is closer to the previou value).
50
+ is closer to the previous value).
40
51
  """
41
52
  return round_t(self._t, self.time_base, do_truncate = False)
42
53
 
@@ -96,20 +107,57 @@ class T:
96
107
  """
97
108
  return T(self.truncated + n * self.time_base, self.time_base)
98
109
 
99
- # TODO: Maybe its better to make the '__init__'
100
- # receive the fps and create the 'from_time_base'
101
- # because I think we will provide the fps or the
102
- # sample rate more often
110
+ def previous(
111
+ self,
112
+ n: int = 1
113
+ ) -> 'T':
114
+ """
115
+ Get the value that is 'n' times before the
116
+ 'truncated' property of this instance.
117
+
118
+ Useful when you need the previous value to
119
+ check if the current is the next one or
120
+ similar.
121
+
122
+ Be careful, if the 'truncated' value is 0
123
+ this will give you an unexpected negative
124
+ value.
125
+ """
126
+ return T(self.truncated - n * self.time_base, self.time_base)
127
+
103
128
  @staticmethod
104
129
  def from_fps(
105
130
  t: Union[int, float, Fraction],
106
131
  fps: Union[int, float, Fraction]
107
- ):
132
+ ) -> 'T':
108
133
  """
109
134
  Get the instance but providing the 'fps'
110
- (or sample rate) value directly.
135
+ (or sample rate) value directly, that will
136
+ be turned into a time base.
111
137
  """
112
138
  return T(t, fps_to_time_base(fps))
139
+
140
+ @staticmethod
141
+ def from_pts(
142
+ pts: int,
143
+ time_base: Fraction
144
+ ) -> 'T':
145
+ """
146
+ Get the instance but providing the 'pts'
147
+ and the 'time_base'.
148
+ """
149
+ return T(pts * time_base, time_base)
150
+
151
+
152
+ # TODO: Careful with this below
153
+ """
154
+ To obtain the pts step, or frame duration in
155
+ ticks, you need to apply 2 formulas that are
156
+ different according to if the frame is video
157
+ or audio:
158
+ - Audio: .samples
159
+ - Video: int(round((1 / .fps) / .time_base))
160
+ """
113
161
 
114
162
  def get_ts(
115
163
  start: Union[int, float, Fraction],
yta_video_opengl/video.py CHANGED
@@ -182,17 +182,22 @@ class Video:
182
182
  Get the video frame with the given 't' time
183
183
  moment, using the video cache system.
184
184
  """
185
- return self.reader.video_cache.get_frame_from_t(self._get_real_t(t))
186
-
185
+ return self.reader.video_cache.get_frame(self._get_real_t(t))
186
+
187
187
  def get_audio_frame_from_t(
188
188
  self,
189
189
  t: Union[int, float, Fraction]
190
190
  ) -> 'AudioFrame':
191
191
  """
192
192
  Get the audio frame with the given 't' time
193
- moment, using the audio cache system.
193
+ moment, using the audio cache system. This
194
+ method is useful when we need to combine
195
+ many different frames so we can obtain them
196
+ one by one.
197
+
198
+ TODO: Is this actually necessary (?)
194
199
  """
195
- return self.reader.audio_cache.get_frame_from_t(self._get_real_t(t))
200
+ return self.reader.get_audio_frame_from_t(self._get_real_t(t))
196
201
 
197
202
  def get_audio_frames_from_t(
198
203
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: yta-video-opengl
3
- Version: 0.0.13
3
+ Version: 0.0.15
4
4
  Summary: Youtube Autonomous Video OpenGL Module
5
5
  Author: danialcala94
6
6
  Author-email: danielalcalavalera@gmail.com
@@ -0,0 +1,24 @@
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/timeline.py,sha256=y2IPLRlk3ix14zflCsLKWajbqtf6Y8ceStpLs69OqHY,9323
5
+ yta_video_opengl/complete/track.py,sha256=hI1b4EmbXMPB_COxNUs1VlHVPtbiaIgvt37RY-YUz7g,13623
6
+ yta_video_opengl/complete/video_on_track.py,sha256=KROAI0bndnfcvKlHGsSEyWg9o1xozW0PI_Rhqp0r9kw,4844
7
+ yta_video_opengl/nodes/__init__.py,sha256=TZ-ZO05PZ0_ABq675E22_PngLWOe-_w5s1cLlV3NbWM,3469
8
+ yta_video_opengl/nodes/audio/__init__.py,sha256=4nKkC70k1UgLcCSPqFWm3cKdaJM0KUmQTwGWv1xFarQ,2926
9
+ yta_video_opengl/nodes/video/__init__.py,sha256=gSoaoEmjdQmyRwH18mf5z3NAhap3S0RgbeBbfBXi4jc,132
10
+ yta_video_opengl/nodes/video/opengl.py,sha256=K2pyCJEd9z4gnZqJetKyGPbtHuBzFsx74ZYyzhSqYPo,8510
11
+ yta_video_opengl/reader/__init__.py,sha256=kKvOAEeDjIwAaWtpDEQHdAd_Gwk3Ssz2tv6gpNwVkQo,19644
12
+ yta_video_opengl/reader/cache/__init__.py,sha256=PAfGM2J-8Vv6p6Cd9aAUvyBcw3rjx2gy_2pJO22VtDM,7020
13
+ yta_video_opengl/reader/cache/audio.py,sha256=cm_1D5f5RnmJgaidA1pnEhTPF8DE0mU2MofmwjU_b5k,6781
14
+ yta_video_opengl/reader/cache/utils.py,sha256=9aJ6qyUFRvoh2jRbIvtF_-1MOm_sgQtPiy0WXLCZYcA,1402
15
+ yta_video_opengl/reader/cache/video.py,sha256=CSVgb3Sjqzk22sQkukoakVzms-wwZpXOT61Y6tirhjg,3292
16
+ yta_video_opengl/t.py,sha256=xOhT1xBEwChlXf-Tuy-WxA_08iRJWVlnL_Hyzr-9-sk,6633
17
+ yta_video_opengl/tests.py,sha256=EdTyYtTUd_mj6geWnrvnF-wZSHCKKvhYgiLclkV73O0,26576
18
+ yta_video_opengl/utils.py,sha256=yUi17EjNR4SVpvdDUwUaKl4mBCb1uyFCSGoIX3Zr2F0,15586
19
+ yta_video_opengl/video.py,sha256=JPIWDQcYlLi8eT2LOFQtS1jVu5xVmW4bz1VMtP0gMeA,8626
20
+ yta_video_opengl/writer.py,sha256=QwvjQcEkzn1WAVqVTFiI6tYIXJO67LKKUTJGO_eflFM,8893
21
+ yta_video_opengl-0.0.15.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
22
+ yta_video_opengl-0.0.15.dist-info/METADATA,sha256=nDTKhQqRMXHzjg8kQWvRWKfvDsP7rvsAhpcl8qayl-8,714
23
+ yta_video_opengl-0.0.15.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
24
+ yta_video_opengl-0.0.15.dist-info/RECORD,,