Encourage FUNIX

The consultation of the site is completely free and without advertisements. Donations are nevertheless appreciated to pay for hosting and encourage its author


Video surveillance systems

Video surveillance systems

February 8, 2025

This site has been automatically translated with Google Translate from this original page written in french, there may be some translation errors

Presentation

This page aims to present you different tools to set up a Linux-based video surveillance system with the use of independent surveillance cameras (IP or Wifi), analog, digital or simple webcams, otherwise called CCTV . This page presents two software, zoneminder and motionplus , both allowing to integrate a wide range of cameras, to do automatic motion detection and to create events, they are also based on a web server, allowing via a browser to configure them, to view the cameras in real time and to manage events, whether on a fixed or mobile computer. Zoneminder is much more advanced and has automatic learning and object recognition functions, unlike motionplus which is a much simpler and less cumbersome tool to implement.

This page is expected to expand as I install, upgrade and improve my own system.

The hardware

You can find everything in the field of surveillance cameras at more or less affordable prices, they are generally supplied with dedicated proprietary software necessarily running under Windows, the fact of running it under Linux does not always allow you to take full advantage of all their functionalities, we will be satisfied with the standard and all the software intelligence being deported in the supervision software.

Without wanting to advertise for this or that brand, I was looking for an IP camera to place it outside, I first made my choice on the Reolink brand , but I was unable to make it work under Linux and even under Windows! And nothing is done on the part of this manufacturer for Linux users , so return to sender and I fall back on the Annke brand .


Annke C500 I51DL Camera and POE Adapter

Annke C500 I51DL Outdoor Station Camera

In either case these IP cameras are powered via the Ethernet cable (PoE Power over Ethernet) and this requires a router or a special adapter like the one you can see in the photo above.

Small downside, I had to go through Windows at least once to activate it with the home software by setting a password and the IP address but then all the configuration can be done from a browser under Linux by simply typing the IP address in the URL bar. The screenshots below were made with Firefox on Linux/Mageia 9.


Once you have entered your login, you come across the real-time viewing page which does not work under Linux but that is not a problem because you have no use for it.

On the other hand, the configuration page works perfectly and that is the point, we have access to all the possible parameters from the browser.


You can also choose an encoding using HEVC. Visualization is done simply by typing in a shell

ffplay rtsp://admin:password@192.168.2.110

I also have in my device an Annke WPT500 I51CP camera , the configuration is done under a mobile under Android with Annke Sight , it will be necessary to create an account, configure it by creating a password then by connecting it to the correct Wi-Fi network.

It will be visible under Linux with the command

ffplay rtsp://admin:password@192.168.2.138:554/ch0_1.264

You no longer need the application on Android , which you can then uninstall. This camera only generates streams with the HEVC codec , we will see later how this can be important.

WPT500 I51CP Outdoor Station Camera



Stream a camera's video stream in rtsp

If your camera is not equipped with a basic rtsp compatible video stream server , you can set up one that can work with a simple webcam. I chose mediamtx which is much more than a simple rtsp server. The official website is https://github.com/bluenviron/mediamtx, where you can get the latest release that you unzip by typing

tar xvfz mediamtx-1.8.5.tar.gz

this gives the mediamtx-1.9.3 directory , the sources are compiled with the go language which must have been previously installed ( golang-bin package on my mageia). In the directory we type successively

go generate ./...
CGO_ENABLED=0 GOOS=linux go build .

This will give a mediamtx binary that you can then move to /usr/local/bin. We will also copy the configuration file mediamtx.yml to /usr/local/etc . We first launch it without necessarily being root

mediamtx

here are the traces

2024/10/25 16:45:46 INF MediaMTX v0.0.0
2024/10/25 16:45:46 INF configuration loaded from /usr/local/etc/mediamtx.yml
2024/10/25 16:45:46 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2024/10/25 16:45:46 INF [RTMP] listener opened on :1935
2024/10/25 16:45:46 INF [HLS] listener opened on :8888
2024/10/25 16:45:46 INF [WebRTC] listener opened on :8889 (HTTP), :8189 (ICE/UDP)
2024/10/25 16:45:46 INF [SRT] listener opened on :8890 (UDP)

we launch the video stream with ffmpeg with /dev/video0 as source which corresponds to the webcam on an rtsp address corresponding to the machine on which mediamtx is launched

ffmpeg -f v4l2 -framerate 24 -video_size 640x480 -i /dev/video0 -f rtsp -rtsp_transport tcp rtsp://tetiaroa.kervao.fr:8554/monflux

This is what the server returns

2024/10/25 16:47:16 INF [RTSP] [conn 192.168.2.16:39506] opened
2024/10/25 16:47:16 INF [RTSP] [session 23cd16d2] created by 192.168.2.16:39506
2024/10/25 16:47:16 INF [RTSP] [session 23cd16d2] is publishing to path 'monflux', 1 track (MPEG-4 Video)

you can view the video stream from any machine on the network by typing

ffplay rtsp://tetiaroa.kervao.fr:8554/monflux

here is the server trace

2024/08/17 09:31:01 INF [RTSP] [conn 192.168.2.16:55664] opened
2024/08/17 09:31:01 INF [RTSP] [session bd9fc103] created by 192.168.2.16:55664
2024/08/17 09:31:01 INF [RTSP] [session bd9fc103] is reading from path 'monflux', with UDP, 1 track (MPEG-4 Video)

The webcam can be integrated and used in the video surveillance tools presented below.

[ back to top of page ]

Zoneminder

Facility

Zoneminder is considered the reference opensource video surveillance software. The official website is https://zoneminder.com. You can get the latest version there and unzip it by typing

tar xvfz zoneminder-1.36.35.tar.gz

we will first install the following packages

