trap/trap/frame_emitter.py

51 lines
1.5 KiB
Python

from argparse import Namespace
import time
import cv2
import zmq
class FrameEmitter:
'''
Emit frame in a separate threat so they can be throttled,
or thrown away when the rest of the system cannot keep up
'''
def __init__(self, config: Namespace) -> None:
self.config = config
context = zmq.Context()
self.frame_sock = context.socket(zmq.PUB)
self.frame_sock.bind(config.zmq_frame_addr)
self.frame_sock.setsockopt(zmq.CONFLATE, 1) # only keep latest frame
def emit_video(self):
video = cv2.VideoCapture(str(self.config.video_src))
fps = video.get(cv2.CAP_PROP_FPS)
frame_duration = 1./fps
prev_time = time.time()
while True:
ret, frame = video.read()
# seek to 0 if video has finished. Infinite loop
if not ret:
video.set(cv2.CAP_PROP_POS_FRAMES, 0)
ret, frame = video.read()
assert ret is not False # not really error proof...
self.frame_sock.send(frame)
# defer next loop
new_frame_time = time.time()
time_diff = (new_frame_time - prev_time)
if time_diff < frame_duration:
time.sleep(frame_duration - time_diff)
new_frame_time += frame_duration - time_diff
else:
prev_time = new_frame_time
def run_frame_emitter(config: Namespace):
router = FrameEmitter(config)
router.emit_video()