Clean history, git LFS

This commit is contained in:
2025-07-05 15:36:34 +00:00
commit 70423ce723
141 changed files with 8484 additions and 0 deletions
@@ -0,0 +1,204 @@
+++
categories = ["software"]
tags = ["docker"]
date = 2024-04-18T17:00:33Z
description = ""
draft = false
slug = "ipcam-timelapse"
title = "📹 IP Camera Time-lapse in Frigate"
author = "nicholas"
+++
I have a container running `Frigate`, which captures and republishes a feed from my security camera overlooking the area beyond my deck. I will periodically capture a frame from this stream for some time, and compile the frames into time-lapses using `ffmpeg`
{{< image
src="images/ip-cam-mounted.JPG"
caption="IP camera mounted" >}}
{{< image
src="images/ip-cam-view.JPG"
caption="IP camera view of deck overlooking the neighborhood" >}}
## Docker Container - Frigate
As I mention above, I am already using `Frigate` to manage my IP camera stream for things like object detection, recording, and other such functions that are common in video management systems. The software lacks built-in features relating to time-lapses, but this is easily implemented through other means.
## Docker Compose
First, I include here the basic `docker-compose.yml` file that I use to get a `Frigate` container up and running. Not a lot of software configuration is defined here, this will mostly be done later in the frigate configuration file.
```yaml
services:
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "512mb"
devices:
- /dev/dri/renderD128 # for intel hwaccel
volumes:
- /etc/localtime:/etc/localtime:ro
- ${HOST_PATH_CONFIG}:/config
- ${HOST_PATH_MEDIA}:/media/frigate
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "${PORT}:5000"
- "8554:8554" # RTSP feeds
- "8555:8555/tcp" # WebRTC over tcp
- "8555:8555/udp" # WebRTC over udp
environment:
- FRIGATE_CAMERA_USER=${FRIGATE_CAMERA_USER}
- FRIGATE_CAMERA_PASSWORD=${FRIGATE_CAMERA_PASSWORD}
```
```
PORT=<port number>
HOST_PATH_CONFIG=<host path for config>
HOST_PATH_MEDIA=<host path for media>
```
This is my frigate configuration file config.yml. In this configuration, I am not recording or capturing snapshots of anything, which are major features of frigate. Instead I am using frigate to monitor the feed in real time and to periodically grab frames from the stream it publishes. In other words, it is superfluous to use frigate for the purpose of capturing frames. One could go straight to the source RTSP stream and circumvent the re-stream. But I do this anyway because sometimes I like to capture videos of squirrels and birds using frigate's object detection.
```yaml
ui:
live_mode: mse
mqtt:
enabled: false
go2rtc:
streams:
deck:
- rtsp://{FRIGATE_CAMERA_USER}:{FRIGATE_CAMERA_PASSWORD}@192.168.1.200:554//h265Preview_01_main
birdseye:
enabled: false
mode: continuous
cameras:
deck: # <------ Name the camera
objects:
track:
- person
- animal
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/deck
roles:
- record
- detect
hwaccel_args: preset-vaapi
input_args: -tag:v hvc1
output_args:
record: preset-record-generic-audio-copy
record:
enabled: false
events:
pre_capture: 2
post_capture: 2
objects:
- animal
snapshots: # <----- Enable snapshots
enabled: false
detect:
enabled: false
width: 3840
height: 2160
detectors:
ov:
type: openvino
device: AUTO
model:
path: /openvino-model/ssdlite_mobilenet_v2.xml
model:
width: 300
height: 300
input_tensor: nhwc
input_pixel_format: bgr
labelmap_path: /openvino-model/coco_91cl_bkgr.txt
labelmap:
15: animal
16: animal
17: animal
```
```shell
sudo docker compose up -d
```
# Time-lapse Parameters
The goal is to compress a month (30 days) of time into a minute.
## Clip Duration
The view from my deck is not so exciting, so I do not want time-lapse clip to last too long. I settled on 1 minute.
## Frame rate
I want the video to be very smooth, so I chose 60 frames per second. This should be plenty. I can change my mind when I generate a video using ffmpeg's -framerate {framerate} option because I am storing each individual frame as a .png file.
## Interval
The interval follows from the frame rate and clip duration. The interval is a function of clip duration and frame rate.
The relationship between these variables can be expressed:
duration = frames * framerate
interval = duration / framerate
# Capturing Frames from Frigate
```sh
#!/bin/sh
time=`date '+%Y_%m_%d__%H_%M_%S'`;
StorageFileName=$time.png
/usr/bin/ffmpeg -rtsp_transport tcp -i rtsp://<username>:<password>@<IP address>/Preview_<channel number>_<stream type> -ss 1 -frames:v 1 -update 1 <path>/$StorageFileName
```
Here we use ffmpeg to capture the frames and store them as png files according to the time it was captured. This script runs every 12 minutes via cron:
```sh
crontab -e
*/12 * * * * <path_to_timelapse.sh>
```
This is the command I use to generate a video.
```shell
ffmpeg -framerate 60 -pattern_type glob -i '*.png' -c:v libx265 -crf 28 -preset ultrafast -s 2k 28_ultrafast.mp4
```
{{< image
src="images/timelapse.gif"
caption="Timelapse" >}}
{{< video
src="videos/timelapse-multiday.mp4"
width="100%" >}}
{{< video
src="videos/timelapse-deck-planter.mp4"
width="100%" >}}
ReoLink RLC-810WA