- lib64vlc-devel
- perl-Apache-Test-1.430.0-2.mga9.noarch
- perl-AppConfig-1.710.0-7.mga9.noarch
- perl-Archive-Zip-1.680.0-2.mga9.noarch
- perl-Astro-SunTime-0.60.0-5.mga9.noarch
- perl-BSD-Resource-1.291.100-10.mga9.x86_64
- perl-Class-Inspector-1.360.0-3.mga9.noarch
- perl-Class-Load-0.250.0-4.mga9.noarch
- perl-Class-Mix-0.6.0-5.mga9.noarch
- perl-Class-Singleton-1.600.0-2.mga9.noarch
- perl-Class-Std-0.13.0-6.mga9.noarch
- perl-Class-Std-Fast-0.0.8-14.mga9.noarch
- perl-Convert-BinHex-1.125.0-5.mga9.noarch
- perl-Crypt-Eksblowfish-0.9.0-23.mga9.x86_64
- perl-Crypt-Rijndael-1.160.0-4.mga9.x86_64
- perl-Data-Entropy-0.7.0-10.mga9.noarch
- perl-Data-Float-0.13.0-5.mga9.noarch
- perl-Data-Flow-1.20.0-10.mga9.noarch
- perl-Data-OptList-0.113.0-1.mga9.noarch
- perl-Data-UUID-1.227.0-1.mga9.x86_64
- perl-Date-Manip-6.900.0-1.mga9.noarch
- perl-DateTime-1.590.0-1.mga9.x86_64
- perl-DateTime-Locale-1.370.0-1.mga9.noarch
- perl-DateTime-TimeZone-2.600.0-1.mga9.noarch
- perl-DBD-mysql-4.50.0-8.mga9.x86_64
- perl-Device-SerialPort-1.40.0-26.mga9.x86_64
- perl-File-ShareDir-1.118.0-2.mga9.noarch
- perl-HTTP-Lite-2.440.0-6.mga9.noarch
- perl-IO-Interface-1.90.0-14.mga9.x86_64
- perl-IO-SessionData-1.30.0-9.mga9.noarch
- perl-IO-Socket-Multicast-1.120.0-26.mga9.x86_64
- perl-JSON-MaybeXS-1.4.4-1.mga9.noarch
- perl-Linux-Pid-0.40.0-24.mga9.x86_64
- perl-List-AllUtils-0.190.0-2.mga9.noarch
- perl-List-SomeUtils-0.590.0-1.mga9.noarch
- perl-List-UtilsBy-0.120.0-1.mga9.noarch
- perl-MIME-tools-5.510.0-1.mga9.noarch
- perl-Net-SFTP-Foreign-1.930.0-2.mga9.noarch
- perl-Number-Bytes-Human-0.110.0-5.mga9.noarch
- perl-Params-Classify-0.15.0-11.mga9.x86_64
- perl-Params-Util-1.102.0-4.mga9.x86_64
- perl-PHP-Serialization-0.340.0-11.mga9.noarch
- perl-Pod-POM-2.10.0-7.mga9.noarch
- perl-SOAP-Lite-1.270.0-3.mga9.noarch
- perl-SOAP-WSDL-3.4.0-3.mga9.noarch
- perl-Sub-Install-0.929.0-1.mga9.noarch
- perl-Sys-CPU-0.610.0-20.mga9.x86_64
- perl-Sys-MemInfo-0.990.0-13.mga9.x86_64
- perl-Sys-Mmap-0.200.0-6.mga9.x86_64
- perl-Task-Weaken-1.60.0-4.mga9.noarch
- perl-Template-Toolkit-3.101.0-1.mga9.x86_64
- perl-Time-ParseDate-2015.103.0-6.mga9.noarch
- perl-URI-Encode-1.1.1-4.mga9.noarch
- perl-X10-0.30.0-10c.mga9.noarch

We return to the zoneminder-1.36.35 directory in which we type successively

mkdir build
cd build/
cd ..
git clone "https://github.com/ZoneMinder/ZoneMinder.git" zoneminder_release
cd zoneminder_release/
cp -Rf .git ..
cd ..
cd build/
git submodule update --init --recursive

and finally the configuration command with the settings of the MySQL server name ( ZM_DB_HOST ) in this case based on MariaDB , the activation of the systemd service ( ZM_SYSTEMD ), the owner of the httpd process ( ZM_WEB_USER ) and the paths of the event storage directory ( ZM_DIR_EVENTS ), the cgi-bin executables ( ZM_CGI_DIR ), the installation prefix with /usr and not /usr/local ( CMAKE_INSTALL_PREFIX ), the path of the configuration file ( ZM_CONFIG_DIR ), the search path for perl modules ( ZM_PERL_SEARCH_PATH ) and the files accessible by browser ( ZM_WEBDIR ).
For the record, it is necessary to have a functional Apache+PHP+MariaDB server .

cmake .. -DMYSQLCLIENT_LIBRARIES=/usr/local/mysql/lib/libmysqlclient.so -DZM_DB_HOST=mariadb-serveur -DZM_WEB_USER=apache -DZM_DIR_EVENTS=/media/motion/events -DZM_CGIDIR=/usr/share/zoneminder/cgi-bin -DCMAKE_INSTALL_PREFIX=/usr -DZM_CONFIG_DIR=/etc/zm -DZM_CONFIG_SUBDIR=/etc/zm/conf.d -DZM_PERL_SEARCH_PATH=/usr/share/perl5/vendor_perl -DZM_SYSTEMD=ON -DZM_WEBDIR=/usr/share/zoneminder/www/

here is the result

-- Detected compiler: /usr/bin/cc
-- Sendfile support: Linux/Solaris sendfile()
-- Building man pages: Yes (default)
-- Could NOT find LibJWT (missing: LIBJWT_LIBRARY)
-- Checking prototype MD5 for HAVE_MD5_OPENSSL - True
-- Using web user: apache
-- Using web group: apache
Building unit tests: No (default)
-- Optional libraries found: zlib cURL OpenSSL PCRE GCrypt AVFormat AVCodec AVDevice AVUtil SWScale SWResample libVLC
-- Optional libraries not found: LIBJWT libVNC
-- Running ZoneMinder configuration generator
Generating '/home/olivier/compilation/zoneminder-1.36.35/build/zm_config_defines.h'
Updating '/home/olivier/compilation/zoneminder-1.36.35/build/db/zm_create.sql'
-- ZoneMinder configuration generator completed successfully
-- Configuring done (0.4s)
-- Generating done (0.1s)
-- Build files have been written to: /home/olivier/compilation/zoneminder-1.36.35/build


then type make then as root make install
I played with the ZM_PERL_MM_PARMS variable but it did not install the perl modules in the right place, I had to type the commands below manually

cp -Rf /root/perl5/lib/perl5/WSDiscovery11 /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/WSDiscovery10 /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/WSNotification /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/ONVIF /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/WSNotification/ /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/ZoneMinder* /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/WSSecurity/ /usr/share/perl5/vendor_perl
cp -Rf /root/perl5/lib/perl5/WSDiscovery /usr/share/perl5/vendor_perl

You must start by creating a mysql database by typing:

mariadb -u root -p < /usr/share/zoneminder/db/zm_create.sql

we check if the base is correctly created, it is simply called zm and we create a privileged user zmuser on the zm base with the password zmpass which will obviously have to be changed

mariadb -u root -p

here is the result

Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 25
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+---------------------+
| Database |
+---------------------+
| MyMusic82 |
| MyMusic83 |
| MyVideos121 |
| MyVideos131 |
| digikam |
| digikam_similarites |
| digikam_vignettes |
| digikam_faces |
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| roundcubemail |
| spamassassin |
| syncstorage_rs |
| sys |
| tokenserver_rs |
| zm |
+----------------------+
18 rows in set (0.096 sec)

MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [mysql]> CREATE USER 'zmuser' IDENTIFIED BY 'zmpass';
Query OK, 0 rows affected (0.087 sec)

MariaDB [mysql]> GRANT ALL ON zm.* TO 'zmuser'@'localhost';
Query OK, 0 rows affected (0.201 sec)

