vidformer 0.6.0__py3-none-any.whl → 0.6.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
vidformer/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """A Python library for creating and viewing videos with vidformer."""
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.6.2"
4
4
 
5
5
  from .vf import *
vidformer/cv2/vf_cv2.py CHANGED
@@ -1,5 +1,24 @@
1
+ """
2
+ vidformer.cv2 is the cv2 frontend for [vidformer](https://github.com/ixlab/vidformer).
3
+
4
+ > ⚠️ This module is a work in progress. See the [implemented functions list](https://ixlab.github.io/vidformer/opencv-filters.html).
5
+
6
+ **Quick links:**
7
+ * [📦 PyPI](https://pypi.org/project/vidformer/)
8
+ * [📘 Documentation - vidformer-py](https://ixlab.github.io/vidformer/vidformer-py/)
9
+ * [📘 Documentation - vidformer.cv2](https://ixlab.github.io/vidformer/vidformer-py-cv2/)
10
+ * [🧑‍💻 Source Code](https://github.com/ixlab/vidformer/tree/main/vidformer-py/)
11
+ """
12
+
1
13
  from .. import vf
2
14
 
15
+ try:
16
+ import cv2 as _opencv2
17
+ except:
18
+ _opencv2 = None
19
+
20
+ import numpy as np
21
+
3
22
  import uuid
4
23
  from fractions import Fraction
5
24
  from bisect import bisect_right
@@ -9,6 +28,7 @@ CAP_PROP_POS_FRAMES = 1
9
28
  CAP_PROP_FRAME_WIDTH = 3
10
29
  CAP_PROP_FRAME_HEIGHT = 4
11
30
  CAP_PROP_FPS = 5
31
+ CAP_PROP_FRAME_COUNT = 7
12
32
 
13
33
  FONT_HERSHEY_SIMPLEX = 0
14
34
  FONT_HERSHEY_PLAIN = 1
@@ -28,6 +48,10 @@ LINE_AA = 16
28
48
  _filter_scale = vf.Filter("Scale")
29
49
  _filter_rectangle = vf.Filter("cv2.rectangle")
30
50
  _filter_putText = vf.Filter("cv2.putText")
51
+ _filter_arrowedLine = vf.Filter("cv2.arrowedLine")
52
+ _filter_line = vf.Filter("cv2.line")
53
+ _filter_circle = vf.Filter("cv2.circle")
54
+ _filter_addWeighted = vf.Filter("cv2.addWeighted")
31
55
 
32
56
 
33
57
  def _ts_to_fps(timestamps):
@@ -49,16 +73,18 @@ def _server():
49
73
  return _global_cv2_server
50
74
 
51
75
 
52
- def set_cv2_server(server):
76
+ def set_cv2_server(server: vf.YrdenServer):
53
77
  """Set the server to use for the cv2 frontend."""
54
78
  global _global_cv2_server
55
79
  assert isinstance(server, vf.YrdenServer)
56
80
  _global_cv2_server = server
57
81
 
58
82
 
59
- class _Frame:
60
- def __init__(self, f):
83
+ class Frame:
84
+ def __init__(self, f, fmt):
61
85
  self._f = f
86
+ self._fmt = fmt
87
+ self.shape = (fmt["height"], fmt["width"], 3)
62
88
 
63
89
  # denotes that the frame has not yet been modified
64
90
  # when a frame is modified, it is converted to rgb24 first
@@ -67,6 +93,23 @@ class _Frame:
67
93
  def _mut(self):
68
94
  self._modified = True
69
95
  self._f = _filter_scale(self._f, pix_fmt="rgb24")
96
+ self._fmt["pix_fmt"] = "rgb24"
97
+
98
+ def numpy(self):
99
+ """
100
+ Return the frame as a numpy array.
101
+ """
102
+
103
+ self._mut()
104
+ spec = vf.Spec([Fraction(0, 1)], lambda t, i: self._f, self._fmt)
105
+ loader = spec.load(_server())
106
+
107
+ frame_raster_rgb24 = loader[0]
108
+ assert type(frame_raster_rgb24) == bytes
109
+ assert len(frame_raster_rgb24) == self.shape[0] * self.shape[1] * 3
110
+ raw_data_array = np.frombuffer(frame_raster_rgb24, dtype=np.uint8)
111
+ frame = raw_data_array.reshape(self.shape)
112
+ return frame
70
113
 
