from datetime import datetime, date, time, timedelta import os import cv2 import gpiod import math from gpiod.line import Direction, Value #from wakepy import keep def 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) + '.mp4' # mkv required for h264 encoding #delay for long delay long_delay = timedelta(minutes=1) last_time_stamp = minute_segment_from(datetime.now()) # live webcam feed camera = cv2.VideoCapture("/dev/video0") if not camera.isOpened(): print("Cannot open camera") exit() # video writer fourcc = cv2.VideoWriter_fourcc(*'mp4v') camera.set(cv2.CAP_PROP_FPS, 60.0) camera_fps = camera.get(cv2.CAP_PROP_FPS) camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) video_writer = cv2.VideoWriter(path_to_video_at(last_time_stamp), fourcc, camera_fps, (int(camera.get(3)),int(camera.get(4))), #resolution (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY) ) # video feed from previously captured video twenty_four_hours_ago = cv2.VideoCapture(path_to_video_at(last_time_stamp - timedelta(hours=24))) twelve_hours_ago = cv2.VideoCapture(path_to_video_at(last_time_stamp - timedelta(hours=12))) five_minutes_ago = cv2.VideoCapture(path_to_video_at(last_time_stamp - timedelta(minutes=5))) # fullscreen window yess good cv2.namedWindow("mirror", cv2.WINDOW_NORMAL) cv2.setWindowProperty("mirror", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) queue = [(False, None)] * math.floor(camera_fps * 32) #queue of 32 seconds of frames idx = 0 # current index into the frame queue lines = { "five_second": 2, "thirty_second": 3, "five_minute": 4, "twelve_hour": 5, "twenty_four_hour": 6 } input_line = gpiod.LineSettings(direction=Direction.INPUT) #with keep.presenting(): with gpiod.request_lines( "/dev/gpiochip4", consumer="mirror-to-yesterday", config={ lines["five_second"]: input_line, lines["thirty_second"]: input_line, lines["five_minute"]: input_line, lines["twelve_hour"]: input_line, lines["twenty_four_hour"]: input_line, } ) as io_lines: while(True): if last_time_stamp != minute_segment_from(datetime.now()): # find file older than our long delay oldest_file_path = path_to_video_at(minute_segment_from(datetime.now() - timedelta(hours=24) - timedelta(minutes=10))) if os.path.isfile(oldest_file_path): print(f"deleting old file {oldest_file_path}") os.remove(oldest_file_path) video_writer.release() newly_recording_file_path = path_to_video_at(minute_segment_from(datetime.now())) print(f"opening {newly_recording_file_path} too record this upcoming ssegment to") video_writer = cv2.VideoWriter(newly_recording_file_path, fourcc, camera_fps, (int(camera.get(3)), int(camera.get(4))), (cv2.VIDEOWRITER_PROP_HW_ACCELERATION, cv2.VIDEO_ACCELERATION_ANY) ) if twenty_four_hours_ago.isOpened(): twenty_four_hours_ago.release() twenty_four_hours_ago = cv2.VideoCapture(path_to_video_at(minute_segment_from(datetime.now() - timedelta(hours=24)))) if twelve_hours_ago.isOpened(): twelve_hours_ago.release() twelve_hours_ago = cv2.VideoCapture(path_to_video_at(minute_segment_from(datetime.now() - timedelta(hours=12)))) if five_minutes_ago.isOpened(): five_minutes_ago.release() five_minutes_ago = cv2.VideoCapture(path_to_video_at(minute_segment_from(datetime.now() - timedelta(minutes=5)))) last_time_stamp = 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 frames = { "five_second": queue[(idx - math.floor(5*camera_fps)) % len(queue)], "thirty_second": queue[(idx - math.floor(30*camera_fps)) % len(queue)], "five_minute": five_minutes_ago.read(), "twelve_hour": twelve_hours_ago.read(), "twenty_four_hour": twenty_four_hours_ago.read(), } #valid, the_frame = frames.five_second if not io_lines.get_value(lines["twenty_four_hour"]): valid, the_frame = frames["twenty_four_hour"] elif not io_lines.get_value(lines["twelve_hour"]): valid, the_frame = frames["twelve_hour"] elif not io_lines.get_value(lines["five_minute"]): valid, the_frame = frames["five_minute"] elif not io_lines.get_value(lines["thirty_second"]): valid, the_frame = frames["thirty_second"] else: #if not io_lines.get_value(lines.five_second) valid, the_frame = frames["five_second"] if valid: cv2.imshow("mirror", the_frame) idx = (idx + 1) % len(queue) key = cv2.waitKey(16) # listen for keyprress for 16 ms if key & 0xFF == ord('q') or key == 27: # q or esc break # After the loop release the cap object camera.release() video_writer.release() twenty_four_hours_ago.release() twelve_hours_ago.release() five_minutes_ago.release() # Destroy all the windows cv2.destroyAllWindows()