now I created the file /usr/lib/systemd/system/zoneminder.service which will contain

[Unit]
Description=ZoneMinder CCTV recording and security system
After=network.target mariadb.service httpd.service
Requires=mariadb.service httpd.service

[Service]
User=apache
Type=forking
ExecStart=/usr/bin/zmpkg.pl start
ExecReload=/usr/bin/zmpkg.pl reload
ExecStop=/usr/bin/zmpkg.pl stop

[Install]
WantedBy=multi-user.target

Please note that the user must correspond to the owner of the Apache httpd process . The service is activated by typing

systemctl enable zoneminder

[ back to top of page ]

The configuration file /etc/zm/zm.conf looks like this

# ============================================================
#
# ZoneMinder Base Configuration
#
# ============================================================
#
# *** DO NOT EDIT THIS FILE ***
#
# To make custom changes to the variables below, create a new configuration
# file, with an extension of .conf, under the /etc/zm/conf.d
# folder, containing your desired modifications.
#

# Path to installed data directory, used mostly for finding DB upgrade scripts
ZM_PATH_DATA=/usr/share/zoneminder

# Path to ZoneMinder binaries
ZM_PATH_BIN=/usr/bin

# Path to ZoneMinder libraries (none at present, for future use)
ZM_PATH_LIB=/usr/lib64

# Path to ZoneMinder configuration (this file only at present)
ZM_PATH_CONF=/etc/zm

# Path to ZoneMinder web files
ZM_PATH_WEB=/usr/share/zoneminder/www

# Path to ZoneMinder cgi files
ZM_PATH_CGI=/usr/share/zoneminder/cgi-bin

# Username and group that web daemon (httpd/apache) runs as
# user and group owner of the apache daemon httpd
ZM_WEB_USER=apache
ZM_WEB_GROUP=apache

# ZoneMinder database type: n/a far only mysql is supported
ZM_DB_TYPE=mysql

# ZoneMinder database hostname or ip address and optionally port or unix socket
# Acceptable formats include hostname[:port], ip_address[:port], or
# localhost:/path/to/unix_socket
# the name of the server on which the mariadb server is running
ZM_DB_HOST=mariadb-serveur

# ZoneMinder database name
ZM_DB_NAME=zm

# ZoneMinder database user
ZM_DB_USER=zmuser

# ZoneMinder database password
# the password as defined in mariadb
ZM_DB_PASS=zmpass

# SSL CA certificate for ZoneMinder database
ZM_DB_SSL_CA_CERT=

# SSL client key for ZoneMinder database
ZM_DB_SSL_CLIENT_KEY=

# SSL client cert for ZoneMinder database
ZM_DB_SSL_CLIENT_CERT=

# Do NOT set ZM_SERVER_HOST if you are not using Multi-Server
# You have been warned
#
# The name specified here must have a corresponding entry
# in the Servers tab under Options
ZM_SERVER_HOST=

Another file /etc/zm/conf.d/01-system-paths.conf which will contain

# ============================================================
#
# ZoneMinder System Paths Configuration
#
# ============================================================
#
# This config file contains the variables previously found under Options -> Paths
#
# *** DO NOT EDIT THIS FILE ***
#
# To make custom changes to the variables below, create a new configuration
# file, with an extension of .conf, containing your desired modifications.
#

# Full path to the folder events are recorded to.
# The web account user must have full read/write permission to this folder.
# directory where the events are recorded
# the owner of the httpd process must be the owner, it is apache
ZM_DIR_EVENTS=/media/motion/events

# Foldername under the webroot where ZoneMinder looks for optional sound files
# to play when an alarm is detected.
ZM_DIR_SOUNDS=sounds

# Full path to the folder where exported archives are stored
# The web account user must have full read/write permission to this folder.
# directory where the archives are exported
# the apache user must own the directory
ZM_DIR_EXPORTS=/var/tmp/zm

# ZoneMinder url path to the zms streaming server
ZM_PATH_ZMS=/zm/cgi-bin/nph-zms

# Full Path to ZoneMinder's mapped memory files
# The web account user must have full read/write permission to this folder.
ZM_PATH_MAP=/dev/shm

# Full Path to ZoneMinder's socket folder
# The web account user must have full read/write permission to this folder.
# sockets directory
# the apache user must own it
ZM_PATH_SOCKS=/var/run/zm

# Full path to ZoneMinder's log folder
# The web account user must have full read/write permission to this folder.
# logs directory
# the apache user must own it
ZM_PATH_LOGS=/var/log/zm

# Full path to ZoneMinder's swap folder
# The web account user must have full read/write permission to this folder.
ZM_PATH_SWAP=/var/tmp/zm

# Full path to optional arp binary
# ZoneMinder will find the arp binary automatically on most systems
ZM_PATH_ARP="/usr/sbin/arp"

#Full path to shutdown binary
ZM_PATH_SHUTDOWN="/sbin/shutdown"

# Path to FFmpeg binary
ZM_PATH_FFMPEG="/usr/local/bin/ffmpeg"

It will be necessary to ensure that the apache user is the owner of certain directories necessary for the operation of zoneminder

chown -R apache:apache /var/run/zm
chown -R apache:apache /var/log/zm
chown -R apache:apache /var/lib/zoneminder
chown -R apache:apache /usr/share/zoneminder/www
chown -R apache:apache /var/cache/zoneminder
chown -R apache:apache /etc/zm

Incidentally I created the following link

ln -s /var/cache/zoneminder/ /usr/share/zoneminder/www/cache

you will then need to modify the configuration of the Apache httpd server in the file /usr/local/apache2/conf/httpd/conf, first of all the list of useful and necessary modules

LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule cgid_module modules/mod_cgid.so
LoadModule dir_module modules/mod_dir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule php_module modules/libphp.so

(...)

# the owner of the apache/httpd daemon

User apache
Group apache

(...)

#zoneminder specific directives
<Directory "/usr/share/zoneminder/www">
   Options -Indexes +FollowSymLinks
   AllowOverride All
   Require all granted
</Directory>

<Directory "/var/cache/zoneminder">
    Options -Indexes +FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

<Directory "/usr/share/zoneminder/cgi-bin">
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    AllowOverride All
    Require all granted
</Directory>

<Directory "/usr/share/zoneminder/www/api">
   RewriteEngine on
   RewriteRule ^$ app/webroot/ [L]
   RewriteRule (.*) app/webroot/$1 [L]
   RewriteBase /zm/api
</Directory>

<Directory "/usr/share/zoneminder/www/api/app">
   RewriteEngine on
   RewriteRule ^$ webroot/ [L]
   RewriteRule (.*) webroot/$1 [L]
   RewriteBase /zm/api
</Directory>

<Directory "/usr/share/zoneminder/www/api/app/webroot">
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    RewriteBase /zm/api
</Directory>

