Skip to content

Instantly share code, notes, and snippets.

@tklam
Created September 22, 2019 15:00
Show Gist options
  • Save tklam/47f178a3fe87a4b52705f2771130622c to your computer and use it in GitHub Desktop.
Save tklam/47f178a3fe87a4b52705f2771130622c to your computer and use it in GitHub Desktop.
Raspberry Pi Zero W as a body cam
# Readme for developers
## Hardware
+ Raspberry Pi Zero W
+ Pi Camera NOIR V2 (use regular Pi Camera if false colour is unacceptable or
night vision is not required)
## Software
+ OS: Kali linux for ARM
+ 99% of components are already available in the stock image. Additional
required packages include:
+ raspivid
+ hostapd
+ dnsmasq
+ The system will create a WiFi acecss point after boot up
## Recording Video
### How to record a video?
The system will start recording as soon as a USB memory stick of the
appropriate format is pluged in.
1. Power on the system
2. Plug in the USB memory stick with an ext2/ext3/ext4/exfat/FAT* Linux partition.
* If FAT is used, no files can be larger than 4GB.
3. The system will identify the USB memory stick inserted, and save the
encrypted videos on its first partition (which is mounted at */root/usb*)
### How to retrieve the recorded videos?
1. Connect to the Pi0W's WiFi access point
2. Copy the video files via ssh using _rsync_ or _scp_:
```
rsync -avz -e 'ssh' [email protected]:usb/*.h264 .
```
Alternatively, you can power off the body camera system, and then mount the
USB memory stick onto other computers.
3. Decrypt the videos in the machine containing the privae key:
```
gpg -d a.h264 > video1-1841.01.26.h264
gpg -d a.h264 > video2-1841.01.26.h264
```
### How is plug-n-play implemented?
1. Create a udev rule as `/etc/udev/rules.d/10-usbmount.rules' with the following content:
```
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", RUN+="/usr/bin/systemctl --no-block restart raspivid-record-@%k.service"
```
2. Create `/etc/systemd/system/raspivid-record-\@.service`:
```
[Unit]
Description=Record video using raspivid with predefined parameters and encryptio n
BindsTo=dev-%i.device
[Service]
Type=simple
ExecStart=/root/scripts/raspivid_stream.sh %I
```
3. Then, the script `/root/scripts/raspivid_stream.sh` will be invoked whenever
a USB memory stick is inserted into the system and is mounted successfully.
### The recording script
```bash
#!/bin/bash
(
killall -9 raspivid
umount /root/usb
usb_device="/dev/${1}1"
echo "Trying to use dev: $usb_device"
echo " Fixing $usb_device"
fsck -a $usb_device
echo " Remounting $usb_device"
mkdir -p /root/usb
mount $usb_device /root/usb
ls /root/usb
if [ ! -e /root/usb/ ]; then
echo "Cannot find /root/usb/ "
exit -1
fi
echo "Start recording in 2 s"
current_time=`date +'%Y.%m.%d.%H.%M.%S'`
sleep 2
video_filename="/root/usb/video-${current_time}.h264"
mv --backup=t $video_filename ${video_filename}.bak
raspivid -t 0 -n \
-b 0 -fps 24 \
-vs \
-qp 30 \
-drc med \
-a 12 \
-o - \
| gpg -e -r 'Justice' > $video_filename
) > /root/raspivide.service.log 2>&1
```
This script accepts the device name of the USB memory stick as a parameter. It performs:
1. Try to fix and mount the USB memory stick inserted at /root/usb
2. Use `raspivid` to record video
3. Pipe the output of `raspivid` to `gpg` to encrypt the recorded video on the fly
4. Store the video in `/root/usb`
## Known Issues
1. It seems Raspberry Pi Zero W cannot connect to WiFi with channel 13. That
is why I decided to make the body camera system serve as a WiFi access point
instead of a WiFi client. This makes upgrading the system a bit inconvenient.
2. The WiFi speed is insufficient for streaming the recorded video in WLAN
## TODO
1. Better security
2. Better connection protocol
3. User interface/API
4. Time synchronization
5. What will happen when the USB memory stick is full?
6. Save recorded video to remote server. This is easy. Maybe uploading them to
distributed storage in Tor network is a good idea?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment