Photo by Bernadette Wurzinger
minigugl is a little video streaming client to read an MJPEG video stream and store it in chunks (segments) locally as H.264-encoded video files. It's highly configurable and the perfect little helper to continuously record videos to file (e.g., for dashcams or security cameras).
This project uses poetry for Python dependency management and requires Python 3.6.1+, but no newer than Python 3.7.x due to its dependencies. pyenv is a great tool to manage different Python versions.
It furthermore requires FFmpeg for video encoding/decoding.
minigugl uses the fantastic Python video processing framework called vidgear to read an MJPEG stream with VideoGear and process it through FFmpeg with WriteGear.
Video frames are augmented with text using OpenCV. This includes timestamps using arrow and optionally GPS coordinates using gpsd, e.g., using a Globalsat BU-353S4 GPS USB Receiver.
- Clone the GitHub repo:
git clone git@github.com:FraBle/minigugl.git - Inside
minigugldirectory, runpoetry install --no-rootto install dependencies.- Use
poetry install --no-root --extras gpsto install it with GPS tooling.
- Use
minigugl uses pydantic's settings management and provides defaults for all parameters except OUTPUT_DIR and VIDEO_SOURCE.
The following parameters can be passed in as environment variables. Alternatively, you can use a .env file as well.
| Environment Variable | Type | Required | Default |
|---|---|---|---|
OUTPUT_DIR |
str |
Yes | |
VIDEO_SOURCE |
str |
Yes | |
DEBUG |
bool |
No | False |
LOG_FORMAT |
str |
No | provided |
LOG_LEVEL |
str |
No | "info" |
ENABLE_GPS |
bool |
No | False |
GPS_INTERVAL_SEC |
float or int |
No | 0.1 |
ANNOTATION_FONT_HEIGHT |
int |
No | 15 |
ANNOTATION_MARGIN |
int |
No | 5 |
ANNOTATION_PADDING |
int |
No | 5 |
VIDEO_CODEC |
str |
No | "libx264" |
VIDEO_FRAMERATE |
int |
No | 24 |
VIDEO_HEIGHT |
int |
No | 480 |
VIDEO_SEGMENT_LENGTH_SEC |
int |
No | 60 |
VIDEO_WIDTH |
int |
No | 640 |
With all required environment variables set, execute the following code inside the repo directory to start the video streaming client:
poetry run python -m minigugl.clientBased on
These steps have been verified with a Raspberry Pi 3B+ running DietPi with the following DietPi-optimised software installed:
[ ] 0 OpenSSH Client: Feature-rich SSH, SFTP and SCP client
[ ] 16 Build-Essentials: common packages for compiling
[ ] 17 Git Client: Clone and manage Git repositories locally
[ ] 103 DietPi-RAMlog: minimal, optimised logging
[ ] 104 Dropbear: Lightweight SSH server
Changes applied to dietpi.txt for easier, headless setup:
AUTO_SETUP_ACCEPT_LICENSE=1
AUTO_SETUP_LOCALE=en_US.UTF-8
AUTO_SETUP_KEYBOARD_LAYOUT=us
AUTO_SETUP_TIMEZONE=America/Los_Angeles
AUTO_SETUP_NET_WIFI_ENABLED=1
AUTO_SETUP_NET_WIFI_COUNTRY_CODE=US
AUTO_SETUP_NET_HOSTNAME=<custom hostname>
AUTO_SETUP_HEADLESS=1
AUTO_SETUP_AUTOSTART_TARGET_INDEX=7
AUTO_SETUP_AUTOMATED=1
AUTO_SETUP_GLOBAL_PASSWORD=<custom password>
AUTO_SETUP_INSTALL_SOFTWARE_ID=0 #OpenSSH Client
AUTO_SETUP_INSTALL_SOFTWARE_ID=16 #Build-Essentials
AUTO_SETUP_INSTALL_SOFTWARE_ID=17 #Git
AUTO_SETUP_INSTALL_SOFTWARE_ID=103 #DietPi-RAMlog
AUTO_SETUP_INSTALL_SOFTWARE_ID=104 #Dropbear
CONFIG_BOOT_WAIT_FOR_NETWORK=2Changes applied to config.txt for camera setup:
#-------RPi camera module-------
start_x=1
#disable_camera_led=1
#-------GPU memory splits-------
gpu_mem_256=128
gpu_mem_512=128
gpu_mem_1024=128Don't forget to set aWIFI_SSID[0] and aWIFI_KEY[0] in dietpi-wifi.txt.
Once the Raspberry Pi comes up and is connected to the WiFi, follow these steps:
-
Install
v4l2rtspserversudo apt install -y cmake liblog4cpp5-dev libv4l-dev cd /tmp git clone https://github.com/mpromonet/v4l2rtspserver.git cd /tmp/v4l2rtspserver cmake . make sudo make install
-
Install
v4l-utilsfor debugging & control commandssudo apt install v4l-utils
Example "rotatation of camera":
v4l2-ctl --set-ctrl=rotate=90
-
Add
v4l2-ctlcommand to system boot viaudevsubsystemsudo nano /etc/udev/rules.d/99-local-webcam.rules:SUBSYSTEM=="video4linux", PROGRAM="/usr/bin/v4l2-ctl --set-ctrl=rotate=90" -
Add
bcm2835-v4l2to/etc/modules(kernel modules to load at boot time)sudo nano /etc/modules:# Add to the end of the file bcm2835-v4l2 -
Set parameters for
bcm2835-v4l2by creating a config file:sudo nano /etc/modprobe.d/bcm2835-v4l2.conf:options bcm2835-v4l2 max_video_width=640 options bcm2835-v4l2 max_video_height=480 -
Reboot Raspberry Pi with
rebootand test the setup by startingv4l2rtspserverwith open source V4L2 driverbcm2835-v4l2v4l2-ctl --all # should print driver and device info with set resolution v4l2rtspserver -W640 -H480 -F30 -P8555 /dev/video0 # start RTSP server manually
-
Testing H264 RTSP video stream, e.g. with VLC from a MacBook
vlc rtsp://<rpi-ip>:8555/unicast
-
Add
v4l2rtspserverstart-up scriptCreate start-up script
sudo nano /usr/local/bin/start-rtsp-server:#!/bin/bash v4l2rtspserver -W640 -H480 -F30 -P8555 /dev/video0Add execution rights with
sudo chmod +x /usr/local/bin/start-rtsp-server. -
Add
v4l2rtspserverto systemdCreate systemd entry
sudo nano /lib/systemd/system/v4l2rtspserver.service:[Unit] Description=V4L2 RTSP server After=network.target [Service] Type=simple ExecStart=/usr/local/bin/start-rtsp-server Restart=always RestartSec=1 StartLimitIntervalSec=0 [Install] WantedBy=multi-user.target
Enable
v4l2rtspserver.servicesudo systemctl daemon-reload sudo systemctl enable v4l2rtspserver.service sudo systemctl start v4l2rtspserver.service -
Reboot Raspberry Pi with
rebootand confirm everything starts automaticallyOpen H264 RTSP video stream, e.g. with VLC from a MacBook:
vlc rtsp://<rpi-ip>:8555/unicast
If you encounter an error such as
root@guglhupf-agent-2:~# /usr/local/bin/start-rtsp-server
2021-04-24 16:24:49,091 [NOTICE] - /tmp/v4l2rtspserver/main.cpp:294
Version: 0.2.3-26-gd0da079 live555 version:2021.04.06
2021-04-24 16:24:49,092 [NOTICE] - /tmp/v4l2rtspserver/src/V4l2RTSPServer.cpp:36
Create V4L2 Source.../dev/video0
2021-04-24 16:24:49,092 [NOTICE] - /tmp/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:49
Device /dev/video0
VIDIOC_REQBUFS: Inappropriate ioctl for device
2021-04-24 16:24:49,092 [NOTICE] - /tmp/v4l2rtspserver/v4l2wrapper/src/V4l2MmapDevice.cpp:141
Device /dev/video0
VIDIOC_STREAMOFF: Inappropriate ioctl for device
VIDIOC_REQBUFS: Inappropriate ioctl for device
...restart the picamera, e.g. using dietpi-config (under 1 : Display Options).
-
Install
gpsdpackagesapt install gpsd gpsd-clients
-
Edit gpsd config (setting
DEVICES,GPSD_OPTIONS, andGPSD_SOCKET)nano /etc/default/gpsd
/etc/default/gpsdfor reference:# Default settings for the gpsd init script and the hotplug wrapper. # Start the gpsd daemon automatically at boot time START_DAEMON="true" # Use USB hotplugging to add new USB devices automatically to the daemon USBAUTO="true" # Devices gpsd should collect to at boot time. # They need to be read/writeable, either by user gpsd or the group dialout. DEVICES="/dev/ttyUSB0" # Other options you want to pass to gpsd # "-n: Don't wait for a client to connect before polling whatever GPS is associated with it." GPSD_OPTIONS="-n" GPSD_SOCKET="/var/run/gpsd.sock" -
Enable the gpsd service
systemctl enable gpsd.socket systemctl start gpsd.socket -
Verify GPS connection by running
gpsmonand/orcgps