#alias zoneminder in this specific order
ScriptAlias ​​/zm/cgi-bin "/usr/share/zoneminder/cgi-bin"
Alias ​​/zm/cache "/var/cache/zoneminder"
Alias ​​/zm "/usr/share/zoneminder/www"

We will also ensure that the time zone variable in the /usr/local/apache2/conf/php.ini file is correctly initialized

date.timezone = Europe/Paris

we restart Apache httpd to take into account the update of these last two files

systemctl httpd restart

and we launch zoneminder by typing

systemctl start zoneminder

and this is what the command returns

systemctl status zoneminder

● zoneminder.service - ZoneMinder CCTV recording and security system
     Loaded: loaded (/usr/lib/systemd/system/zoneminder.service; disabled; preset: disabled)
     Active: active (running) since Fri 2024-08-09 16:03:47 CEST; 11s ago
    Process: 3570 ExecStart=/usr/bin/zmpkg.pl start (code=exited, status=0/SUCCESS)
   Main PID: 3578 (zmdc.pl)
      Tasks: 5 (limit: 9239)
     Memory: 91.5M
        CPU: 2.077s
     CGroup: /system.slice/zoneminder.service
             ├─3578 /usr/bin/perl -wT /usr/bin/zmdc.pl startup
             ├─3606 /usr/bin/perl -wT /usr/bin/zmfilter.pl --filter_id=1 --daemon
             ├─3610 /usr/bin/perl -wT /usr/bin/zmfilter.pl --filter_id=2 --daemon
             ├─3616 /usr/bin/perl -wT /usr/bin/zmwatch.pl
             └─3620 /usr/bin/perl -wT /usr/bin/zmstats.pl

Aug 09 16:03:44 ultra.kervao.fr systemd[1]: Starting zoneminder.service...
Aug 09 16:03:47 ultra.kervao.fr systemd[1]: Started zoneminder.service.


Use

Here is the main screen with a camera added from the Add Camera command with Modect mode , meaning it will detect movements and create an event for each one.

It will be necessary to define the video source of the view, by putting the path

Then we define the camera characteristics from the source


In Storage we will rather choose at the Video Writer Camera Passthrough level to not overload zoneminder with an encoding, this means that we write the video provided by the camera as is.

Note the % reference image fusion parameter which will affect the detection rate, for an external camera it is recommended to set 12.5%. To trigger an alarm we can set a difference value, it corresponds to the percentage of the image that has moved compared to the reference image.

With multiple cameras this gives


By clicking on the camera you have the real-time view, the events are displayed in a list below the view of the selected camera


To view a particular event, you must click on it, the event in question is marked in the timeline in red


Attention for cameras providing video with the HEVC codec, the replay will not be visible under Firefox whose foundation refuses to pay the corresponding patents. On the other hand it will work very well with Gnome web (former Epiphany ) for example.

We have video replay tools to view the event in question, we can delete them at the previous level.
To have a video wall with the camera, we will go to Montage


The Options menu will allow you to access the different options


Events are saved by default under /var/lib/zoneminder/www/events, you can add additional space by clicking on Add new storage


You have every interest in doing regular cleaning to avoid exploding the disk, it is possible to do it automatically from the Filters menu by selecting PurgeWhenFull with cleaning launched from a 95% occupancy of the disk.


To be notified by email of the slightest event, configure the Email option in the Options


but this is not enough, you then need to create a filter that will trigger the sending of emails when the detection score reaches at least 5.


To further refine the settings, you can define detection zones with specific settings for each zone; you must slide the 4 green dots at the corner to materialize it.



For each camera, we can therefore define several detection zones; below there are 3 active zones and 5 inactive zones where no event will be reported.


For more details on the zones, you can consult the official documentation as well as this wiki page and this one, this page in French is also a valuable help in understanding the types of zones and their settings.

We can remember that there are several alarm triggering methods, Alarmed Pixels, Filtered Pixels and blobs without going into the details which are given in the pages cited above, the last blobs method is given to be the most effective. We will then define the detection thresholds from the size of the detected objects.

The exterior cameras remain the most delicate to adjust. I struggled quite a bit to find the right setting for my camera which aims at the gate which is rather far away, it did not detect anything at all until I went back to the settings on this page which were a good starting point, without it being totally satisfactory for objects the size of a person close to the gate.



In this case, you will have to use the unit pixels rather than percentage which allows a finer adjustment. In my case (below) the area of ​​the zone is 204040 pixels, or given the shape of my trapezoidal zone, approximately a rectangle of 900x225 pixels from there you have to imagine the size of a person to deduce their size in pixels (you can use gimp ) , in my case it is approximately a size of 25x60 pixels, or 1500 pixels which we will find in the min field of Surface in alarm


Then you have to proceed by trial and error for the rest of the parameters. Now when an event is detected the area(s) concerned will be indicated



Go even further with ZMES

The Event Notification Server or ZMES is a complementary tool to zoneminder, it has a "machine learning" or automatic learning which allows it to recognize objects, whether they are people or cars for example.

The official site is  https://github.com/ZoneMinder/zmeventnotification where you can retrieve the sources and unzip them by typing

tar xvfz zmeventnotification-6.1.29.tar.gz

This gives the directory zmeventnotification-6.1.29. We will first install the packages perl-YAML-LibYAML, perl-Crypt-MySQL, perl-Module-Build-Tiny and perl-CPAN-DistnameInfo. Then with CPAN

perl -MCPAN -e "install Crypt::Eksblowfish::Bcrypt"
perl -MCPAN -e "install Protocol::WebSocket"
perl -MCPAN -e "install Net::WebSocket::Server"

perl -MCPAN -e "install Net::MQTT::Simple"


      

Now we type as root

zmeventnotification-6.1.29/install.sh

Here is part of the result

which: no apt-get in (/root/perl5:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/mysql/bin:/usr/lib64/qt5/bin:/usr/lib64/qt6/bin)
which: no yum in (/root/perl5:/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/usr/local/mysql/bin:/usr/lib64/qt5/bin:/usr/lib64/qt6/bin)

----------- Configured Values ----------------------------
Your distro seems to be ubuntu
Your webserver user seems to be apache
Your webserver group seems to be apache
wget is /usr/bin/wget
installer software is
Install Event Server: prompt
Install Event Server config: prompt
Install Hooks: prompt
Install Hooks config: prompt
Upgrade Hooks config (if applicable): yes
Download and install models (if needed): yes

The Event Server will be installed to /usr/bin
The Event Server config will be installed to /etc/zm
Hooks will be installed to /var/lib/zmeventnotification sub-folders
Hook config files will be installed to /etc/zm

Models that will be checked/installed:
(Note, if you have already downloaded a model, it will not be deleted)
Yolo V3 (INSTALL_YOLOV3): yes
TinyYolo V3 (INSTALL_TINYYOLOV3): yes
Yolo V4 (INSTALL_YOLOV4): yes
Tiny Yolo V4 (INSTALL_TINYYOLOV4): yes
Google Coral Edge TPU (INSTALL_CORAL_EDGETPU): no

