from datetime import datetime, date, time, timedelta import os import cv2 from wakepy import keep def five_minute_segment_from(the_time): # this is mocked out too be a one minute segment instead return the_time.replace(second=0, microsecond=0) #return the_time.replace(minute=(the_time.minute // 1)*1, second=0, microsecond=0) def path_to_video_at(time_stamp): return 'videos/' + str(time_stamp) + '.mkv' # mkv required for h264 encoding #delay for long delay long_delay = timedelta(minutes=1) last_time_stamp = five_minute_segment_from(datetime.now()) # live webcam feed camera = cv2.VideoCapture(0) if not camera.isOpened(): print("Cannot open camera") exit() # video writer fourcc = cv2.VideoWriter_fourcc(*'H264') video_writer = cv2.VideoWriter(path_to_video_at(last_time_stamp), fourcc, camera.get(cv2.CAP_PROP_FPS), (int(camera.get(3)),int(camera.get(4))), (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY) ) # video feed from previously captured video old_time = cv2.VideoCapture(path_to_video_at(last_time_stamp)) # fullscreen window yess good cv2.namedWindow("mirror", cv2.WINDOW_NORMAL) cv2.setWindowProperty("mirror", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) queue = [(False, None)] * 100 #queue of recent frames idx = 0 # current index into the frame queue short_term_delay_frames = 20 # hoow many frames back are we going in the buffer when we're on a short term delay? longterm = False # are we shoowing a long term delay? (versus a sshort term delay) #with keep.presenting(): while(True): if last_time_stamp != five_minute_segment_from(datetime.now()): # find file older than our long delay old_file = path_to_video_at(five_minute_segment_from(datetime.now() - long_delay - timedelta(minutes=1))) if os.path.isfile(old_file): print(f"deleting old file {old_file}") os.remove(old_file) video_writer.release() newly_recording_file = path_to_video_at(five_minute_segment_from(datetime.now())) print(f"opening {newly_recording_file} too record this upcoming ssegment to") video_writer = cv2.VideoWriter(newly_recording_file, fourcc, camera.get(cv2.CAP_PROP_FPS), (int(camera.get(3)), int(camera.get(4))), (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY) ) if old_time.isOpened(): old_time.release() new_file = path_to_video_at(five_minute_segment_from(datetime.now() - long_delay)) print(f"opening the previously recorded file {new_file} to read from for long mirror") old_time = cv2.VideoCapture(new_file, cv2.CAP_FFMPEG) last_time_stamp = five_minute_segment_from(datetime.now()) ret, frame = camera.read() frame = cv2.flip(frame, 1) # record the frame to the appropriate file, and also to the short term buffer video_writer.write(frame) queue[idx] = ret, frame prev_frame_valid, prev_frame = queue[(idx - short_term_delay_frames) % len(queue)] old_frame_valid, old_frame = old_time.read() if not longterm and prev_frame_valid: cv2.imshow('mirror', prev_frame) elif longterm and old_frame_valid: cv2.imshow('mirror', old_frame) key = cv2.waitKey(16) # listen for keyprress for 16 ms if key & 0xFF == ord('q') or key == 27: # q or esc break if key & 0xFF == ord('a'): short_term_delay_frames += 1 if key & 0xFF == ord('d'): short_term_delay_frames -= 1 if key & 0xFF == ord('z'): longterm = not longterm idx = (idx + 1) % len(queue) # After the loop release the cap object camera.release() old_time.release() video_writer.release() # Destroy all the windows cv2.destroyAllWindows()