vidformer 0.5.0__py3-none-any.whl → 0.5.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vidformer
3
- Version: 0.5.0
3
+ Version: 0.5.2
4
4
  Summary: A Python library for creating and viewing videos with vidformer.
5
5
  Author-email: Dominik Winecki <dominikwinecki@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -0,0 +1,4 @@
1
+ vidformer.py,sha256=gSe2Kq19Y1v3jQ6cLg6tS7aVr_qB_vN4JcxjCpFXg2k,27989
2
+ vidformer-0.5.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
3
+ vidformer-0.5.2.dist-info/METADATA,sha256=yFb6aI7LrodHg7fvReIQaF760STK5KbfhWEMEHBYxpk,643
4
+ vidformer-0.5.2.dist-info/RECORD,,
vidformer.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """A Python library for creating and viewing videos with vidformer."""
2
2
 
3
- __version__ = "0.5.0"
3
+ __version__ = "0.5.2"
4
4
 
5
5
  import subprocess
6
6
  from fractions import Fraction
@@ -77,7 +77,7 @@ class Spec:
77
77
  frames.append(frame)
78
78
  return {"frames": frames}, s, f
79
79
 
80
- def play(self, server, method="html"):
80
+ def play(self, server, method="html", verbose=False):
81
81
  """Play the video live in the notebook."""
82
82
 
83
83
  spec, sources, filters = self._to_json_spec()
@@ -103,7 +103,9 @@ class Spec:
103
103
  }
104
104
  arrays = []
105
105
 
106
- print(f"Sending to server. Spec is {len(spec_obj_json_gzip_b64)} bytes")
106
+ if verbose:
107
+ print(f"Sending to server. Spec is {len(spec_obj_json_gzip_b64)} bytes")
108
+
107
109
  resp = server._new(spec_obj_json_gzip_b64, sources, filters, arrays, self._fmt)
108
110
  hls_video_url = resp["stream_url"]
109
111
  hls_player_url = resp["player_url"]
@@ -150,7 +152,35 @@ class Spec:
150
152
  else:
151
153
  return hls_player_url
152
154
 
153
- def save(self, server, pth, encoder=None, encoder_opts=None):
155
+ def load(self, server):
156
+ spec, sources, filters = self._to_json_spec()
157
+ spec_json_bytes = json.dumps(spec).encode("utf-8")
158
+ spec_obj_json_gzip = gzip.compress(spec_json_bytes, compresslevel=1)
159
+ spec_obj_json_gzip_b64 = base64.b64encode(spec_obj_json_gzip).decode("utf-8")
160
+
161
+ sources = [
162
+ {
163
+ "name": s._name,
164
+ "path": s._path,
165
+ "stream": s._stream,
166
+ "service": s._service.as_json() if s._service is not None else None,
167
+ }
168
+ for s in sources
169
+ ]
170
+ filters = {
171
+ k: {
172
+ "filter": v._func,
173
+ "args": v._kwargs,
174
+ }
175
+ for k, v in filters.items()
176
+ }
177
+ arrays = []
178
+
179
+ resp = server._new(spec_obj_json_gzip_b64, sources, filters, arrays, self._fmt)
180
+ namespace = resp["namespace"]
181
+ return Loader(server, namespace, self._domain)
182
+
183
+ def save(self, server, pth, encoder=None, encoder_opts=None, format=None):
154
184
  """Save the video to a file."""
155
185
 
156
186
  assert encoder is None or type(encoder) == str
@@ -191,6 +221,7 @@ class Spec:
191
221
  self._fmt,
192
222
  encoder,
193
223
  encoder_opts,
224
+ format,
194
225
  )
195
226
 
196
227
  return resp
@@ -273,6 +304,53 @@ class Spec:
273
304
  return out
274
305
 
275
306
 