If any of this looks wrong, please hit Ctrl+C and edit the variables in this script...


Install Event Server [y/N]:y
*** Installing ES Dependencies ***
 install libconfig-inifiles-perl libcrypt-mysql-perl libcrypt-eksblowfish-perl libmodule-build-perl libyaml-perl libjson-per liblwp-protocol-https-perl libgeos-devl
install: cible 'libyaml-perl': Aucun fichier ou dossier de ce type
 install libnet-websocket-server-perl
install: opérande de fichier cible manquant après 'libnet-websocket-server-perl'
Saisissez « install --help » pour plus d'informations.
*** Installing ES ***
Success:Completed, but you will still have to install ES dependencies as per https://zmeventnotification.readthedocs.io/en/latest/guides/install.html#install-dependencies


Install Event Server Config [y/N]:y
Replacing ES config & rules file
Success:config copied
Replacing ES rules file
Success:rules copied
====> Remember to fill in the right values in the config files, or your system won't work! <=============


Install Hook [y/N]:y
Installing pip...
install: opérande de fichier cible manquant après 'pip'
Saisissez « install --help » pour plus d'informations.
Installing python3-opencv...
install: opérande de fichier cible manquant après 'python3-opencv'
Saisissez « install --help » pour plus d'informations.
*** Installing Hooks ***
Checking for YoloV3 data files....
yolov3.cfg exists, no need to download
coco.names exists, no need to download
yolov3.weights exists, no need to download

Checking for TinyYOLOV3 data files...
yolov3-tiny.cfg exists, no need to download
coco.names exists, no need to download
yolov3-tiny.weights exists, no need to download

Checking for TinyYOLOV4 data files...
yolov4-tiny.cfg exists, no need to download
coco.names exists, no need to download
yolov4-tiny.weights exists, no need to download

Checking for YOLOV4 data files...
WARNING:Note, you need OpenCV 4.4+ for Yolov4 to work
yolov4.cfg exists, no need to download
coco.names exists, no need to download
yolov4.weights exists, no need to download
*** Installing push api plugins ***
*** Installing detection scripts ***

*** Installing user contributions ***
Copying over contrib/example.py...
Copying over contrib/ftp_selective_upload.py...

(...)

Success:Done

    |-------------------------- NOTE -------------------------------------|
   
     Hooks are installed, but please make sure you have the right version
     of OpenCV installed. I recommend removing any pip packages you may
     have installed of opencv* and compiling OpenCV 4.4.x+ from source.
     See https://zmeventnotification.readthedocs.io/en/latest/guides/hooks.html#opencv-install

    |----------------------------------------------------------------------|

Installing package deps...
Installing gifsicle, if needed...
install : option invalide -- 'q'
Saisissez « install --help » pour plus d'informations.
Skipping Hook install


Install Hook Config [y/N]:y
Replacing Hook config file
Success:config copied
====> Remember to fill in the right values in the config files, or your system won't work! <=============
====> If you changed /etc/zm remember to fix  /var/lib/zmeventnotification/bin/zm_event_start.sh! <========


Creating a migrated objectconfig if required
Current version of file is 1.2
Nothing to migrate

*** Please remember to start the Event Server after this update ***

You will need to modify or create files under /etc/zm first secrets.ini which will contain

[secrets]

# the URL to access zoneminder https://ultra.kervao.fr/zm needs to be adapted, the login user and password are defined in the system configuration page

ZMES_PICTURE_URL=https://ultra.kervao.fr/zm/index.php?view=image&eid=EVENTID&fid=objdetect&width=600
ZM_USER=zm-user
ZM_PASSWORD=password

ZM_PORTAL=https://ultra.kervao.fr/zm
ZM_API_PORTAL=https://ultra.kervao.fr/zm/api

# certificate and key for an ssl connection, I reused those of my apache server
ES_CERT_FILE=/etc/ssl/public/apache.crt
ES_KEY_FILE=/etc/ssl/apache/apache.key

#key for license plate recognition, you will need to create an account on this site https://platerecognizer.com/
PLATEREC_ALPR_KEY=cb5ece0dhkhg1bea8dfd08408ec6cb8370d6c3b5c

We will now modify the file /etc/zm/objectconfig.ini which will contain (extracts)

(...)

secrets = /etc/zm/secrets.ini

# portal/user/password are needed if you plan on using ZM's legacy
# auth mechanism to get images

# do not modify anything it will look in the secrets.ini file

portal=!ZM_PORTAL
user=!ZM_USER
password=!ZM_PASSWORD

# api portal is needed if you plan to use tokens to get images
# requires ZM 1.33 or above
api_portal=!ZM_API_PORTAL

# this parameter must be set to yes in case of encrypted connection with self signed certificate
allow_self_signed=yes

(...)

# If you need basic auth to access ZM

#if the directory is password protected with a .htaccess we will indicate the password here

basic_user=login-apache
basic_password=password-apache

(...)

# API/password for remote gateway
ml_user=!ML_USER
ml_password=!ML_PASSWORD

(...)

# the key for license plate recognition, same as the secrets.ini file
alpr_key=cb5ece0dhkhg1bea8dfd08408ec6cb8370d6c3b5c

We now modify /etc/zm/zmeventnotification.ini

[ssl]
# Enable SSL (default: yes)
enable = yes

#same key in secrets.ini file
cert = /etc/ssl/public/apache.crt
key = /etc/ssl/apache/apache.key

Now in the system options and configuration we will check the boxes OPT_USE_API and OPT_USE_EVENTNOTIFICATION

We restart zoneminder and launch ZMES by typing

sudo -u apache /usr/bin/zmeventnotification.pl

here is the result

Use of uninitialized value $first_arg in string eq at ./zmeventnotification.pl line 62.
27/10/2024 17:31:03.690121 zmeventnotification[163691].INF [main:330] [Running on WebSocket library version:0.004]
27/10/2024 17:31:07.018532 zmeventnotification[163691].INF [main:1010] [PARENT: using config file: /etc/zm/zmeventnotification.ini]
10/27/2024 17:31:07.833499 zmeventnotification[163691].INF [main:1010] [PARENT: using secrets file: /etc/zm/secrets.ini]
Use of uninitialized value $es_debug_level in numeric ge (>=) at ./zmeventnotification.pl line 999.
Use of uninitialized value $es_debug_level in numeric ge (>=) at ./zmeventnotification.pl line 999.
Use of uninitialized value $skip_monitors in split at ./zmeventnotification.pl line 543.
Use of uninitialized value $es_debug_level in numeric ge (>=) at ./zmeventnotification.pl line 999.
Use of uninitialized value $hook_skip_monitors in split at ./zmeventnotification.pl line 732.

with an event

