vidformer 0.5.4__py3-none-any.whl → 0.6.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.
- vidformer/__init__.py +5 -0
- vidformer/cv2/__init__.py +1 -0
- vidformer/cv2/vf_cv2.py +428 -0
- vidformer.py → vidformer/vf.py +27 -10
- vidformer-0.6.1.dist-info/METADATA +36 -0
- vidformer-0.6.1.dist-info/RECORD +7 -0
- vidformer-0.5.4.dist-info/METADATA +0 -24
- vidformer-0.5.4.dist-info/RECORD +0 -4
- {vidformer-0.5.4.dist-info → vidformer-0.6.1.dist-info}/WHEEL +0 -0
vidformer/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
from .vf_cv2 import *
|
vidformer/cv2/vf_cv2.py
ADDED
@@ -0,0 +1,428 @@
|
|
1
|
+
from .. import vf
|
2
|
+
|
3
|
+
try:
|
4
|
+
import cv2 as _opencv2
|
5
|
+
except:
|
6
|
+
_opencv2 = None
|
7
|
+
|
8
|
+
import uuid
|
9
|
+
from fractions import Fraction
|
10
|
+
from bisect import bisect_right
|
11
|
+
|
12
|
+
CAP_PROP_POS_MSEC = 0
|
13
|
+
CAP_PROP_POS_FRAMES = 1
|
14
|
+
CAP_PROP_FRAME_WIDTH = 3
|
15
|
+
CAP_PROP_FRAME_HEIGHT = 4
|
16
|
+
CAP_PROP_FPS = 5
|
17
|
+
|
18
|
+
FONT_HERSHEY_SIMPLEX = 0
|
19
|
+
FONT_HERSHEY_PLAIN = 1
|
20
|
+
FONT_HERSHEY_DUPLEX = 2
|
21
|
+
FONT_HERSHEY_COMPLEX = 3
|
22
|
+
FONT_HERSHEY_TRIPLEX = 4
|
23
|
+
FONT_HERSHEY_COMPLEX_SMALL = 5
|
24
|
+
FONT_HERSHEY_SCRIPT_SIMPLEX = 6
|
25
|
+
FONT_HERSHEY_SCRIPT_COMPLEX = 7
|
26
|
+
FONT_ITALIC = 16
|
27
|
+
|
28
|
+
FILLED = -1
|
29
|
+
LINE_4 = 4
|
30
|
+
LINE_8 = 8
|
31
|
+
LINE_AA = 16
|
32
|
+
|
33
|
+
_filter_scale = vf.Filter("Scale")
|
34
|
+
_filter_rectangle = vf.Filter("cv2.rectangle")
|
35
|
+
_filter_putText = vf.Filter("cv2.putText")
|
36
|
+
_filter_arrowedLine = vf.Filter("cv2.arrowedLine")
|
37
|
+
_filter_line = vf.Filter("cv2.line")
|
38
|
+
_filter_circle = vf.Filter("cv2.circle")
|
39
|
+
_filter_addWeighted = vf.Filter("cv2.addWeighted")
|
40
|
+
|
41
|
+
|
42
|
+
def _ts_to_fps(timestamps):
|
43
|
+
return int(1 / (timestamps[1] - timestamps[0])) # TODO: Fix for non-integer fps
|
44
|
+
|
45
|
+
|
46
|
+
def _fps_to_ts(fps, n_frames):
|
47
|
+
assert type(fps) == int
|
48
|
+
return [Fraction(i, fps) for i in range(n_frames)]
|
49
|
+
|
50
|
+
|
51
|
+
_global_cv2_server = None
|
52
|
+
|
53
|
+
|
54
|
+
def _server():
|
55
|
+
global _global_cv2_server
|
56
|
+
if _global_cv2_server is None:
|
57
|
+
_global_cv2_server = vf.YrdenServer()
|
58
|
+
return _global_cv2_server
|
59
|
+
|
60
|
+
|
61
|
+
def set_cv2_server(server):
|
62
|
+
"""Set the server to use for the cv2 frontend."""
|
63
|
+
global _global_cv2_server
|
64
|
+
assert isinstance(server, vf.YrdenServer)
|
65
|
+
_global_cv2_server = server
|
66
|
+
|
67
|
+
|
68
|
+
class _Frame:
|
69
|
+
def __init__(self, f):
|
70
|
+
self._f = f
|
71
|
+
|
72
|
+
# denotes that the frame has not yet been modified
|
73
|
+
# when a frame is modified, it is converted to rgb24 first
|
74
|
+
self._modified = False
|
75
|
+
|
76
|
+
def _mut(self):
|
77
|
+
self._modified = True
|
78
|
+
self._f = _filter_scale(self._f, pix_fmt="rgb24")
|
79
|
+
|
80
|
+
|
81
|
+
class VideoCapture:
|
82
|
+
def __init__(self, path):
|
83
|
+
self._path = path
|
84
|
+
server = _server()
|
85
|
+
self._source = vf.Source(server, str(uuid.uuid4()), path, 0)
|
86
|
+
self._next_frame_idx = 0
|
87
|
+
|
88
|
+
def isOpened(self):
|
89
|
+
return True
|
90
|
+
|
91
|
+
def get(self, prop):
|
92
|
+
if prop == CAP_PROP_FPS:
|
93
|
+
return _ts_to_fps(self._source.ts())
|
94
|
+
elif prop == CAP_PROP_FRAME_WIDTH:
|
95
|
+
return self._source.fmt()["width"]
|
96
|
+
elif prop == CAP_PROP_FRAME_HEIGHT:
|
97
|
+
return self._source.fmt()["height"]
|
98
|
+
|
99
|
+
raise Exception(f"Unknown property {prop}")
|
100
|
+
|
101
|
+
def set(self, prop, value):
|
102
|
+
if prop == CAP_PROP_POS_FRAMES:
|
103
|
+
assert value >= 0 and value < len(self._source.ts())
|
104
|
+
self._next_frame_idx = value
|
105
|
+
elif prop == CAP_PROP_POS_MSEC:
|
106
|
+
t = Fraction(value, 1000)
|
107
|
+
ts = self._source.ts()
|
108
|
+
next_frame_idx = bisect_right(ts, t)
|
109
|
+
self._next_frame_idx = next_frame_idx
|
110
|
+
else:
|
111
|
+
raise Exception(f"Unsupported property {prop}")
|
112
|
+
|
113
|
+
def read(self):
|
114
|
+
if self._next_frame_idx >= len(self._source.ts()):
|
115
|
+
return False, None
|
116
|
+
frame = self._source.iloc[self._next_frame_idx]
|
117
|
+
self._next_frame_idx += 1
|
118
|
+
frame = _Frame(frame)
|
119
|
+
return True, frame
|
120
|
+
|
121
|
+
def release(self):
|
122
|
+
pass
|
123
|
+
|
124
|
+
|
125
|
+
class VideoWriter:
|
126
|
+
def __init__(self, path, fourcc, fps, size):
|
127
|
+
assert isinstance(fourcc, VideoWriter_fourcc)
|
128
|
+
self._path = path
|
129
|
+
self._fourcc = fourcc
|
130
|
+
self._fps = fps
|
131
|
+
self._size = size
|
132
|
+
|
133
|
+
self._frames = []
|
134
|
+
self._pix_fmt = "yuv420p"
|
135
|
+
|
136
|
+
def write(self, frame):
|
137
|
+
if not isinstance(frame, _Frame):
|
138
|
+
raise Exception("frame must be a _Frame object")
|
139
|
+
if frame._modified:
|
140
|
+
f_obj = _filter_scale(frame._f, pix_fmt=self._pix_fmt)
|
141
|
+
self._frames.append(f_obj)
|
142
|
+
else:
|
143
|
+
self._frames.append(frame._f)
|
144
|
+
|
145
|
+
def release(self):
|
146
|
+
spec = self.vf_spec()
|
147
|
+
server = _server()
|
148
|
+
spec.save(server, self._path)
|
149
|
+
|
150
|
+
def vf_spec(self):
|
151
|
+
fmt = {
|
152
|
+
"width": self._size[0],
|
153
|
+
"height": self._size[1],
|
154
|
+
"pix_fmt": self._pix_fmt,
|
155
|
+
}
|
156
|
+
domain = _fps_to_ts(self._fps, len(self._frames))
|
157
|
+
spec = vf.Spec(domain, lambda t, i: self._frames[i], fmt)
|
158
|
+
return spec
|
159
|
+
|
160
|
+
|
161
|
+
class VideoWriter_fourcc:
|
162
|
+
def __init__(self, *args):
|
163
|
+
self._args = args
|
164
|
+
|
165
|
+
|
166
|
+
def rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None):
|
167
|
+
"""
|
168
|
+
cv.rectangle( img, pt1, pt2, color[, thickness[, lineType[, shift]]] )
|
169
|
+
"""
|
170
|
+
|
171
|
+
assert isinstance(img, _Frame)
|
172
|
+
img._mut()
|
173
|
+
|
174
|
+
assert len(pt1) == 2
|
175
|
+
assert len(pt2) == 2
|
176
|
+
assert all(isinstance(x, int) for x in pt1)
|
177
|
+
assert all(isinstance(x, int) for x in pt2)
|
178
|
+
|
179
|
+
assert len(color) == 3 or len(color) == 4
|
180
|
+
color = [float(x) for x in color]
|
181
|
+
if len(color) == 3:
|
182
|
+
color.append(255.0)
|
183
|
+
|
184
|
+
args = []
|
185
|
+
if thickness is not None:
|
186
|
+
assert isinstance(thickness, int)
|
187
|
+
args.append(thickness)
|
188
|
+
if lineType is not None:
|
189
|
+
assert isinstance(lineType, int)
|
190
|
+
assert thickness is not None
|
191
|
+
args.append(lineType)
|
192
|
+
if shift is not None:
|
193
|
+
assert isinstance(shift, int)
|
194
|
+
assert shift is not None
|
195
|
+
args.append(shift)
|
196
|
+
|
197
|
+
img._f = _filter_rectangle(img._f, pt1, pt2, color, *args)
|
198
|
+
|
199
|
+
|
200
|
+
def putText(
|
201
|
+
img,
|
202
|
+
text,
|
203
|
+
org,
|
204
|
+
fontFace,
|
205
|
+
fontScale,
|
206
|
+
color,
|
207
|
+
thickness=None,
|
208
|
+
lineType=None,
|
209
|
+
bottomLeftOrigin=None,
|
210
|
+
):
|
211
|
+
"""
|
212
|
+
cv.putText( img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]] )
|
213
|
+
"""
|
214
|
+
|
215
|
+
assert isinstance(img, _Frame)
|
216
|
+
img._mut()
|
217
|
+
|
218
|
+
assert isinstance(text, str)
|
219
|
+
|
220
|
+
assert len(org) == 2
|
221
|
+
assert all(isinstance(x, int) for x in org)
|
222
|
+
|
223
|
+
assert isinstance(fontFace, int)
|
224
|
+
assert isinstance(fontScale, float) or isinstance(fontScale, int)
|
225
|
+
fontScale = float(fontScale)
|
226
|
+
|
227
|
+
assert len(color) == 3 or len(color) == 4
|
228
|
+
color = [float(x) for x in color]
|
229
|
+
if len(color) == 3:
|
230
|
+
color.append(255.0)
|
231
|
+
|
232
|
+
args = []
|
233
|
+
if thickness is not None:
|
234
|
+
assert isinstance(thickness, int)
|
235
|
+
args.append(thickness)
|
236
|
+
if lineType is not None:
|
237
|
+
assert isinstance(lineType, int)
|
238
|
+
assert thickness is not None
|
239
|
+
args.append(lineType)
|
240
|
+
if bottomLeftOrigin is not None:
|
241
|
+
assert isinstance(bottomLeftOrigin, bool)
|
242
|
+
assert lineType is not None
|
243
|
+
args.append(bottomLeftOrigin)
|
244
|
+
|
245
|
+
img._f = _filter_putText(img._f, text, org, fontFace, fontScale, color, *args)
|
246
|
+
|
247
|
+
|
248
|
+
def arrowedLine(
|
249
|
+
img, pt1, pt2, color, thickness=None, line_type=None, shift=None, tipLength=None
|
250
|
+
):
|
251
|
+
"""
|
252
|
+
cv.arrowedLine( img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]] )
|
253
|
+
"""
|
254
|
+
assert isinstance(img, _Frame)
|
255
|
+
img._mut()
|
256
|
+
|
257
|
+
assert len(pt1) == 2
|
258
|
+
assert len(pt2) == 2
|
259
|
+
assert all(isinstance(x, int) for x in pt1)
|
260
|
+
assert all(isinstance(x, int) for x in pt2)
|
261
|
+
|
262
|
+
assert len(color) == 3 or len(color) == 4
|
263
|
+
color = [float(x) for x in color]
|
264
|
+
if len(color) == 3:
|
265
|
+
color.append(255.0)
|
266
|
+
|
267
|
+
args = []
|
268
|
+
if thickness is not None:
|
269
|
+
assert isinstance(thickness, int)
|
270
|
+
args.append(thickness)
|
271
|
+
if line_type is not None:
|
272
|
+
assert isinstance(line_type, int)
|
273
|
+
assert thickness is not None
|
274
|
+
args.append(line_type)
|
275
|
+
if shift is not None:
|
276
|
+
assert isinstance(shift, int)
|
277
|
+
assert shift is not None
|
278
|
+
args.append(shift)
|
279
|
+
if tipLength is not None:
|
280
|
+
assert isinstance(tipLength, float)
|
281
|
+
assert shift is not None
|
282
|
+
args.append(tipLength)
|
283
|
+
|
284
|
+
img._f = _filter_arrowedLine(img._f, pt1, pt2, color, *args)
|
285
|
+
|
286
|
+
|
287
|
+
def line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None):
|
288
|
+
assert isinstance(img, _Frame)
|
289
|
+
img._mut()
|
290
|
+
|
291
|
+
assert len(pt1) == 2
|
292
|
+
assert len(pt2) == 2
|
293
|
+
assert all(isinstance(x, int) for x in pt1)
|
294
|
+
assert all(isinstance(x, int) for x in pt2)
|
295
|
+
|
296
|
+
assert len(color) == 3 or len(color) == 4
|
297
|
+
color = [float(x) for x in color]
|
298
|
+
if len(color) == 3:
|
299
|
+
color.append(255.0)
|
300
|
+
|
301
|
+
args = []
|
302
|
+
if thickness is not None:
|
303
|
+
assert isinstance(thickness, int)
|
304
|
+
args.append(thickness)
|
305
|
+
if lineType is not None:
|
306
|
+
assert isinstance(lineType, int)
|
307
|
+
assert thickness is not None
|
308
|
+
args.append(lineType)
|
309
|
+
if shift is not None:
|
310
|
+
assert isinstance(shift, int)
|
311
|
+
assert shift is not None
|
312
|
+
args.append(shift)
|
313
|
+
|
314
|
+
img._f = _filter_line(img._f, pt1, pt2, color, *args)
|
315
|
+
|
316
|
+
|
317
|
+
def circle(img, center, radius, color, thickness=None, lineType=None, shift=None):
|
318
|
+
assert isinstance(img, _Frame)
|
319
|
+
img._mut()
|
320
|
+
|
321
|
+
assert len(center) == 2
|
322
|
+
assert all(isinstance(x, int) for x in center)
|
323
|
+
|
324
|
+
assert isinstance(radius, int)
|
325
|
+
|
326
|
+
assert len(color) == 3 or len(color) == 4
|
327
|
+
color = [float(x) for x in color]
|
328
|
+
if len(color) == 3:
|
329
|
+
color.append(255.0)
|
330
|
+
|
331
|
+
args = []
|
332
|
+
if thickness is not None:
|
333
|
+
assert isinstance(thickness, int)
|
334
|
+
args.append(thickness)
|
335
|
+
if lineType is not None:
|
336
|
+
assert isinstance(lineType, int)
|
337
|
+
assert thickness is not None
|
338
|
+
args.append(lineType)
|
339
|
+
if shift is not None:
|
340
|
+
assert isinstance(shift, int)
|
341
|
+
assert shift is not None
|
342
|
+
args.append(shift)
|
343
|
+
|
344
|
+
img._f = _filter_circle(img._f, center, radius, color, *args)
|
345
|
+
|
346
|
+
|
347
|
+
def getFontScaleFromHeight(*args, **kwargs):
|
348
|
+
"""
|
349
|
+
cv.getFontScaleFromHeight( fontFace, pixelHeight[, thickness] )
|
350
|
+
"""
|
351
|
+
if _opencv2 is None:
|
352
|
+
raise NotImplementedError("getFontScaleFromHeight requires the cv2 module")
|
353
|
+
return _opencv2.getFontScaleFromHeight(*args, **kwargs)
|
354
|
+
|
355
|
+
|
356
|
+
def getTextSize(*args, **kwargs):
|
357
|
+
"""
|
358
|
+
cv.getTextSize( text, fontFace, fontScale, thickness )
|
359
|
+
"""
|
360
|
+
if _opencv2 is None:
|
361
|
+
raise NotImplementedError("getTextSize requires the cv2 module")
|
362
|
+
return _opencv2.getTextSize(*args, **kwargs)
|
363
|
+
|
364
|
+
|
365
|
+
def addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=-1):
|
366
|
+
"""
|
367
|
+
cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] ) -> dst
|
368
|
+
"""
|
369
|
+
assert isinstance(src1, _Frame)
|
370
|
+
assert isinstance(src2, _Frame)
|
371
|
+
src1._mut()
|
372
|
+
src2._mut()
|
373
|
+
|
374
|
+
if dst is None:
|
375
|
+
dst = _Frame(src1._f)
|
376
|
+
else:
|
377
|
+
assert isinstance(dst, _Frame)
|
378
|
+
dst._mut()
|
379
|
+
|
380
|
+
assert isinstance(alpha, float) or isinstance(alpha, int)
|
381
|
+
assert isinstance(beta, float) or isinstance(beta, int)
|
382
|
+
assert isinstance(gamma, float) or isinstance(gamma, int)
|
383
|
+
alpha = float(alpha)
|
384
|
+
beta = float(beta)
|
385
|
+
gamma = float(gamma)
|
386
|
+
|
387
|
+
if dtype != -1:
|
388
|
+
raise Exception("addWeighted does not support the dtype argument")
|
389
|
+
|
390
|
+
dst._f = _filter_addWeighted(src1._f, alpha, src2._f, beta, gamma)
|
391
|
+
return dst
|
392
|
+
|
393
|
+
|
394
|
+
# Stubs for unimplemented functions
|
395
|
+
|
396
|
+
|
397
|
+
def clipLine(*args, **kwargs):
|
398
|
+
raise NotImplementedError("clipLine is not yet implemented in the cv2 frontend")
|
399
|
+
|
400
|
+
|
401
|
+
def drawContours(*args, **kwargs):
|
402
|
+
raise NotImplementedError("drawContours is not yet implemented in the cv2 frontend")
|
403
|
+
|
404
|
+
|
405
|
+
def drawMarker(*args, **kwargs):
|
406
|
+
raise NotImplementedError("drawMarker is not yet implemented in the cv2 frontend")
|
407
|
+
|
408
|
+
|
409
|
+
def ellipse(*args, **kwargs):
|
410
|
+
raise NotImplementedError("ellipse is not yet implemented in the cv2 frontend")
|
411
|
+
|
412
|
+
|
413
|
+
def ellipse2Poly(*args, **kwargs):
|
414
|
+
raise NotImplementedError("ellipse2Poly is not yet implemented in the cv2 frontend")
|
415
|
+
|
416
|
+
|
417
|
+
def fillConvexPoly(*args, **kwargs):
|
418
|
+
raise NotImplementedError(
|
419
|
+
"fillConvexPoly is not yet implemented in the cv2 frontend"
|
420
|
+
)
|
421
|
+
|
422
|
+
|
423
|
+
def fillPoly(*args, **kwargs):
|
424
|
+
raise NotImplementedError("fillPoly is not yet implemented in the cv2 frontend")
|
425
|
+
|
426
|
+
|
427
|
+
def polylines(*args, **kwargs):
|
428
|
+
raise NotImplementedError("polylines is not yet implemented in the cv2 frontend")
|
vidformer.py → vidformer/vf.py
RENAMED
@@ -1,7 +1,3 @@
|
|
1
|
-
"""A Python library for creating and viewing videos with vidformer."""
|
2
|
-
|
3
|
-
__version__ = "0.5.4"
|
4
|
-
|
5
1
|
import subprocess
|
6
2
|
from fractions import Fraction
|
7
3
|
import random
|
@@ -21,6 +17,8 @@ import requests
|
|
21
17
|
import msgpack
|
22
18
|
import numpy as np
|
23
19
|
|
20
|
+
from . import __version__
|
21
|
+
|
24
22
|
_in_notebook = False
|
25
23
|
try:
|
26
24
|
from IPython import get_ipython
|
@@ -355,7 +353,7 @@ class Loader:
|
|
355
353
|
class YrdenServer:
|
356
354
|
"""A connection to a Yrden server"""
|
357
355
|
|
358
|
-
def __init__(self, domain=None, port=None, bin=
|
356
|
+
def __init__(self, domain=None, port=None, bin=None):
|
359
357
|
"""Connect to a Yrden server
|
360
358
|
|
361
359
|
Can either connect to an existing server, if domain and port are provided, or start a new server using the provided binary
|
@@ -365,7 +363,12 @@ class YrdenServer:
|
|
365
363
|
self._port = port
|
366
364
|
self._proc = None
|
367
365
|
if self._port is None:
|
368
|
-
|
366
|
+
if bin is None:
|
367
|
+
if os.getenv("VIDFORMER_BIN") is not None:
|
368
|
+
bin = os.getenv("VIDFORMER_BIN")
|
369
|
+
else:
|
370
|
+
bin = "vidformer-cli"
|
371
|
+
|
369
372
|
self._domain = "localhost"
|
370
373
|
self._port = random.randint(49152, 65535)
|
371
374
|
cmd = [bin, "yrden", "--port", str(self._port)]
|
@@ -579,17 +582,31 @@ class StorageService:
|
|
579
582
|
return f"{self._service}(config={self._config})"
|
580
583
|
|
581
584
|
|
582
|
-
def _json_arg(arg):
|
585
|
+
def _json_arg(arg, skip_data_anot=False):
|
583
586
|
if type(arg) == FilterExpr or type(arg) == SourceExpr:
|
584
587
|
return {"Frame": arg._to_json_spec()}
|
585
588
|
elif type(arg) == int:
|
589
|
+
if skip_data_anot:
|
590
|
+
return {"Int": arg}
|
586
591
|
return {"Data": {"Int": arg}}
|
587
592
|
elif type(arg) == str:
|
593
|
+
if skip_data_anot:
|
594
|
+
return {"String": arg}
|
588
595
|
return {"Data": {"String": arg}}
|
596
|
+
elif type(arg) == float:
|
597
|
+
if skip_data_anot:
|
598
|
+
return {"Float": arg}
|
599
|
+
return {"Data": {"Float": arg}}
|
589
600
|
elif type(arg) == bool:
|
601
|
+
if skip_data_anot:
|
602
|
+
return {"Bool": arg}
|
590
603
|
return {"Data": {"Bool": arg}}
|
604
|
+
elif type(arg) == tuple or type(arg) == list:
|
605
|
+
if skip_data_anot:
|
606
|
+
return {"List": [_json_arg(x, True) for x in list(arg)]}
|
607
|
+
return {"Data": {"List": [_json_arg(x, True) for x in list(arg)]}}
|
591
608
|
else:
|
592
|
-
|
609
|
+
raise Exception(f"Unknown arg type: {type(arg)}")
|
593
610
|
|
594
611
|
|
595
612
|
class Filter:
|
@@ -751,9 +768,9 @@ class UDF:
|
|
751
768
|
keys = list(obj.keys())
|
752
769
|
assert len(keys) == 1
|
753
770
|
type_key = keys[0]
|
754
|
-
assert type_key in ["
|
771
|
+
assert type_key in ["FrameType", "String", "Int", "Bool"]
|
755
772
|
|
756
|
-
if type_key == "
|
773
|
+
if type_key == "FrameType":
|
757
774
|
frame = obj[type_key]
|
758
775
|
assert type(frame) == dict
|
759
776
|
assert "width" in frame
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: vidformer
|
3
|
+
Version: 0.6.1
|
4
|
+
Summary: A Python library for creating and viewing videos with vidformer.
|
5
|
+
Author-email: Dominik Winecki <dominikwinecki@gmail.com>
|
6
|
+
Requires-Python: >=3.8
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Operating System :: OS Independent
|
10
|
+
Requires-Dist: requests
|
11
|
+
Requires-Dist: msgpack
|
12
|
+
Requires-Dist: numpy
|
13
|
+
Project-URL: Documentation, https://ixlab.github.io/vidformer/vidformer-py/
|
14
|
+
Project-URL: Homepage, https://ixlab.github.io/vidformer/
|
15
|
+
Project-URL: Issues, https://github.com/ixlab/vidformer/issues
|
16
|
+
|
17
|
+
# vidformer-py
|
18
|
+
|
19
|
+
[](https://pypi.org/project/vidformer/)
|
20
|
+
[](https://github.com/ixlab/vidformer/blob/main/LICENSE)
|
21
|
+
|
22
|
+
|
23
|
+
vidformer-py is our Python 🐍 interface for [vidformer](https://github.com/ixlab/vidformer).
|
24
|
+
Our [getting started guide](https://ixlab.github.io/vidformer/getting-started.html) explains how to use it.
|
25
|
+
|
26
|
+
**Quick links:**
|
27
|
+
* [📦 PyPI](https://pypi.org/project/vidformer/)
|
28
|
+
* [📘 Documentation](https://ixlab.github.io/vidformer/vidformer-py/)
|
29
|
+
* [🧑💻 Source Code](https://github.com/ixlab/vidformer/tree/main/vidformer-py/)
|
30
|
+
|
31
|
+
**Publish:**
|
32
|
+
```bash
|
33
|
+
export FLIT_USERNAME='__token__' FLIT_PASSWORD='<token>'
|
34
|
+
flit publish
|
35
|
+
```
|
36
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
vidformer/__init__.py,sha256=C-kb3m7hPUh0Sw09vty3JKJHMbJTQcdqSmt8m2V9HIM,113
|
2
|
+
vidformer/vf.py,sha256=gexrp0PQ8cbkixCPLY9BCquHeHWfD6iUcA_wbSxGmFQ,29511
|
3
|
+
vidformer/cv2/__init__.py,sha256=wOjDsYyUKlP_Hye8-tyz-msu9xwaPMpN2sGMu3Lh3-w,22
|
4
|
+
vidformer/cv2/vf_cv2.py,sha256=m05MNPklhaaAfFQfTWetJ_FqWq0u_s77INfABUnHVoA,11664
|
5
|
+
vidformer-0.6.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
6
|
+
vidformer-0.6.1.dist-info/METADATA,sha256=gbvJy_0NGLbnq-EvDsDSoUm7EmHhlfUQL5au6pKCsXk,1383
|
7
|
+
vidformer-0.6.1.dist-info/RECORD,,
|
@@ -1,24 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: vidformer
|
3
|
-
Version: 0.5.4
|
4
|
-
Summary: A Python library for creating and viewing videos with vidformer.
|
5
|
-
Author-email: Dominik Winecki <dominikwinecki@gmail.com>
|
6
|
-
Requires-Python: >=3.8
|
7
|
-
Description-Content-Type: text/markdown
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
9
|
-
Classifier: Operating System :: OS Independent
|
10
|
-
Requires-Dist: requests
|
11
|
-
Requires-Dist: msgpack
|
12
|
-
Requires-Dist: numpy
|
13
|
-
Project-URL: Homepage, https://ixlab.github.io/vidformer/
|
14
|
-
Project-URL: Issues, https://ixlab.github.io/vidformer/issues
|
15
|
-
|
16
|
-
# vidformer-py
|
17
|
-
|
18
|
-
## Publish
|
19
|
-
|
20
|
-
```bash
|
21
|
-
export FLIT_USERNAME='__token__' FLIT_PASSWORD='<token>'
|
22
|
-
flit publish
|
23
|
-
```
|
24
|
-
|
vidformer-0.5.4.dist-info/RECORD
DELETED
@@ -1,4 +0,0 @@
|
|
1
|
-
vidformer.py,sha256=11H5DONF82OWWdd4DxE30u9puuT_Y3sy3bFEhvKZs54,28821
|
2
|
-
vidformer-0.5.4.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
3
|
-
vidformer-0.5.4.dist-info/METADATA,sha256=Sn-s_MobObWQkbOiqDqeKNB69Td5kjM79TdXN-YXgHs,643
|
4
|
-
vidformer-0.5.4.dist-info/RECORD,,
|
File without changes
|