307
+ class Loader:
308
+ def __init__(self, server, namespace: str, domain):
309
+ self._server = server
310
+ self._namespace = namespace
311
+ self._domain = domain
312
+
313
+ def _chunk(self, start_i, end_i):
314
+ return self._server._raw(self._namespace, start_i, end_i)
315
+
316
+ def __len__(self):
317
+ return len(self._domain)
318
+
319
+ def _find_index_by_rational(self, value):
320
+ if value not in self._domain:
321
+ raise ValueError(f"Rational timestamp {value} is not in the domain")
322
+ return self._domain.index(value)
323
+
324
+ def __getitem__(self, index):
325
+ if isinstance(index, slice):
326
+ start = index.start if index.start is not None else 0
327
+ end = index.stop if index.stop is not None else len(self._domain)
328
+ assert start >= 0 and start < len(self._domain)
329
+ assert end >= 0 and end <= len(self._domain)
330
+ assert start <= end
331
+ num_frames = end - start
332
+ all_bytes = self._chunk(start, end - 1)
333
+ all_bytes_len = len(all_bytes)
334
+ assert all_bytes_len % num_frames == 0
335
+ return [
336
+ all_bytes[
337
+ i
338
+ * all_bytes_len
339
+ // num_frames : (i + 1)
340
+ * all_bytes_len
341
+ // num_frames
342
+ ]
343
+ for i in range(num_frames)
344
+ ]
345
+ elif isinstance(index, int):
346
+ assert index >= 0 and index < len(self._domain)
347
+ return self._chunk(index, index)
348
+ else:
349
+ raise TypeError(
350
+ "Invalid argument type for iloc. Use a slice or an integer."
351
+ )
352
+
353
+
276
354
  class YrdenServer:
277
355
  """A connection to a Yrden server"""
278
356
 
@@ -340,7 +418,9 @@ class YrdenServer:
340
418
 
341
419
  return r.json()
342
420
 
343
- def _export(self, pth, spec, sources, filters, arrays, fmt, encoder, encoder_opts):
421
+ def _export(
422
+ self, pth, spec, sources, filters, arrays, fmt, encoder, encoder_opts, format
423
+ ):
344
424
  req = {
345
425
  "spec": spec,
346
426
  "sources": sources,
@@ -352,6 +432,7 @@ class YrdenServer:
352
432
  "output_path": pth,
353
433
  "encoder": encoder,
354
434
  "encoder_opts": encoder_opts,
435
+ "format": format,
355
436
  }
356
437
 
357
438
  r = requests.post(f"http://{self._domain}:{self._port}/export", json=req)
@@ -360,6 +441,14 @@ class YrdenServer:
360
441
 
361
442
  return r.json()
362
443
 
444
+ def _raw(self, namespace, start_i, end_i):
445
+ r = requests.get(
446
+ f"http://{self._domain}:{self._port}/{namespace}/raw/{start_i}-{end_i}"
447
+ )
448
+ if not r.ok:
449
+ raise Exception(r.text)
450
+ return r.content
451
+
363
452
  def hls_js_url(self):
364
453
  """Return the link to the yrden-hosted hls.js file"""
365
454
  return f"http://{self._domain}:{self._port}/hls.js"
@@ -440,6 +529,9 @@ class Source:
440
529
  def ts(self):
441
530
  return self._src["ts"]
442
531
 
532
+ def __len__(self):
533
+ return len(self._src["ts"])
534
+
443
535
  def __getitem__(self, idx):
444
536
  if type(idx) != Fraction:
445
537
  raise Exception("Source index must be a Fraction")
@@ -1,4 +0,0 @@
1
- vidformer.py,sha256=qA5TAoLLhhtWjH9CTu3FfCFK3EKI-R1CapvnTuVSc0A,24944
2
- vidformer-0.5.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
3
- vidformer-0.5.0.dist-info/METADATA,sha256=nuIDLRFHysJF8KOhfM_OEx6FtmSr5zVfOkB9lBiMEMs,643
4
- vidformer-0.5.0.dist-info/RECORD,,