27/10/2024 17:31:26.558583 zmeventnotification[163691].INF [main:1010] [PARENT: Push enabled via FCM]
27/10/2024 17:31:26.558734 zmeventnotification[163691].INF [main:1010] [PARENT: MQTT Disabled]
27/10/2024 17:31:26.558814 zmeventnotification[163691].INF [main:1010] [PARENT: |------- Starting ES version: 6.1.29 ---------|]
Can't ignore signal CHLD, forcing to default. 10/27/2024 5:31:49
PM
[main:1010] [PARENT: Re-loading monitors]
Use of uninitialized value in concatenation (.) or string at ./zmeventnotification.pl line 1453.
10/27/2024 5:31:54.071086 zmeventnotification[163691].INF [main:1010] [PARENT: New event 380 reported for Monitor:4 (Name:Camera-4) Motion[last processed eid:]]
27/10/2024 17:31:56.427281 zmeventnotification[163691].INF [main:1010] [PARENT: Secure WS(WSS) is enabled...]
27/10/2024 17:31:56.427365 zmeventnotification[163691].INF [main:1010] [PARENT: Web Socket Event Server listening on port 9000]

to activate it as a systemd service, we will create the file /usr/lib/systemd/system/zmes.service which will contain

[Unit]
Description=ZMES
After=zoneminder.service
Requires=zoneminder.service httpd.service

[Service]
User=apache
Type=simple
ExecStart=/usr/bin/zmeventnotification.pl
Restart=on-failure

[Install]
WantedBy=multi-user.target

we will activate it by typing

systemclt enable zmes

we launch it by typing

systemctl start zmes

here is his status by typing

systemctl status zmes

● zmes.service - ZMES
     Loaded: loaded (/usr/lib/systemd/system/zmes.service; disabled; preset: disabled)
     Active: active (running) since Thu 2024-10-31 10:43:42 CET; 36s ago
   Main PID: 243499 (zmeventnotifica)
      Tasks: 1 (limit: 9239)
     Memory: 46.3M
        CPU: 784ms
     CGroup: /system.slice/zmes.service
             └─243499 /usr/bin/perl -T /usr/bin/zmeventnotification.pl

Oct 31 10:43:42 ultra.kervao.fr systemd[1]: Started zmes.service.
Oct 31 10:43:42 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $first_arg in string eq at /usr/bin/zmeventnotification.pl line 61.
Oct 31 10:43:43 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $es_debug_level in numeric ge (>=) at /usr/bin/zmeventnotification.pl line 998.
Oct. 31 10:43:43 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $es_debug_level in numeric ge (>=) at /usr/bin/zmeventnotification.pl line 998.
Oct. 31 10:43:43 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $skip_monitors in split at /usr/bin/zmeventnotification.pl line 542.
Oct 31 10:43:43 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $es_debug_level in numeric ge (>=) at /usr/bin/zmeventnotification.pl line 998.
Oct. 31 10:43:43 ultra.kervao.fr zmeventnotification.pl[243499]: Use of uninitialized value $hook_skip_monitors in split at /usr/bin/zmeventnotification.pl line 731.
Oct. 31 10:43:44 ultra.kervao.fr zmeventnotification.pl[243505]: Can't ignore signal CHLD, forcing to default.

And this is what it will give at the interface level, we see that it has identified people and a vehicle (truck).


And in the Audit Events Report menu, you can click on the links where an object has been identified.

the object in question is surrounded, here a person



Do a zoneminder update

If you update zoneminder, the database will not necessarily be in the right format and when you launch it you might get a message like this

Version mismatch, system is version 1.36.35, database is 1.36.33, please run zmupdate.pl to update

In this case with a MariaDB server I first created the following links

ln -s /usr/local/mysql/bin/mariadb-dump /usr/local/bin/mysqldump
ln -s /usr/local/mysql/bin/mariadb /usr/local/bin/mysql


then we type

/usr/bin/zmupdate.pl

here is the result

Initiating database upgrade to version 1.36.35 from version 1.36.33

Do you wish to take a backup of your database prior to upgrading?
This may result in a large file in /var/tmp/zm if you have a lot of events.
Press 'y' for a backup or 'n' to continue: y
Creating backup to /var/tmp/zm/zm-1.36.33.dump. This may take several minutes.
mysqldump: Deprecated program name. It will be removed in a future release, use '/usr/local/mysql/bin/mariadb-dump' instead
Database successfully backed up to /var/tmp/zm/zm-1.36.33.dump, proceeding to upgrade.

Upgrading database to version 1.36.35
Upgrading DB to 1.36.34 from 1.36.33
mysql: Deprecated program name. It will be removed in a future release, use '/usr/local/mysql/bin/mariadb' instead

Database successfully upgraded to version 1.36.34.

Database upgrade to version 1.36.35 successful.

That's it, it's done, we can launch and use zoneminder again .

[ back to top of page ]

Control zoneminder from a mobile phone with zmNinja

It is possible to access zoneminder from a mobile as soon as you have activated your LAMP server to be visible on the internet as indicated here and if possible with an encrypted connection as explained there.

The display on mobile is not great and not very user friendly as can be seen below:

It turns out that there is an ad hoc application called zmNinja. While it certainly costs the modest sum of €4.69, it is worth investing for so little to have a comfortable viewing on mobile.

First of all, under zoneminder I made some configurations to secure access. I first created users, a classic admin account and a limited user account.

Then in the system level settings I enabled zoneminder authentication by checking the boxes below.

Then everything happens on the mobile, where we start to indicate the URL and passwords.


The first ZM authentication password corresponds to the password defined in zoneminder, the second corresponds to the password set up under Apache with the .htaccess file to secure access to the directory.


The second part of the screen is below where we will indicate the URL of the zoneminder server .

The main screen


Editing mode

If you have the following error in the logs

requests.exceptions.HTTPError: 500 Server Error: Internal Server Error for url: https://ultra.kervao.fr/zm/api/host/login.json

it is that PHP is missing the apcu extension, we will get it here https://github.com/krakjoe/apcu/releases, we uncompress by typing

tar xvfz apcu-5.1.24.tar.gz
cd apcu-5.1.24
phpize
./configure --enable-apcu
make

and as root make install

we will modify /usr/local/apache2/conf/php.ini by adding

extension=apcu
apc.enabled=1
apc.enable_cli=1

we restart
apache. For this other error

