diff --git a/displayarray/frame/frame_publishing.py b/displayarray/frame/frame_publishing.py index 044be1c..e96370f 100644 --- a/displayarray/frame/frame_publishing.py +++ b/displayarray/frame/frame_publishing.py @@ -147,7 +147,6 @@ def pub_cam_loop_opencv( sub = subscriber_dictionary.cam_cmd_sub(name) sub.return_on_no_data = "" msg = "" - if mjpg: try: cam.set(cv2.CAP_PROP_FOURCC, cv2.CAP_OPENCV_MJPEG) @@ -158,6 +157,7 @@ def pub_cam_loop_opencv( cam.set(cv2.CAP_PROP_FRAME_HEIGHT, request_size[1]) if not cam.isOpened(): + print("camera failed to open") subscriber_dictionary.CV_CAMS_DICT[name].status_pub.publish("failed") return False now = time.time() @@ -168,13 +168,18 @@ def pub_cam_loop_opencv( if ret is False or not isinstance(frame, (np.ndarray, list)): cam.release() subscriber_dictionary.CV_CAMS_DICT[name].status_pub.publish("failed") + print("cam returned false") return False if cam.get(cv2.CAP_PROP_FRAME_COUNT) > 0: frame_counter += 1 if frame_counter >= cam.get(cv2.CAP_PROP_FRAME_COUNT): frame_counter = 0 cam = cv2.VideoCapture(cam_id) - subscriber_dictionary.CV_CAMS_DICT[name].frame_pub.publish(frame) + try: + subscriber_dictionary.CV_CAMS_DICT[name].frame_pub.publish(frame) + except KeyError: # we got deleted. Time to exit. + cam.release() + return False msg = sub.get() sub.release() @@ -195,9 +200,10 @@ def pub_cam_thread( """Run pub_cam_loop in a new thread. Starts on creation.""" name = uid_for_source(cam_id) + t = None if name in uid_dict.keys(): t = uid_dict[name] - else: + if t is None or not t.is_alive(): # Enables reopening cameras if "cv" in force_backend.lower(): pub_cam_loop = pub_cam_loop_opencv elif ( diff --git a/displayarray/frame/subscriber_dictionary.py b/displayarray/frame/subscriber_dictionary.py index 11f7d97..137d1b0 100644 --- a/displayarray/frame/subscriber_dictionary.py +++ b/displayarray/frame/subscriber_dictionary.py @@ -50,6 +50,11 @@ def stop_cam(cam_id: Union[int, str]): if str(cam_id) in CV_CAM_HANDLERS_DICT: CV_CAM_HANDLERS_DICT[str(cam_id)].cmd_pub.publish("quit", blocking=True) +def del_cam(cam_id: Union[int, str]): + if str(cam_id) in CV_CAMS_DICT: + del CV_CAMS_DICT[str(cam_id)] + if str(cam_id) in CV_CAM_HANDLERS_DICT: + del CV_CAM_HANDLERS_DICT[str(cam_id)] def cam_cmd_sub(cam_id, blocking=True): """Get a command subscriber for registered camera "cam_id".""" diff --git a/displayarray/window/subscriber_windows.py b/displayarray/window/subscriber_windows.py index 03b632c..8128711 100644 --- a/displayarray/window/subscriber_windows.py +++ b/displayarray/window/subscriber_windows.py @@ -112,6 +112,7 @@ class SubscriberWindows(object): def __stop_all_cams(self): for c in self.source_names: subscriber_dictionary.stop_cam(c) + subscriber_dictionary.del_cam(c) def handle_keys(self, key_input: int): """Capture key input for the escape function and passing to key control subscriber threads.""" @@ -214,7 +215,6 @@ class SubscriberWindows(object): def update_frames(self): """Update the windows with the newest data for all frames.""" self.frames = {} - for i in range(len(self.input_vid_global_names)): if self.input_vid_global_names[i] in self.FRAME_DICT and not isinstance( self.FRAME_DICT[self.input_vid_global_names[i]], NoData