download the latest os, and check if libcamera-*
is available in terminal via autocomplete. Several options are available
- libcamera-hello libcamera-jpeg libcamera-raw libcamera-still libcamera-vid libcamerify
If you wonder where raspistill and raspivid went the got replaced by a new stack and i confirm it works well. Python lib not out yet, still you can do motion detection.
Start by reading doc and then build the binaries into python via subprocess
Example:
before: mkdir /home/user/camera; paste motion_detect.json to dir
run via python capture.py
$ cat motion_detect.json
{
"motion_detect" :
{
"roi_x" : 0,
"roi_y" : 0,
"roi_width" : 1,
"roi_height" : 1,
"difference_m" : 0.2,
"difference_c" : 20,
"region_threshold" : 0.005,
"frame_period" : 30,
"hskip" : 2,
"vskip" : 2,
"verbose" : 1
}
}
import subprocess
import shutil
from datetime import datetime as dt
import os
def printc(s):
print('\033[1;36mINFO\033[0m ' + s)
def get_sorted_filenames():
filenames = [s for s in os.listdir('/home/user/camera') if s.startswith('vid')]
filenames.sort()
return filenames
def get_last_filenr():
filenames = get_sorted_filenames()
if len(filenames) == 0:
return 0
return int(filenames[-1].partition('_')[0].removeprefix('vid'))
def start_detect():
return subprocess.Popen(['libcamera-still',
'--timeout', '0',
'--nopreview',
'--lores-width', '1280', '--lores-height', '720',
'--post-process-file', '/home/user/camera/motion_detect.json'],
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
text=True)
def start_recording():
filename = f'vid{get_last_filenr() + 1}_{dt.utcnow().strftime("%Y-%m-%d-%H:%M:%S")}.h264'
return subprocess.run(['libcamera-vid', '--timeout', '10000', '--framerate', '3', '-o', filename],
text=True, timeout=15, capture_output=True, check=True)
def free_disk_space():
filenames = get_sorted_filenames()
if len(filenames) > 100:
to_delete = filenames[:len(filenames) // 4]
for filename in to_delete:
os.remove('/home/user/camera/' + filename)
print(to_delete)
printc('Delete done.')
p1 = start_detect()
p2 = None
while True:
s = p1.stderr.readline()
print(s, end='')
if 'Motion detected' in s:
printc('Motion detected, recording...')
try:
p1.terminate()
except Exception as e:
print(e)
p1.kill()
try:
p2 = start_recording()
printc('Video recorded.')
print(p2)
except Exception as e:
print(e)
p1 = start_detect()
printc('Motion checking...')
stats = shutil.disk_usage('/')
if stats.used / stats.total > 0.9:
printc('Disk almost full!')
free_disk_space()
The specific motion capture used is found in
https://github.com/raspberrypi/libcamera-apps/blob/main/post_processing_stages/motion_detect_stage.cpp