vidformer 0.5.0__py3-none-any.whl → 0.5.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
|
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
|
-
|
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
|
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(
|
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")
|
vidformer-0.5.0.dist-info/RECORD
DELETED
@@ -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,,
|
File without changes
|