Skip to content

TinyTimelapseCam - Mini Delay Camera Based on ESP32-S3

This is a mini delay camera based on ESP32-S3 that allows you to capture the drifting clouds during the day, the celestial movements throughout the night, and the diverse array of people on city streets.

Deploying the Network Camera

Please refer to the Camera Usage section for deployment details. We won't delve into it here.

Testing with Python to Access the Stream
# Import the OpenCV library
import cv2

# Define the camera URL
camera_url = ""

# Create a VideoCapture object
cap = cv2.VideoCapture(camera_url)

# Check if the camera is successfully opened
if not cap.isOpened():
    print("Unable to connect to the camera. Please check the camera URL or network connection.")

while True:
    # Read a frame
    ret, frame =

    # Check if the frame is successfully read
    if not ret:
        print("Unable to get a frame.")

    # Display the preview
    cv2.imshow('Camera Preview', frame)

    # Press 'q' to exit the preview
    if cv2.waitKey(1) & 0xFF == ord('q'):

# Release resources

Please note that the streaming address is the original IP followed by :81/stream as a suffix. You can also right-click on the real-time video display on the web page to copy the streaming address.

Delay Camera

If the streaming test was successful, you can now try the following program for the delay camera:
import cv2
import numpy as np
import time
import os

nframes = 500  # Number of photos to take
interval = 0.00001  # Time interval (seconds)

# Change to the IP address of your ESP32
cap = cv2.VideoCapture('')

print("Delay camera is starting")
for i in range(nframes):
    # Capture an image frame
    ret, img =
    # Save the image file
    if img is None:
        print("Unable to capture an image")
        cv2.imwrite('temp_destination/photos/img_' +
                    str(i + 1000).zfill(4) + '.png', img)
    # Wait for a period of time
    print("Photo number:", i)
# Define the path for the photo folder
photos_path = "temp_destination/photos/"
# Create the folder if it doesn't exist
os.makedirs(photos_path, exist_ok=True)
# Retrieve the list of photo file names
photos = os.listdir(photos_path)
# Sort photos by name
# Create a video writing object
video = cv2.VideoWriter("temp_destination/video.avi",
                        cv2.VideoWriter_fourcc(*"MJPG"), 100, (1280, 720))

# Iterate through the photos
for photo in photos:
    # Read the photo as an image
    image = cv2.imread(photos_path + photo)
    # Resize the image to fit the video frame size
    image = cv2.resize(image, (1280, 720))
    # Write the image to the video

# Release the video writing object
print("Time-lapse video generation completed")

After running the program, you can find the generated video in the temp_destination folder. You can also modify the nframes and interval parameters to make the time-lapse camera suitable for different shooting scenarios.

Troubleshooting and Suggestions

  • If the live feed can be displayed on the web but cannot be captured locally, it's because only one stream can be opened at a time. Try closing the web page.
  • If you intend to capture a video for an entire day, consider running the Python program on a low-power server or an old smartphone to avoid keeping your computer on all the time.

References and Acknowledgments

Original: This post is protected by CC BY-NC-SA 4.0 agreement, should be reproduced with attribution. ```

Please note that I've translated the content while maintaining the original markdown format. If you have any further questions or need additional assistance, please feel free to ask.

This post is translated using ChatGPT, please feedback if any omissions.