|
@@ -17,6 +17,11 @@ try:
|
|
|
except ImportError:
|
|
|
logger.warning("RdRand is not available.")
|
|
|
|
|
|
+try:
|
|
|
+ from v4l2py.device import Device, VideoCapture
|
|
|
+except ImportError:
|
|
|
+ logger.warning("v4l2py is not available.")
|
|
|
+
|
|
|
tmp_dir = None
|
|
|
push_timeout = 10
|
|
|
|
|
@@ -169,10 +174,6 @@ def read_video(source, duration=60):
|
|
|
return extract_video(tmpf.name)
|
|
|
|
|
|
|
|
|
-def read_video2(source, _):
|
|
|
- raise NotImplementedError
|
|
|
-
|
|
|
-
|
|
|
def read_audio(source, duration=60):
|
|
|
tmpf = NamedTemporaryFile(suffix=".wav", mode=None, dir=tmp_dir)
|
|
|
|
|
@@ -217,9 +218,6 @@ def sample(source, source_type, multiplier=1):
|
|
|
sampler = read_video
|
|
|
multiplier *= 60
|
|
|
|
|
|
- case "video2":
|
|
|
- sampler = read_video2
|
|
|
-
|
|
|
case "audio":
|
|
|
sampler = read_audio
|
|
|
multiplier *= 60
|
|
@@ -251,11 +249,36 @@ def sample(source, source_type, multiplier=1):
|
|
|
return data
|
|
|
|
|
|
|
|
|
+def video2_sampler(q, source):
|
|
|
+ with Device.from_id(source) as device:
|
|
|
+ capture = VideoCapture(device)
|
|
|
+ capture.set_format(
|
|
|
+ device.info.frame_sizes[0].width, device.info.frame_sizes[0].height, "YUYV"
|
|
|
+ )
|
|
|
+
|
|
|
+ last = 0
|
|
|
+ for frame in device:
|
|
|
+ new = time.monotonic()
|
|
|
+
|
|
|
+ if new - last >= 1:
|
|
|
+ data = extract_lsbs(bytes(frame))
|
|
|
+ data = whiten(data)
|
|
|
+
|
|
|
+ logger.info(f"Sample ready: {len(data)}b.")
|
|
|
+
|
|
|
+ q.put(data)
|
|
|
+
|
|
|
+ last = new
|
|
|
+
|
|
|
+
|
|
|
def push(pool_url, data, secret):
|
|
|
logger.info(f"Pushing {len(data)}b.")
|
|
|
|
|
|
resp = requests.post(
|
|
|
- f"{pool_url}/api/pool", data=data, headers={"X-Secret": secret}, timeout=(push_timeout, push_timeout)
|
|
|
+ f"{pool_url}/api/pool",
|
|
|
+ data=data,
|
|
|
+ headers={"X-Secret": secret},
|
|
|
+ timeout=(push_timeout, push_timeout),
|
|
|
)
|
|
|
|
|
|
(logger.success if resp.status_code == 200 else logger.error)(
|
|
@@ -327,9 +350,17 @@ if __name__ == "__main__":
|
|
|
secret = f"{ident} {secret}"
|
|
|
|
|
|
q = queue.Queue()
|
|
|
- threading.Thread(
|
|
|
- target=puller, args=(q, args.source, args.source_type, args.multiplier)
|
|
|
- ).start()
|
|
|
+
|
|
|
+ pusher_th = threading.Thread(
|
|
|
+ target=pusher, args=(q, args.pool_url, secret, args.cooldown)
|
|
|
+ )
|
|
|
+
|
|
|
+ if args.source_type == "video2":
|
|
|
+ threading.Thread(target=video2_sampler, args=(q, args.source)).start()
|
|
|
+ else:
|
|
|
+ threading.Thread(
|
|
|
+ target=puller, args=(q, args.source, args.source_type, args.multiplier)
|
|
|
+ ).start()
|
|
|
|
|
|
pusher_th = threading.Thread(
|
|
|
target=pusher, args=(q, args.pool_url, secret, args.cooldown)
|