71
114
 
72
115
  class VideoCapture:
@@ -86,6 +129,10 @@ class VideoCapture:
86
129
  return self._source.fmt()["width"]
87
130
  elif prop == CAP_PROP_FRAME_HEIGHT:
88
131
  return self._source.fmt()["height"]
132
+ elif prop == CAP_PROP_FRAME_COUNT:
133
+ return len(self._source.ts())
134
+ elif prop == CAP_PROP_POS_FRAMES:
135
+ return self._next_frame_idx
89
136
 
90
137
  raise Exception(f"Unknown property {prop}")
91
138
 
@@ -106,7 +153,7 @@ class VideoCapture:
106
153
  return False, None
107
154
  frame = self._source.iloc[self._next_frame_idx]
108
155
  self._next_frame_idx += 1
109
- frame = _Frame(frame)
156
+ frame = Frame(frame, self._source.fmt())
110
157
  return True, frame
111
158
 
112
159
  def release(self):
@@ -116,6 +163,8 @@ class VideoCapture:
116
163
  class VideoWriter:
117
164
  def __init__(self, path, fourcc, fps, size):
118
165
  assert isinstance(fourcc, VideoWriter_fourcc)
166
+ if path is not None and not isinstance(path, str):
167
+ raise Exception("path must be a string or None")
119
168
  self._path = path
120
169
  self._fourcc = fourcc
121
170
  self._fps = fps
@@ -125,8 +174,8 @@ class VideoWriter:
125
174
  self._pix_fmt = "yuv420p"
126
175
 
127
176
  def write(self, frame):
128
- if not isinstance(frame, _Frame):
129
- raise Exception("frame must be a _Frame object")
177
+ if not isinstance(frame, Frame):
178
+ raise Exception("frame must be a vidformer.cv2.Frame object")
130
179
  if frame._modified:
131
180
  f_obj = _filter_scale(frame._f, pix_fmt=self._pix_fmt)
132
181
  self._frames.append(f_obj)
@@ -134,11 +183,14 @@ class VideoWriter:
134
183
  self._frames.append(frame._f)
135
184
 
136
185
  def release(self):
137
- spec = self.vf_spec()
186
+ if self._path is None:
187
+ return
188
+
189
+ spec = self.spec()
138
190
  server = _server()
139
191
  spec.save(server, self._path)
140
192
 
141
- def vf_spec(self):
193
+ def spec(self) -> vf.Spec:
142
194
  fmt = {
143
195
  "width": self._size[0],
144
196
  "height": self._size[1],
@@ -154,12 +206,79 @@ class VideoWriter_fourcc:
154
206
  self._args = args
155
207
 
156
208
 
209
+ def imread(path, *args):
210
+ if len(args) > 0:
211
+ raise NotImplementedError("imread does not support additional arguments")
212
+
213
+ assert path.lower().endswith((".jpg", ".jpeg", ".png"))
214
+ server = _server()
215
+ source = vf.Source(server, str(uuid.uuid4()), path, 0)
216
+ frame = Frame(source.iloc[0], source.fmt())
217
+ return frame
218
+
219
+
220
+ def imwrite(path, img, *args):
221
+ if len(args) > 0:
222
+ raise NotImplementedError("imwrite does not support additional arguments")
223
+
224
+ if not isinstance(img, Frame):
225
+ raise Exception("img must be a vidformer.cv2.Frame object")
226
+
227
+ fmt = img._fmt.copy()
228
+ width = fmt["width"]
229
+ height = fmt["height"]
230
+ f = img._f
231
+
232
+ domain = [Fraction(0, 1)]
233
+
234
+ if path.lower().endswith(".png"):
235
+ img._mut() # Make sure it's in rgb24
236
+ spec = vf.Spec(
237
+ domain,
238
+ lambda t, i: img._f,
239
+ {"width": width, "height": height, "pix_fmt": "rgb24"},
240
+ )
241
+ spec.save(_server(), path, encoder="png")
242
+ elif path.lower().endswith((".jpg", ".jpeg")):
243
+ if img._modified:
244
+ # it's rgb24, we need to convert to something jpeg can handle
245
+ f = _filter_scale(img._f, pix_fmt="yuv420p")
246
+ fmt["pix_fmt"] = "yuv420p"
247
+ else:
248
+ if fmt["pix_fmt"] not in ["yuvj420p", "yuvj422p", "yuvj444p"]:
249
+ f = _filter_scale(img._f, pix_fmt="yuvj420p")
250
+ fmt["pix_fmt"] = "yuvj420p"
251
+
252
+ spec = vf.Spec(domain, lambda t, i: f, fmt)
253
+ spec.save(_server(), path, encoder="mjpeg")
254
+ else:
255
+ raise Exception("Unsupported image format")
256
+
257
+
258
+ def vidplay(video, *args, **kwargs):
259
+ """
260
+ Play a vidformer video specification.
261
+
262
+ Args:
263
+ video: one of [vidformer.Spec, vidformer.Source, vidformer.cv2.VideoWriter]
264
+ """
265
+
266
+ if isinstance(video, vf.Spec):
267
+ return video.play(_server(), *args, **kwargs)
268
+ elif isinstance(video, vf.Source):
269
+ return video.play(_server(), *args, **kwargs)
270
+ elif isinstance(video, VideoWriter):
271
+ return video.spec().play(_server(), *args, **kwargs)
272
+ else:
273
+ raise Exception("Unsupported video type to vidplay")
274
+
275
+
157
276
  def rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None):