Oct 27 16:10:04 ultra.kervao.fr zm_detect.py[149699]: ERR [zmesdetect_m4] [Turning DB logging off. Could not connect to DB, message was:(mysql.connector.errors.DatabaseError) 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci' (Background on this error at: http://sqlalche.me/e/13/4xp6)]

This comes from the fact that I use mariadb which did not take over certain MySQL settings , I had to replace the occurrences of utf8mb4_0900_ai_ci with utf8mb4_unicode_520_ci in the files

/usr/local/lib64/python3.10/site-packages/mysql/connector/aio/charsets.py
/usr/local/lib64/python3.10/site-packages/mysql/connector/charsets.py

the command below will allow you to see if everything is working correctly, you will need to indicate an event and camera number.

sudo -u apache /var/lib/zmeventnotification/bin/zm_detect.py --config /etc/zm/objectconfig.ini --eventid 375 --monitorid 4 --debug

If zoneminder seems to work but you get a white screen instead of the image you will probably need to edit the file /etc/zm/conf.d/01-system-paths.conf and indicate

ZM_PATH_ZMS=/zm/cgi-bin/nph-zms

Some sites for more information
and of course on the forum https://forums.zoneminder.com/

Detect motion with motionplus

Facility

The motionplus program is a motion detection utility from various video sources, webcam, video stream, IP camera, wifi or whatever else available on the network. It integrates an httpd server where videos can be viewed in real time, you can also view events, that is to say any movement that has been recorded. The use of a database is necessary to manage events.

The official site is https://motion-project.github.io/ where you can find the original motion program and a revised version called motionplus presented here on this page, which you can decompress by typing

tar xvfz motionplus-release-0.2.2.tar.gz

this gives the motionplus-master directory we will first retrieve the lib64microhttpd-devel and lib64camera-devel packages, we will see later how to use an Apache httpd server. We return to the directory in which we type

autoreconf -fiv;./configure --with-ffmpeg=/usr/local/lib --with-mariadb=/usr/local/mysql

The with-ffmpeg option points to the directory where the ffmpeg libraries I compiled are located to prevent it from using the system version.This is the result

   **************************
      Configure status      
      motionplus 0.2.2
   **************************

CPPFLAGS: -D_THREAD_SAFE -I/usr/include/p11-kit-1 -I/usr/include/webp -I/usr/include/libcamera -I/usr/local/include -I/usr/include/opencv4 -I/usr/local/mysql/include/mysql/ -D_REENTRANT  

LIBS: -pthread -ljpeg -lmicrohttpd -lwebpmux -lwebp -lsharpyuv -lcamera -lcamera-base -L/usr/local/lib -lavutil -lavformat -lavcodec -lswscale -lavdevice -lopencv_gapi -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_ml -lopencv_videostab -lopencv_videoio -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core -L/usr/local/mysql/lib/ -lmariadb -lsqlite3 -lpulse -pthread -lpulse-simple -lasound -lfftw3

LDFLAGS:


OS: linux-gnu
pthread_np: no
pthread_setname_np: yes
pthread_getname_np: yes
XSI error: no
webp support: yes
V4L2 support : yes
libcamera support : yes
FFmpeg support: yes
  libavformat version: 61.1.100
OpenCV: yes
  version: 4.6.0
SQLite3 support: yes
MYSQL support: no
PostgreSQL support: no
MariaDB support: yes
ALSA support: yes
PulseAudio support: yes
FFTW support: yes

Install prefix: /usr/local

The database is needed to manage events, for ffmpeg see the basic tools page for video and for MySQL the corresponding page. Now we type

make

then as root make install. Then we create the motionplus database

mariadb -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10952
Server version: 11.4.2-MariaDB Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create database motionplus;
Query OK, 1 row affected (0.001 sec)

[ back to top of page ]

Now we will modify the configuration file, a default motionplus-dist.conf configuration file has been created under /usr/local/etc/motionplus/ we rename it motionplus.conf. Below you will find the modifications that have been made

;*************************************************
;***** Camera
;*************************************************
device_name
device_id
target_dir /emile/photo/motion

The target_dir variable points to where snapshots and videos will be stored, I placed it in the directory tree of my Apache server so that they can be visible.

(...)

;*************************************************
; Device config files - One for each device.
;*************************************************
camera /usr/local/etc/motionplus/camera1.conf
camera /usr/local/etc/motionplus/camera2.conf
camera /usr/local/etc/motionplus/camera3.conf

Definition of the cameras that will be used and that will be described in the files mentioned above

(...)

;*************************************************
;***** Scripts
;*************************************************
on_event_start
/usr/local/bin/motionmail
on_event_end

script to be launched if there is an event in progress. The script simply contains

#!/bin/bash
mail -s “Motion event” olivier.hoarau@funix.org

(...)

;*************************************************
;***** Picture
;*************************************************
picture_output off
picture_filename %v-%Y%m%d%H%M%S-%q

;*************************************************
;***** Movie
;*******************************************
movie_output on
movie_max_time 120
movie_quality 45
movie_container mp4
movie_filename %v-%Y%m%d%H%M%S

for each event it is a video using the mp4 container (and the x265 codec) which will be used, you must set picture_output to on to have snapshots

(...)

;*************************************************
;***** Database
;******************************************************

database_type mariadb
database_dbname motionplus
database_host mariadb-server
database_port 3306
database_user root
database_password password

These last directives allow access to the motionplus database. The software does not integrate an email or SMS alert system by default, however we have the on_motion_detected parameter which will allow you to launch a script that can make this alert.

Now for a secure connection with password and TLS encryption we will add the following lines

;***** Web Control
;*************************************************
webcontrol_port 8080
webcontrol_localhost off
webcontrol_parms 3
webcontrol_auth_method digest
webcontrol_authentication user:motdepasse
webcontrol_tls on
webcontrol_cert /etc/ssl/public/apache.crt
webcontrol_key /etc/ssl/apache/apache.key

I used the personal certificate and key defined here.

For more details about the configuration file, see this page https://motion-project.github.io/motionplus_config.html

We now define the camera configuration files, example below with an IP camera accessible via rtsp and a webcam.

; /usr/local/etc/motionplus/camera1.conf
;
; This config file was generated by motionplus 0.2.2

;*************************************************
; Configuration options specific to camera 1
;*************************************************

;*************************************************
;***** Camera
;*************************************************
device_name MyCam1
device_id 101

;*************************************************
;***** Source
;*************************************************
netcam_url rtps://admin:password@192.168.2.110

;*************************************
;***** Image
;*************************************************
width 1280
height 720

;*************************************************
;***** Overlays
;*************************************************
text_left CAMERA 1

;*************************************************
;***** Movie
;*************************************************
movie_filename CAM01_%t-%v-%Y%m%d%H%M%S

and the file for the second camera

; /usr/local/etc/motionplus/camera2.conf
;
; This config file was generated by motionplus 0.2.2

;*************************************************
; Configuration options specific to camera 2
;*************************************************

;*************************************************
;***** Camera
;*************************************************
device_name Patio
device_id 102

;*************************************************
;***** Source
;*************************************************
v4l2_device /dev/video0

;*************************************************
;***** Image
;*************************************************
width 352
height 288

;*************************************************
;***** Overlays
;*************************************************
text_left Camera2
text_right Patio\n%Y-%m-%d\n%T-%q

;*************************************************
;***** Movie
;*************************************************
movie_filename CAM02_%t-%v-%Y%m%d%H%M%S

[ back to top of page ]

Use

Now we launch motionplus, the owner of the process must be able to write in the directory designated by target_dir (avoid root...). Here is the result

Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] conf_process: Processing config file /usr/local/etc/motionplus/motionplus.conf
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] conf_edit_stream_preview_method: Invalid stream_preview_method combined
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] conf_process: Processing config file /usr/local/etc/motionplus/camera1.conf
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] conf_process: Processing config file /usr/local/etc/motionplus/camera2.conf
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] conf_process: Processing config file /usr/local/etc/motionplus/camera3.conf
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] log_init: Logging to syslog
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] log_init: MotionPlus 0.2.2 started
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] log_init: Using log type (ALL) log level (NTC)
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] mytranslate_init: Language: English
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][STR][00:motionplus] webu_init_webcontrol: Starting webcontrol on port 8080
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][STR][00:motionplus] webu_init_webcontrol: Started webcontrol on port 8080
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ENC][00:motionplus] motpls_av_init: libavcodec version 61.3.100
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ENC][00:motionplus] motpls_av_init: libavformat version 61.1.100
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][VID][00:ml00:camera-sud] netcam_start: Opening Netcam
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][VID][02:ml02:Piece2] netcam_start: Opening Netcam
oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:motionplus] main: Motionplus pid: 1331263
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][VID][01:ml01:Piece1] netcam_start: Opening Netcam
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_handler: Norm: Camera handler thread [5] started
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][02:ml02:Piece2] mlp_ring_resize: Resizing buffer to 4 items
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][01:ml01:Piece1] mlp_ring_resize: Resizing buffer to 4 items
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_handler: Norm: Camera handler thread [6] started
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Camera (Piece2) connected
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Netcam capture FPS is 15.
Oct. 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Unable to determine the camera source FPS.
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Camera (Piece1) connected
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Netcam capture FPS is 15.
Oct 25 17:09:33 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Unable to determine the camera source FPS.
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc:
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: ******************************************************
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: The network camera is sending pictures at 0x0
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: resolution but config is 1280x720. If possible change
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: the netcam or config so that the image height and
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: width are the same to lower the CPU usage.
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc: ******************************************************
Oct 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][00:ml00:camera-sud] netcam_ntc:
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:ml00:camera-sud] mlp_ring_resize: Resizing buffer to 4 items
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][NET][03:nc03:camera-sud] netcam_handler: Norm: Camera handler thread [3] started
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][02:ml02:Piece2] mlp_init: Camera 103 started: motion detection Enabled
Oct. 25 17:09:35 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][01:ml01:Piece1] mlp_init: Camera 102 started: motion detection Enabled
Oct 25 17:09:36 ultra.kervao.fr motionplus[1331263]: [NTC][NET][03:nc03:camera-sud] netcam_connect: Norm: Camera (camera-sud) connected
Oct 25 17:09:36 ultra.kervao.fr motionplus[1331263]: [NTC][NET][03:nc03:camera-sud] netcam_connect: Norm: Netcam capture FPS is 21.
Oct. 25 17:09:36 ultra.kervao.fr motionplus[1331263]: [NTC][NET][03:nc03:camera-sud] netcam_connect: Norm: Camera source is 20 FPS
Oct. 25 17:09:37 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][00:ml00:camera-sud] mlp_init: Camera 101 started: motion detection Enabled

