a webcam with a 5 second, 30 minute, or 24 hour delay
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.6 KiB

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):
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'
#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_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
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()