158
277
  """
159
278
  cv.rectangle( img, pt1, pt2, color[, thickness[, lineType[, shift]]] )
160
279
  """
161
280
 
162
- assert isinstance(img, _Frame)
281
+ assert isinstance(img, Frame)
163
282
  img._mut()
164
283
 
165
284
  assert len(pt1) == 2
@@ -203,7 +322,7 @@ def putText(
203
322
  cv.putText( img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]] )
204
323
  """
205
324
 
206
- assert isinstance(img, _Frame)
325
+ assert isinstance(img, Frame)
207
326
  img._mut()
208
327
 
209
328
  assert isinstance(text, str)
@@ -234,3 +353,186 @@ def putText(
234
353
  args.append(bottomLeftOrigin)
235
354
 
236
355
  img._f = _filter_putText(img._f, text, org, fontFace, fontScale, color, *args)
356
+
357
+
358
+ def arrowedLine(
359
+ img, pt1, pt2, color, thickness=None, line_type=None, shift=None, tipLength=None
360
+ ):
361
+ """
362
+ cv.arrowedLine( img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]] )
363
+ """
364
+ assert isinstance(img, Frame)
365
+ img._mut()
366
+
367
+ assert len(pt1) == 2
368
+ assert len(pt2) == 2
369
+ assert all(isinstance(x, int) for x in pt1)
370
+ assert all(isinstance(x, int) for x in pt2)
371
+
372
+ assert len(color) == 3 or len(color) == 4
373
+ color = [float(x) for x in color]
374
+ if len(color) == 3:
375
+ color.append(255.0)
376
+
377
+ args = []
378
+ if thickness is not None:
379
+ assert isinstance(thickness, int)
380
+ args.append(thickness)
381
+ if line_type is not None:
382
+ assert isinstance(line_type, int)
383
+ assert thickness is not None
384
+ args.append(line_type)
385
+ if shift is not None:
386
+ assert isinstance(shift, int)
387
+ assert shift is not None
388
+ args.append(shift)
389
+ if tipLength is not None:
390
+ assert isinstance(tipLength, float)
391
+ assert shift is not None
392
+ args.append(tipLength)
393
+
394
+ img._f = _filter_arrowedLine(img._f, pt1, pt2, color, *args)
395
+
396
+
397
+ def line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None):
398
+ assert isinstance(img, Frame)
399
+ img._mut()
400
+
401
+ assert len(pt1) == 2
402
+ assert len(pt2) == 2
403
+ assert all(isinstance(x, int) for x in pt1)
404
+ assert all(isinstance(x, int) for x in pt2)
405
+
406
+ assert len(color) == 3 or len(color) == 4
407
+ color = [float(x) for x in color]
408
+ if len(color) == 3:
409
+ color.append(255.0)
410
+
411
+ args = []
412
+ if thickness is not None:
413
+ assert isinstance(thickness, int)
414
+ args.append(thickness)
415
+ if lineType is not None:
416
+ assert isinstance(lineType, int)
417
+ assert thickness is not None
418
+ args.append(lineType)
419
+ if shift is not None:
420
+ assert isinstance(shift, int)
421
+ assert shift is not None
422
+ args.append(shift)
423
+
424
+ img._f = _filter_line(img._f, pt1, pt2, color, *args)
425
+
426
+
427
+ def circle(img, center, radius, color, thickness=None, lineType=None, shift=None):
428
+ assert isinstance(img, Frame)
429
+ img._mut()
430
+
431
+ assert len(center) == 2
432
+ assert all(isinstance(x, int) for x in center)
433
+
434
+ assert isinstance(radius, int)
435
+
436
+ assert len(color) == 3 or len(color) == 4
437
+ color = [float(x) for x in color]
438
+ if len(color) == 3:
439
+ color.append(255.0)
440
+
441
+ args = []
442
+ if thickness is not None:
443
+ assert isinstance(thickness, int)
444
+ args.append(thickness)
445
+ if lineType is not None:
446
+ assert isinstance(lineType, int)
447
+ assert thickness is not None
448
+ args.append(lineType)
449
+ if shift is not None:
450
+ assert isinstance(shift, int)
451
+ assert shift is not None
452
+ args.append(shift)
453
+
454
+ img._f = _filter_circle(img._f, center, radius, color, *args)
455
+
456
+
457
+ def getFontScaleFromHeight(*args, **kwargs):
458
+ """
459
+ cv.getFontScaleFromHeight( fontFace, pixelHeight[, thickness] )
460
+ """
461
+ if _opencv2 is None:
462
+ raise NotImplementedError("getFontScaleFromHeight requires the cv2 module")
463
+ return _opencv2.getFontScaleFromHeight(*args, **kwargs)
464
+
465
+
466
+ def getTextSize(*args, **kwargs):
467
+ """
468
+ cv.getTextSize( text, fontFace, fontScale, thickness )
469
+ """
470
+ if _opencv2 is None:
471
+ raise NotImplementedError("getTextSize requires the cv2 module")
472
+ return _opencv2.getTextSize(*args, **kwargs)
473
+
474
+
475
+ def addWeighted(src1, alpha, src2, beta, gamma, dst=None, dtype=-1):
476
+ """
477
+ cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] ) -> dst
478
+ """
479
+ assert isinstance(src1, Frame)
480
+ assert isinstance(src2, Frame)
481
+ src1._mut()
482
+ src2._mut()
483
+
484
+ if dst is None:
485
+ dst = Frame(src1._f, src1._fmt.copy())
486
+ else:
487
+ assert isinstance(dst, Frame)
488
+ dst._mut()
489
+
490
+ assert isinstance(alpha, float) or isinstance(alpha, int)
491
+ assert isinstance(beta, float) or isinstance(beta, int)
492
+ assert isinstance(gamma, float) or isinstance(gamma, int)
493
+ alpha = float(alpha)
494
+ beta = float(beta)
495
+ gamma = float(gamma)
496
+
497
+ if dtype != -1:
498
+ raise Exception("addWeighted does not support the dtype argument")
499
+
500
+ dst._f = _filter_addWeighted(src1._f, alpha, src2._f, beta, gamma)
501
+ return dst
502
+
503
+
504
+ # Stubs for unimplemented functions
505
+
506
+
507
+ def clipLine(*args, **kwargs):
508
+ raise NotImplementedError("clipLine is not yet implemented in the cv2 frontend")
509
+
510
+
511
+ def drawContours(*args, **kwargs):
512
+ raise NotImplementedError("drawContours is not yet implemented in the cv2 frontend")
513
+
514
+
515
+ def drawMarker(*args, **kwargs):
516
+ raise NotImplementedError("drawMarker is not yet implemented in the cv2 frontend")
517
+
518
+
519
+ def ellipse(*args, **kwargs):
520
+ raise NotImplementedError("ellipse is not yet implemented in the cv2 frontend")
521
+
522
+
523
+ def ellipse2Poly(*args, **kwargs):
524
+ raise NotImplementedError("ellipse2Poly is not yet implemented in the cv2 frontend")
525
+
526
+
527
+ def fillConvexPoly(*args, **kwargs):
528
+ raise NotImplementedError(
529
+ "fillConvexPoly is not yet implemented in the cv2 frontend"
530
+ )
531
+
532
+
533
+ def fillPoly(*args, **kwargs):
534
+ raise NotImplementedError("fillPoly is not yet implemented in the cv2 frontend")
535
+
536
+
537
+ def polylines(*args, **kwargs):
538
+ raise NotImplementedError("polylines is not yet implemented in the cv2 frontend")
vidformer/vf.py CHANGED
@@ -1,3 +1,13 @@
1
+ """
2
+ vidformer-py is a Python 🐍 interface for [vidformer](https://github.com/ixlab/vidformer).
3
+
4
+ **Quick links:**
5
+ * [📦 PyPI](https://pypi.org/project/vidformer/)
6
+ * [📘 Documentation - vidformer-py](https://ixlab.github.io/vidformer/vidformer-py/)
7
+ * [📘 Documentation - vidformer.cv2](https://ixlab.github.io/vidformer/vidformer-py-cv2/)
8
+ * [🧑‍💻 Source Code](https://github.com/ixlab/vidformer/tree/main/vidformer-py/)
9
+ """
10
+
1
11
  import subprocess
2
12
  from fractions import Fraction
3
13
  import random
@@ -43,19 +53,40 @@ def _check_hls_link_exists(url, max_attempts=150, delay=0.1):
43
53
 
44
54
 
45
55
  class Spec:
56
+ """
57
+ A video transformation specification.
58
+
59
+ See https://ixlab.github.io/vidformer/concepts.html for more information.
60
+ """
61
+
46
62
  def __init__(self, domain: list[Fraction], render, fmt: dict):
47
63
  self._domain = domain
48
64
  self._render = render
49
65
  self._fmt = fmt
50
66
 
51
67
  def __repr__(self):
52
- lines = []
53
- for i, t in enumerate(self._domain):
54
- frame_expr = self._render(t, i)
55
- lines.append(
56
- f"{t.numerator}/{t.denominator} => {frame_expr}",
57
- )
58
- return "\n".join(lines)
68
+ if len(self._domain) <= 20:
69
+ lines = []
70
+ for i, t in enumerate(self._domain):
71
+ frame_expr = self._render(t, i)
72
+ lines.append(
73
+ f"{t.numerator}/{t.denominator} => {frame_expr}",
74
+ )
75
+ return "\n".join(lines)
76
+ else:
77
+ lines = []
78
+ for i, t in enumerate(self._domain[:10]):
79
+ frame_expr = self._render(t, i)
80
+ lines.append(
81
+ f"{t.numerator}/{t.denominator} => {frame_expr}",
82
+ )
83
+ lines.append("...")
84
+ for i, t in enumerate(self._domain[-10:]):
85
+ frame_expr = self._render(t, i)
86
+ lines.append(
87
+ f"{t.numerator}/{t.denominator} => {frame_expr}",
88
+ )
89
+ return "\n".join(lines)
59
90
 
60
91
  def _sources(self):
61
92
  s = set()
@@ -351,12 +382,18 @@ class Loader:
351
382
 
352
383
 
353
384
  class YrdenServer:
354
- """A connection to a Yrden server"""
385
+ """
386
+ A connection to a Yrden server.
387
+
388
+ A yrden server is the main API for local use of vidformer.
389
+ """
355
390
 
356
391
  def __init__(self, domain=None, port=None, bin=None):
357
- """Connect to a Yrden server
392
+ """
393
+ Connect to a Yrden server
358
394
 
359
- Can either connect to an existing server, if domain and port are provided, or start a new server using the provided binary
395
+ Can either connect to an existing server, if domain and port are provided, or start a new server using the provided binary.
396
+ If no domain or binary is provided, the `VIDFORMER_BIN` environment variable is used.
360
397
  """
361
398
 
362
399
  self._domain = domain
@@ -503,11 +540,13 @@ class SourceILoc:
503
540
 
504
541
  def __getitem__(self, idx):
505
542
  if type(idx) != int:
506
- raise Exception("Source iloc index must be an integer")
543
+ raise Exception(f"Source iloc index must be an integer, got a {type(idx)}")
507
544
  return SourceExpr(self._source, idx, True)
508
545
 
509
546
 
510
547
  class Source:
548
+ """A video source."""
549
+
511
550
  def __init__(
512
551
  self, server: YrdenServer, name: str, path: str, stream: int, service=None
513
552
  ):
@@ -610,6 +649,8 @@ def _json_arg(arg, skip_data_anot=False):
610
649
 
611
650
 
612
651
  class Filter:
652
+ """A video filter."""
653
+
613
654
  def __init__(self, name: str, tl_func=None, **kwargs):
614
655
  self._name = name
615
656
 
@@ -854,6 +895,10 @@ class UDF:
854
895
 
855
896
 
856
897
  class UDFFrameType:
898
+ """
899
+ Frame type for use in UDFs.
900
+ """
901
+
857
902
  def __init__(self, width: int, height: int, pix_fmt: str):
858
903
  assert type(width) == int
859
904
  assert type(height) == int
@@ -886,6 +931,8 @@ class UDFFrameType:
886
931
 
887
932
 
888
933
  class UDFFrame:
934
+ """A symbolic reference to a frame for use in UDFs."""
935
+
889
936
  def __init__(self, data: np.ndarray, f_type: UDFFrameType):
890
937
  assert type(data) == np.ndarray
891
938
  assert type(f_type) == UDFFrameType
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.1
2
+ Name: vidformer
3
+ Version: 0.6.2
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
+ [![PyPI version](https://img.shields.io/pypi/v/vidformer.svg)](https://pypi.org/project/vidformer/)
20
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ixlab/vidformer/blob/main/LICENSE)
21
+
22
+ vidformer-py is a Python 🐍 interface for [vidformer](https://github.com/ixlab/vidformer).
23
+ Our [getting started guide](https://ixlab.github.io/vidformer/getting-started.html) explains how to use it.
24
+
25
+ **Quick links:**
26
+ * [📦 PyPI](https://pypi.org/project/vidformer/)
27
+ * [📘 Documentation - vidformer-py](https://ixlab.github.io/vidformer/vidformer-py/)
28
+ * [📘 Documentation - vidformer.cv2](https://ixlab.github.io/vidformer/vidformer-py-cv2/)
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=JnJ5T-Afn8dZXAkwmq38cFzrnK4aZZZSFhHdUqVLdno,113
2
+ vidformer/vf.py,sha256=0idKHOkWXC5bki1thrgihKQwJ91gDCzf96tl3Gm5vaA,31059
3
+ vidformer/cv2/__init__.py,sha256=wOjDsYyUKlP_Hye8-tyz-msu9xwaPMpN2sGMu3Lh3-w,22
4
+ vidformer/cv2/vf_cv2.py,sha256=CO9LZ7FwOhrzNJ1eFjd9JddZm0PjY-XtOlKIYGB3iQQ,15486
5
+ vidformer-0.6.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
6
+ vidformer-0.6.2.dist-info/METADATA,sha256=_jQnVbcd_OHAy57G7HXIijyXUOoR9Q8AzURvjn3ljDA,1487
7
+ vidformer-0.6.2.dist-info/RECORD,,
@@ -1,24 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: vidformer
3
- Version: 0.6.0
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
-
@@ -1,7 +0,0 @@
1
- vidformer/__init__.py,sha256=MgZOCVL7wOxSseM5LArXHtW3FzPKLcmGzUaosUhSn6A,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=C3b8OEGSHh7AFbtddybP_DwR7rvy34lCewt9JWcLTaM,6196
5
- vidformer-0.6.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
6
- vidformer-0.6.0.dist-info/METADATA,sha256=hK3hz1DM6NQfkmMz2L5Uc098wgCvPJzaHbpkZy-DDt8,643
7
- vidformer-0.6.0.dist-info/RECORD,,