You will notice that when passing in front of the webcam the videos accumulate under /emile/photo/motion, it works!! The log will give the following line to each movement identified as an event.

[NTC][ALL][ml01:MyCam2] mlp_detected_trigger: Motion detected - starting event 1

The application has a web interface visible at the URL http://localhost:8080/. We see the different views in real time

Configuration is possible from the interface

Events are accessible via Recordings


First of all, for motionplus to be launched via systemd, we will ensure that the daemon parameter is set to off in the configuration file

;*************************************************
;***** System
;*************************************************
daemon off
;log_file
log_level 6
log_type ALL

We will then create the file /usr/lib/systemd/system/motionplus.service which will contain

[Unit]
Description=Motion - monitor live video, trigger responses, record video/stills.
After=local-fs.target network.target

[Service]
User=apache
EnvironmentFile=-/usr/local/etc/motionplus
ExecStart=/usr/local/bin/motionplus -n
Type=simple
ExecReload=@KILL@ -HUP $MAINPID
Restart=on-failure
RestartSec=5
# Don't restart if unconfigured / misconfigured eg daemon disabled
# in defaults file. See also /usr/include/sysexits.h or sysexits(3)
RestartPreventExitStatus=78

[Install]
WantedBy=multi-user.target

And we will launch motionplus by typing

systemctl start motionplus

the following command

systemctl status motionplus

will give

● motionplus.service - Motion - monitor live video, trigger responses, record video/stills.
     Loaded: loaded (/usr/lib/systemd/system/motionplus.service; disabled; preset: disabled)
     Active: active (running) since Fri 2024-10-25 17:09:33 CEST; 52min ago
   Main PID: 1331263 (motionplus)
      Tasks: 17 (limit: 9239)
     Memory: 120.2M
        CPU: 42min 59.330s
     CGroup: /system.slice/motionplus.service
             └─1331263 /usr/local/bin/motionplus -n

Oct 25 18:00:49 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_handler_reconnect: Norm: Reconnecting with camera....
Oct 25 18:00:49 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Camera (Piece1) connected
Oct 25 18:00:49 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Netcam capture FPS is 15.
Oct 25 18:00:49 ultra.kervao.fr motionplus[1331263]: [NTC][NET][06:nc06:Piece1] netcam_connect: Norm: Unable to determine the camera source FPS.
Oct 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_handler_reconnect: Norm: Reconnecting with camera....
Oct 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Camera (Piece2) connected
Oct. 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Netcam capture FPS is 15.
Oct. 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][NET][05:nc05:Piece2] netcam_connect: Norm: Unable to determine the camera source FPS.
Oct 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][ALL][02:ml02:Piece2] mlp_detected_trigger: Motion detected - starting event
Oct 17 25 18:01:17 ultra.kervao.fr motionplus[1331263]: [NTC][EVT][02:ml02:Piece2] on_movie_start_command: File saved to: /media/motion/CAM03_103-17-20241025180117.mp4

to make it permanently active we will type

systemctl enable motionplus

Now you can open the ports of your server so that the motionplus web interface is accessible on the internet.

So that the recorded files do not explode the disk, you can delete the files from the interface or you can create a cron task which a regulard intervals will delete the files which are more than 5 days old (for example), here is the content of the cleaning executable file to add in /etc/cron.weekly (execution once a week)

#!/bin/bash
find /emile/photo/motion -type f -name "*.mkv" -mtime +5 -exec rm {} \;

Please note that you will need to delete the corresponding events in the mariadb database.
 
[ Back to FUNIX home page ] [ back to top of page ]