Skip to content

Instantly share code, notes, and snippets.

@Robadob
Last active October 14, 2023 16:45
Show Gist options
  • Save Robadob/4270726698f2412bb1020d6cc3f30f92 to your computer and use it in GitHub Desktop.
Save Robadob/4270726698f2412bb1020d6cc3f30f92 to your computer and use it in GitHub Desktop.
This script allows webcam images to be captured at random intervals to create a timelapse video
import cv2 # opencv-python
from datetime import datetime, timedelta
import time
import random
import re
import argparse
class CamContext:
def __init__(self):
self.cam = cv2.VideoCapture(0)
def __enter__(self):
return self.cam
def __exit__(self, exc_type, exc_value, traceback):
self.cam.release()
return False # Don't suppress exceptions
# Seed with current time
random.seed()
# arg parse
parser = argparse.ArgumentParser(
prog='Random Webcam Timelapse',
description='This script allows webcam images to be captured at random intervals to create a timelapse video')
parser.add_argument('--min', default=60, type=int, help="Minimum delay between captures (seconds)")
parser.add_argument('--max', default=120, type=int, help="Maximum delay between captures (seconds)")
parser.add_argument('--hours', default=1, type=int, help="Number of hours to execute for (combines with -m/--mins)")
parser.add_argument('--mins', default=0, type=int, help="Number of mins to execute for (combines with -h/--hours)")
parser.add_argument('--fps', default=24, type=int, help="Frames per second of the resulting video")
args = parser.parse_args()
min_wait = args.min
max_wait = args.max
end_time = datetime.now() + timedelta(hours=args.hours, minutes=args.mins)
print(f"Running for {args.hours}h{args.mins}m, with {min_wait}-{max_wait}s intervals.")
# Video output stream
out = None
while True:
# Sleep random (break if sleep would exceed end time)
sleep_time = random.randint(min_wait, max_wait)
if datetime.now() + timedelta(seconds=sleep_time) > end_time:
break
time.sleep(sleep_time)
# Capture image with cam 0 (and release cam again, to prevent blocking legit uses)
result = None
try:
with CamContext() as cam:
result, image = cam.read()
except Exception as e:
print(f"{datetime.now().isoformat()}: Failed to Enable Cam")
# If image was captured, write it out
if result:
if not out:
# Init output video
start_str = re.sub(r'[^\w_. -]', '', datetime.now().isoformat())
end_str = re.sub(r'[^\w_. -]', '', end_time.isoformat())
vid_path = f"{start_str}_{end_str}.mp4"
height, width, layers = image.shape
print(vid_path)
out = cv2.VideoWriter(vid_path, cv2.VideoWriter_fourcc(*'mp4v'), args.fps, (width,height))
out.write(image)
print(f"{datetime.now().isoformat()}: Captured Image")
else:
print(f"{datetime.now().isoformat()}: Failed to Capture Image")
if out:
out.release()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment