Simple home security video system 09 April 2023 on Krystian's Keep

This page covers setting up a simple multicamera home security system with two features:

Live view.

Live view.

Camera box rev. 1

Camera box rev. 1

Camera box rev. 2

Camera box rev. 2

The system consists of multiple Raspberry Pi devices connected to a common local network. It’s recommended but not required to make a separate home network for this purpose. One device called the hub receives video streams and produces seekable HLS streams and at the same time saves video segments to disk. Other devices called camera devices transmit video streams from a camera to the hub device. The idea is that the hub device is installed inside and camera devices are mounted outside in electrical boxes with Ethernet and PoE.

I have a system like this deployed with 2 camera devices and 1 hub device. It’s working well.

Camera devices

Repeat the following steps for every camera device.

Hardware

Parts:

Tools:

Wiring: TODO

Software

We will use the firmware interface for communication with the Raspberry Pi camera. It’s because the new blob-free libcamera interface is still experimental and I wasn’t able to get it to work on Alpine Linux.

Download files with firmware blobs that contain camera drivers and codecs. But first, to edit OS files, the partition needs to be remounted read-write.

mount /media/mmcblk0p1 -o rw,remount
apk add curl
curl 'https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start_x.elf' > /media/mmcblk0p1/start_x.elf
curl 'https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/fixup_x.dat' > /media/mmcblk0p1/fixup_x.dat

Instruct to load firmware to the VideoCore GPU before boot.

echo "start_file=start_x.elf" >> /media/mmcblk0p1/config.txt
echo "fixup_file=fixup_x.dat" >> /media/mmcblk0p1/config.txt

If your camera is already connected, just reboot. Of not, poweroff, disconnect power, connect camera and connect power.

Verification

After reboot, verify if you are able to obtain images from the camera.

apk add raspberrypi
/opt/vc/bin/raspivid -t 0

You should be able to see a video feed via Pi’s HDMI.

Raspivid service

We will use raspivid’s tcp output to send live video to the camera hub device.

Create /etc/init.d/raspivid with the following contents.

#!/sbin/openrc-run

name=raspivid
command="/opt/vc/bin/$name"
command_args="$raspivid_opts"
command_user="raspivid:raspivid"
supervisor=supervise-daemon
respawn_delay=1
respawn_max=0

depend() {
	need net
	after firewall
}

start_pre() {
	[ -n "$output_log" ] && checkpath -f "$output_log" \
		-m 644 -o raspivid:raspivid
	[ -n "$error_log" ] && checkpath -f "$error_log" \
		-m 644 -o raspivid:raspivid
}

Make it executable and add this file to LBU.

chmod +x /etc/init.d/raspivid
lbu add /etc/init.d/raspivid

Create /etc/conf.d/raspivid with the following contents. These parameters can be tuned. Set the --output to the address of your hub device and adjust the --annotate option to reflect the name of the camera.

The H264 encoder that raspivid uses is limited to 1920x1080 px resolution. In order to use higher resolutions one needs to use MJPEG instead.

raspivid_opts=" \
	--nopreview \
	--output tcp://192.168.1.10:8083 \
	--timeout 0 \
	--flush \
	--codec H264 \
	--rotation 180 \
	--mode 4 \
	--annotate $(( 1024 | 8 | 4 )) \
	--annotate '%Y-%m-%d %X ROAD' \
	--bitrate 0 \
	--width 1640 \
	--height 1232 \
	--qp 25 \
	--framerate 15 \
"

output_log=/var/log/raspivid.log
error_log=/var/log/raspivid.log

Add required raspivid user and add it to video group.

addgroup -S raspivid
adduser -SDh/dev/null -s/sbin/nologin -Graspivid -graspivid raspivid raspivid
adduser raspivid video

Start the service, enable starting it on boot and save changes.

rc-service raspivid start
rc-update add raspivid
lbu commit -d

Hub devices

Firewall

Allow traffic on the following ports in the firewall configuration:

FFmpeg service

Create /etc/init.d/homesec with mode 755:

#!/sbin/openrc-run

name=homesec
command="/usr/bin/ffmpeg"
command_args="$ffmpeg_opts"
command_user="homesec:homesec"
supervisor=supervise-daemon
respawn_delay=1
respawn_max=0

depend() {
	need net
	after firewall
}

start_pre() {
	[ -n "$output_log" ] && checkpath -f "$output_log" \
		-m 644 -o homesec:homesec
	[ -n "$error_log" ] && checkpath -f "$error_log" \
		-m 644 -o homesec:homesec
}

Create user homesec and group homesec.

For each camera create /etc/conf.d/homesec-cameraname:

ffmpeg_opts="-loglevel warning \
	-r 15 \
	-i tcp://192.168.1.10:8082?listen \
	-c copy \
	-f segment \
	-segment_time 00:15:00 \
	-segment_atclocktime 1 \
	-strftime 1 \
	/media/hdd/recordings/%Y-%m-%dT%H:%M:%S_cameraname.h264 \
	-c copy \
	-hls_time 1 \
	-hls_list_size 900 \
	/var/www/homesec/cameraname.m3u8 \
"

output_log=/var/log/homesec-cameraname.log
error_log=/var/log/homesec-cameraname.log

Web streaming

apk add nginx
rc-service nginx start
rc-update add nginx
server {
	listen 80 default_server;
	listen [::]:80 default_server;

	root /var/www/homesec/;

	location / {}
}
<!DOCTYPE html>
<link href="video-js.min.css" rel="stylesheet">
<script src="video.min.js"></script>
<style>
html, body {
  height: 100%;
  margin: 0;
}
video, .video-js {
  width: 100%;
  height: 50%;
}
</style>

<video class="video-js" controls autoplay muted data-setup='{"liveui": true}'>
  <source src="camera1name.m3u8" type="application/x-mpegURL">
  <p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
</video>

<video class="video-js" controls autoplay muted data-setup='{"liveui": true}'>
  <source src="camera2name.m3u8" type="application/x-mpegURL">
  <p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
</video>

Samba

[homesec]
path = /mnt/homesec/
apk add samba-server samba

TODO

Articles from blogs I read

Writing a Unix clone in about a month

I needed a bit of a break from “real work” recently, so I started a new programming project that was low-stakes and purely recreational. On April 21st, I set out to see how much of a Unix-like operating system for x86_64 targets that I could put together in …

via Drew DeVault's blog May 24, 2024

Czy na pewno wiesz, czym jest feminizm? – recenzja książki „Femynizm” Martyny Kaczmarek

Dziś książka dla tych, którzy nie mają zbyt dużej wiedzy o feminizmie lub chcą swoją wiedzę uporządkować. „Femynizm” Martyny Kaczmarek jest dobrą lekturą dla osób, które za feministów ani feministki się nie uważają oraz dla osób, które coś tam niby wiedzą…

via Powiedziała, co wiedziała May 21, 2024

Status update, May 2024

Hi! Sadly, I need to start this status update with bad news: SourceHut has decided to terminate my contract. At this time, I’m still in the process of figuring out what I’ll do next. I’ve marked some SourceHut-specific projects as unmaintained, such as sr.ht-…

via emersion May 21, 2024

Generated by openring