Go to file
zii d9cdd30877 v3.6.t2
-fixed an issue that prevented the name seed value from
 incrementing
2024-10-09 13:00:35 -04:00
src v3.6.t2 2024-10-09 13:00:35 -04:00
templates v3.5.t2 2024-04-21 08:03:30 -04:00
.gitignore v3.4 2024-04-14 08:01:54 -04:00
build.py v3.5.t2 2024-04-21 08:03:30 -04:00
install.py v3.5.t2 2024-04-21 08:03:30 -04:00
JustMotion.pro v3.5.t2 2024-04-21 08:03:30 -04:00
LICENSE.md v1.3 Update 2022-09-22 20:57:46 -04:00
README.md Updated README 2024-08-02 08:42:10 -04:00

JustMotion

JustMotion is a video surveillance application that monitors the video feeds of an IP or local camera and records only footage that contains motion. The main advantage of this is reduced storage requirements as opposed to continuous recording because only video footage of interest is recorded to storage.

Sticking to the principle of doing the least as needed, this application is extremely lightweight with the fact it doesn't attempt to re-implement much of it's functions internally but will instead rely on external applications that already implement the functions very well.

No user interface is implemented instead external applications are more than welcome to interface with the buffer/footage directories to implement a user interface of any flavor.

Usage

Usage: jmotion <argument>

-h : display usage information about this application.
-d : all valid config files found in /etc/jmotion will be used to
     create camera instances. (this is blocking, meant to run with systemd)
-v : display the current version.
-u : uninstall the entire app from your system, including the service.
-f : force an action without pausing for user confirmation.
-s : view the status of all camera instances.
-q : kill all camera instances.
-r : same as -d except it is non-blocking by starting all camera instances
     via systemd. same as 'systemctl start jmotion'

Config File

The config file is a simple text file that contain parameters that dictate the behavior of the application. Below is an example of a config file with all parameters supported and descriptions of each.

# Motion Watch config file
#
# note all lines in this config file that starts with a '#' are ignored.
# also note to avoid using empty lines. if you're going to need an empty
# line, start it with a '#'
#
recording_uri = rtsp://1.2.3.4:554/h264
# this is the uri to the main stream of the IP camera that will be used
# to record footage. it can be a url to an rtsp stream or a direct device
# path such as /dev/video0.
#
buffer_path = /var/buffer
# this is the work directory the app will use to store live footage and
# image frames. it's recommended to use a ram disk for this since there
# will be large amounts of io occuring here. 1GB of space per camera is
# a good rule of thumb.
#
rec_path = /var/footage
# this is video output directory that will be used to store any footage
# that contain any motion events.
#
live_secs = 30
# this is the maximum amount of seconds worth of live footage to keep in
# buffer_path before deleting the oldest 2 seconds worth of footage.
# note: each video clip in buffer_path is typically 2 seconds long.
#
cam_name = cam-1
# this is the optional camera name parameter to identify the camera. this
# name will also be used as the base directory in buffer_path and rec_path. 
# if not defined, the name of the config file will be used.
#
max_event_secs = 30
# this is the maximum amount of secs of video footage that can be recorded 
# in a motion event.
#
img_comp_cmd = magick compare -metric FUZZ &prev& &next& /dev/null
# this is the command line template this application will use when calling 
# the external image comparison application. the external application is
# expected to compare snapshots from the video stream to determine how 
# different the images are from each other. it needs to output a numeric 
# score with the higher values meaning very different while low values 
# mean similar images. the snapshots pulled from the stream will be bitmap 
# formatted so the app will be required to support this format. also avoid 
# outputting any special chars, only numeric chars with a single '.' if 
# outputting a decimal value. magick is the default if not defined in the 
# config file. the special string &prev& will be substituted with the path 
# to the "previous" bitmap image, behind in time stamp to the image path 
# subtituted in &next&.
# 
img_comp_out = stderr
# this is the standard output stream the app defined in img_comp_cmd will
# use to output the comparison score. this can only be stderr or stdout,
# any other stream name is considered invalid.
#
vid_codec = copy
# this is the encoding codec to use when recording footage from the camera. 
# the list of supported codecs entirely depend on the hosts' ffmpeg 
# installation. run 'ffmpeg -codecs' to determine this list. if not 
# defined, 'copy' will be used as in it will just copy the codec format 
# from the camera itself.
#
aud_codec = copy
# this is the audio encoding codec to use when recording from the camera.
# the list of supported audio codes can be determined by running 'ffmpeg
# -codecs' on the host machine. if not defined, 'copy' will be used as in
# it will directly copy the audio stream from the camera if present.
#
stream_ext = .mkv
# this is the file extension that will be used to when recording footage
# from the camera in buffer_path. ffmpeg will also use this to determine 
# what format container to use for the video clips.
#
thumbnail_ext = .jpg
# this the image format that will be used when creating the thumbnails
# for the videos clips recorded to rec_path.
#
rec_ext = .mkv
# this the the file extension that will be used when storing motion footage 
# to rec_path. ffmpeg will also use this to determine what format container 
# to use for the video clips. 
#
img_thresh = 8000
# this parameter defines the score threshold from img_comp_cmd that will
# be considered motion. any motion events will queue up max_event_secs
# worth of video clips to be written out to rec_path.
#
max_events = 100
# this indicates the maximum amount of motion event video clips to keep
# in rec_path before deleting the oldest clip.
#
post_secs = 60
# this is the amount of seconds to wait before running the command 
# defined in post_cmd. the command will not run if motion was detected 
# in the space before post_secs elapsed.
#
post_cmd = move_the_ptz_camera.py
# this an optional command to run with post_secs. one great use for this
# is to move a ptz camera to the next position of it's patrol pattern.
# note: the call to this command will be delayed if motion was detected.
# also, motion detection is paused while this command is running.
#
rec_fps = 30
# this sets the recording frames per second for the footage recorded 
# from the camera. this has no affect if using 'copy' as the vid_codec.
#
rec_scale = 1280:720
# this sets the pixel scale of the recorded footage from the camera. it
# uses width, height numeric strings seperated by a colon, eg W:H. this
# has no affect of using 'copy' as the vid_codec.
#
img_scale = 320:240
# this sets the pixel size of the thumbnails for recorded stored in 
# rec_path. it uses width, height numeric strings seperated by a colon, 
# eg W:H.
#
service_user = jmotion
# this sets the service local user of the application dictating the 
# amount of privilege it will have on the host. if not defined, the 
# unprivileged user 'jmotion' will be used. which ever user is defined 
# here just make sure it has read/write access to buffer_path and 
# rec_path.
#
service_group = jmotion
# this sets the service local group of the application that can further
# refine host privileges. if not defined, the name stored in 
# service_user will be used.

Build/Install

This application is currently only compatible with a Linux based operating systems that are capable of installing python3 and the QT API (QT6.X.X or better).

./build.py    <--run this first
./install.py  <--run this next
note 1: the build script will search for the QT api installed in your 
        system. if not found, it will ask you where it is. either way
        it is recommended to install the QT API before running this
        script.
note 2: both scripts assume python3 is already installed.