vidformer 0.1.0__py3-none-any.whl → 0.3.0__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.
|
3
|
+
Version: 0.3.0
|
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
|
@@ -13,3 +13,10 @@ Requires-Dist: numpy
|
|
13
13
|
|
14
14
|
# vidformer-py
|
15
15
|
|
16
|
+
## Publish
|
17
|
+
|
18
|
+
```bash
|
19
|
+
export FLIT_USERNAME='__token__' FLIT_PASSWORD='<token>'
|
20
|
+
flit publish
|
21
|
+
```
|
22
|
+
|
@@ -0,0 +1,4 @@
|
|
1
|
+
vidformer.py,sha256=hnFxf85IBD1dqaflKYcIE7bp4lYzg5jOCISSyXrvpZs,24520
|
2
|
+
vidformer-0.3.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
3
|
+
vidformer-0.3.0.dist-info/METADATA,sha256=38wZlgJ2NUTDZgsegDsJrfF6uLrxRK00Pn9IBRAjEUQ,523
|
4
|
+
vidformer-0.3.0.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.
|
3
|
+
__version__ = "0.3.0"
|
4
4
|
|
5
5
|
import subprocess
|
6
6
|
from fractions import Fraction
|
@@ -13,6 +13,8 @@ import sys
|
|
13
13
|
import multiprocessing
|
14
14
|
import uuid
|
15
15
|
import threading
|
16
|
+
import gzip
|
17
|
+
import base64
|
16
18
|
|
17
19
|
import requests
|
18
20
|
import msgpack
|
@@ -33,12 +35,12 @@ def _check_hls_link_exists(url, max_attempts=150, delay=0.1):
|
|
33
35
|
try:
|
34
36
|
response = requests.get(url)
|
35
37
|
if response.status_code == 200:
|
36
|
-
return
|
38
|
+
return response.text.strip()
|
37
39
|
else:
|
38
40
|
time.sleep(delay)
|
39
41
|
except requests.exceptions.RequestException as e:
|
40
42
|
time.sleep(delay)
|
41
|
-
return
|
43
|
+
return None
|
42
44
|
|
43
45
|
|
44
46
|
class Spec:
|
@@ -75,15 +77,15 @@ class Spec:
|
|
75
77
|
frames.append(frame)
|
76
78
|
return {"frames": frames}, s, f
|
77
79
|
|
78
|
-
def play(self, server,
|
80
|
+
def play(self, server, method="html"):
|
79
81
|
"""Play the video live in the notebook."""
|
80
82
|
|
81
|
-
from IPython.display import HTML
|
83
|
+
from IPython.display import IFrame, HTML
|
82
84
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
spec, sources, filters = self._to_json_spec()
|
86
|
+
spec_json_bytes = json.dumps(spec).encode("utf-8")
|
87
|
+
spec_obj_json_gzip = gzip.compress(spec_json_bytes, compresslevel=1)
|
88
|
+
spec_obj_json_gzip_b64 = base64.b64encode(spec_obj_json_gzip).decode("utf-8")
|
87
89
|
|
88
90
|
sources = [
|
89
91
|
{
|
@@ -103,18 +105,18 @@ class Spec:
|
|
103
105
|
}
|
104
106
|
arrays = []
|
105
107
|
|
106
|
-
print("Sending to server")
|
107
|
-
resp = server._new(
|
108
|
+
print(f"Sending to server. Spec is {len(spec_obj_json_gzip_b64)} bytes")
|
109
|
+
resp = server._new(spec_obj_json_gzip_b64, sources, filters, arrays, self._fmt)
|
108
110
|
hls_video_url = resp["stream_url"]
|
111
|
+
hls_player_url = resp["player_url"]
|
109
112
|
namespace = resp["namespace"]
|
110
|
-
|
111
|
-
if not keep_spec:
|
112
|
-
os.remove(spec_pth)
|
113
|
-
|
114
113
|
hls_js_url = server.hls_js_url()
|
115
114
|
|
116
|
-
|
117
|
-
|
115
|
+
if method == "iframe":
|
116
|
+
return IFrame(hls_player_url, width=1280, height=720)
|
117
|
+
if method == "html":
|
118
|
+
# We add a namespace to the video element to avoid conflicts with other videos
|
119
|
+
html_code = f"""
|
118
120
|
<!DOCTYPE html>
|
119
121
|
<html>
|
120
122
|
<head>
|
@@ -138,15 +140,23 @@ class Spec:
|
|
138
140
|
</body>
|
139
141
|
</html>
|
140
142
|
"""
|
141
|
-
|
143
|
+
return HTML(data=html_code)
|
144
|
+
else:
|
145
|
+
return hls_player_url
|
142
146
|
|
143
|
-
def save(self, server, pth,
|
147
|
+
def save(self, server, pth, encoder=None, encoder_opts=None):
|
144
148
|
"""Save the video to a file."""
|
145
149
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
assert encoder is None or type(encoder) == str
|
151
|
+
assert encoder_opts is None or type(encoder_opts) == dict
|
152
|
+
if encoder_opts is not None:
|
153
|
+
for k, v in encoder_opts:
|
154
|
+
assert type(k) == str and type(v) == str
|
155
|
+
|
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")
|
150
160
|
|
151
161
|
sources = [
|
152
162
|
{
|
@@ -166,10 +176,16 @@ class Spec:
|
|
166
176
|
}
|
167
177
|
arrays = []
|
168
178
|
|
169
|
-
resp = server._export(
|
170
|
-
|
171
|
-
|
172
|
-
|
179
|
+
resp = server._export(
|
180
|
+
pth,
|
181
|
+
spec_obj_json_gzip_b64,
|
182
|
+
sources,
|
183
|
+
filters,
|
184
|
+
arrays,
|
185
|
+
self._fmt,
|
186
|
+
encoder,
|
187
|
+
encoder_opts,
|
188
|
+
)
|
173
189
|
|
174
190
|
return resp
|
175
191
|
|
@@ -245,7 +261,7 @@ class Spec:
|
|
245
261
|
out["dve2_create_spec"] = end_t - start_t
|
246
262
|
|
247
263
|
start = time.time()
|
248
|
-
resp = server._export(pth, sources, filters, arrays, self._fmt)
|
264
|
+
resp = server._export(pth, sources, filters, arrays, self._fmt, None, None)
|
249
265
|
end = time.time()
|
250
266
|
out["dve2_exec"] = end - start
|
251
267
|
return out
|
@@ -270,11 +286,19 @@ class YrdenServer:
|
|
270
286
|
cmd = [bin, "yrden", "--port", str(self._port)]
|
271
287
|
if _in_notebook:
|
272
288
|
# We need to print the URL in the notebook
|
273
|
-
# This is
|
289
|
+
# This is a trick to get VS Code to forward the port
|
274
290
|
cmd += ["--print-url"]
|
275
291
|
self._proc = subprocess.Popen(cmd)
|
276
292
|
|
277
|
-
|
293
|
+
version = _check_hls_link_exists(f"http://{self._domain}:{self._port}/")
|
294
|
+
if version is None:
|
295
|
+
raise Exception("Failed to connect to server")
|
296
|
+
|
297
|
+
expected_version = f"vidformer-yrden v{__version__}"
|
298
|
+
if version != expected_version:
|
299
|
+
print(
|
300
|
+
f"Warning: Expected version `{expected_version}`, got `{version}`. API may not be compatible!"
|
301
|
+
)
|
278
302
|
|
279
303
|
def _source(self, name: str, path: str, stream: int, service):
|
280
304
|
r = requests.post(
|
@@ -310,9 +334,9 @@ class YrdenServer:
|
|
310
334
|
|
311
335
|
return r.json()
|
312
336
|
|
313
|
-
def _export(self, pth,
|
337
|
+
def _export(self, pth, spec, sources, filters, arrays, fmt, encoder, encoder_opts):
|
314
338
|
req = {
|
315
|
-
"spec":
|
339
|
+
"spec": spec,
|
316
340
|
"sources": sources,
|
317
341
|
"filters": filters,
|
318
342
|
"arrays": arrays,
|
@@ -320,6 +344,8 @@ class YrdenServer:
|
|
320
344
|
"height": fmt["height"],
|
321
345
|
"pix_fmt": fmt["pix_fmt"],
|
322
346
|
"output_path": pth,
|
347
|
+
"encoder": encoder,
|
348
|
+
"encoder_opts": encoder_opts,
|
323
349
|
}
|
324
350
|
|
325
351
|
r = requests.post(f"http://{self._domain}:{self._port}/export", json=req)
|
@@ -345,9 +371,9 @@ class SourceExpr:
|
|
345
371
|
|
346
372
|
def __repr__(self):
|
347
373
|
if self._is_iloc:
|
348
|
-
return f"{self._source.
|
374
|
+
return f"{self._source._name}.iloc[{self._idx}]"
|
349
375
|
else:
|
350
|
-
return f"{self._source.
|
376
|
+
return f"{self._source._name}[{self._idx}]"
|
351
377
|
|
352
378
|
def _to_json_spec(self):
|
353
379
|
if self._is_iloc:
|
@@ -511,6 +537,8 @@ class FilterExpr:
|
|
511
537
|
|
512
538
|
|
513
539
|
class UDF:
|
540
|
+
"""User-defined filter superclass"""
|
541
|
+
|
514
542
|
def __init__(self, name: str):
|
515
543
|
self._name = name
|
516
544
|
self._socket_path = None
|
vidformer-0.1.0.dist-info/RECORD
DELETED
@@ -1,4 +0,0 @@
|
|
1
|
-
vidformer.py,sha256=bLGZ4zQVkU6etFj0jWuJM8h0sJqcZXwkqA0VfdtCyk0,23257
|
2
|
-
vidformer-0.1.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
3
|
-
vidformer-0.1.0.dist-info/METADATA,sha256=2YNtgTcee8N9LM8lzMvNFLndbcNy88Fqk6mwFYhz8pQ,427
|
4
|
-
vidformer-0.1.0.dist-info/RECORD,,
|
File without changes
|