Raspberry pi zero w based car dashcam

My pi zero board was lying unused since last couple of year. So I thought to make some use of it and decided to build a car dashcam.

What all you need ?

Raspberry pi zero w board, microSD memory card (>8GB), pi camera

I have used raspbian lite OS and python3 to develop scripts. And to present recordings on web, I have used lighttpd webserver with php-cgi.

Solution is using an external json config for most parameters.

Here is the sample json config:

{
   "Caption": "Some text",
   "Caption_BG": "green",
   "RecordingPath": "/opt/videos",
   "maxspace": 500,
   "framerate": 25,
   "Region": "Asia/Kolkata",
   "resolution": {
                   "width": 640,
                   "height": 480
                 }
}

Here is the python code:

#!/usr/bin/python3
from picamera import PiCamera
from picamera import Color
import os
import datetime
import time
import pytz
from pathlib import Path
import sys
import json
import syslog

try:
   params = sys.argv[1]
   param, value = params.split('=')
   if param != "--config":
      sys.exit()
   playconf = value
except:
   print("Usage: pizam.py --config=<json config>")
   sys.exit()

with open(playconf) as cfg:
  cfgdata = json.load(cfg)

# maxspace in mb
maxspace = cfgdata['maxspace']
Caption = cfgdata['Caption']
Caption_BG = cfgdata['Caption_BG']
RecordingPath = cfgdata['RecordingPath']
framerate = cfgdata['framerate']
resHt = cfgdata['resolution']['height']
resWd = cfgdata['resolution']['width']
Region = cfgdata['Region']
Timezone = pytz.timezone(Region)
RecDuration = 3600

def CheckSize(Directory):
  DirSize = 0
  for (path, dirs, files) in os.walk(Directory):
      for file in files:
          filename = os.path.join(path, file)
          DirSize += os.path.getsize(filename)
  return(round(DirSize/(1000*1000),2))

def FreeUpSpace(FileList):
  for file in FileList:
    if CheckSize(RecordingPath) > float(maxspace):
      message = "Dashcam Removing {}".format(file)
      syslog.syslog(message)
      print(message)
      os.remove(file)

camera = PiCamera()
camera.resolution = (resWd, resHt)
camera.framerate = framerate
camera.video_stabilization = True
if Caption_BG is not None:
   camera.annotate_background = Color(Caption_BG)

while True:
   FileList = sorted(Path(RecordingPath).iterdir(), key=os.path.getmtime)
   FreeUpSpace(FileList)
   pattern = datetime.datetime.now(Timezone).strftime('%H-%d%m%Y')
   recFile = "{}/Cap-{}.{}".format(RecordingPath, pattern, 'h264')
   message = "Dashcam Creating {}".format(recFile)

   increment = 1
   while os.path.exists(recFile):
      recFile = "{}/Cap-{}-{}.{}".format(RecordingPath, pattern, increment, 'h264')
      increment = increment + 1
   message = "Dashcam Creating {}".format(recFile)
   syslog.syslog(message)
   print(message)
     
   timeout = time.time() + RecDuration
   camera.start_recording(recFile)
   while (time.time() < timeout):
      camera.annotate_text = "{} {}".format(Caption, datetime.datetime.now(Timezone).strftime('%H:%M:%S %Y-%m-%d'))
      camera.annotate_text_size = 20
   if time.time() > timeout:
      camera.stop_recording()

camera.stop_recording()

Service unit to start program at boot/reboot

[Unit]
Description=Pizam Car Dashcam

[Service]
User=manish
Type=simple
Restart=always
RestartSec=60
ExecStart=/home/manish/pizam/pizam.py --config=/home/manish/pizam/config.json

[Install]
WantedBy=multi-user.target

PHP code to view recordings over web:

<?php

$dir = '/var/www/html/recordings/';
$rec = 'recordings/';
$okfiletypes = array('mp4','jpg','h264');

$files = array();
if (is_dir($dir)) {
        if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                        if (($file != '.') && ($file != '..')) {
                                if (in_array(strtolower(substr($file,(strrpos($file,'.')+1))),$okfiletypes)) {
                                        $files[] = $file;
                                }
                        }
                }
                closedir($dh);
        }
}
sort($files);

foreach ($files as $file) {
        echo '<div><a href="'.$rec.$file.'">'.$file.'</a></div>';
}
?>