<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.staging.zoneminder.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Burger</id>
	<title>ZoneMinder Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.staging.zoneminder.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Burger"/>
	<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/Special:Contributions/Burger"/>
	<updated>2026-05-03T13:37:57Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17939</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17939"/>
		<updated>2026-04-20T01:56:51Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Disable Logging via cli */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A. For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm. I would recommend setting this in a crontab on a zm server, just so you don&amp;#039;t accidentally leave logging on at some point.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17938</id>
		<title>Finding Camera Stream Paths</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17938"/>
		<updated>2026-04-12T13:08:38Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Reverse Engineering Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains methods and approaches for getting cameras to work with ZM. The best results will be with cameras tested by users in the [[Hardware Compatibility List]]. Next will be with cameras that detail the path in user manuals, and or are Onvif compliant. Proprietary and undocumented cameras are more difficult.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Overall, this can be as simple as looking in the user manual, or as complicated as reverse engineering and breaking into the device.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Typical methods of obtaining the cameras paths in order of easiest to hardest are:&lt;br /&gt;
&lt;br /&gt;
*User Manual/Website&lt;br /&gt;
*Onvif probe&lt;br /&gt;
*Search online resources and forums&lt;br /&gt;
*Get access to the camera shell&lt;br /&gt;
*Intercept network packets with TCPDump or Wireshark&lt;br /&gt;
*Reverse Engineer&lt;br /&gt;
&lt;br /&gt;
Double check that you don&amp;#039;t have any other settings that may block cameras communicating to your computer (firewall, antivirus, etc). For new users who install using the [https://wiki.zoneminder.com/Helpful_user_contributed_resources#Installation_Procedure recommended install] guides, this should not be a concern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; While doing this testing, you want to keep in mind the following:&lt;br /&gt;
* Test outside of ZM, first. (this is faster)&lt;br /&gt;
* Verify that ffmpeg / vlc works (see below for examples of usage)&lt;br /&gt;
* use the info that works in ffmpeg or vlc in zm.&lt;br /&gt;
&lt;br /&gt;
==Testing out a Camera==&lt;br /&gt;
Easy tools to quickly check whether a stream path works in ZM or not are [[VLC]] and [[Ffmpeg]].&lt;br /&gt;
As an example, VLC from the gui (file -&amp;gt; connect to network stream) would connect with a path possibly like&lt;br /&gt;
 rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the hardware compatibility lists for more details. Port for RTSP is usually but not always 554.&lt;br /&gt;
&lt;br /&gt;
If you want to test from the terminal without X, you can use ffmpeg&lt;br /&gt;
 $ ffmpeg -i rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;  output.mp4&lt;br /&gt;
 or (from X)&lt;br /&gt;
 $ ffplay rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the stream connects, it will provide you with some information about the stream encoding, and also the resolution.&lt;br /&gt;
&lt;br /&gt;
Note that the above are examples for RTSP. You would use http for MJPEG. See the [[Hardware Compatibility List]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Required Fields==&lt;br /&gt;
&lt;br /&gt;
Not all fields are required to be filled in for Zoneminder. &lt;br /&gt;
&lt;br /&gt;
* Resolution must be right. &lt;br /&gt;
* Most cameras require username/password.&lt;br /&gt;
&lt;br /&gt;
If you are unsure how to fill in the information into Zoneminder, refer to the [[Hardware Compatibility List]] for other cameras, and copy them.&lt;br /&gt;
&lt;br /&gt;
Note that the results you get from cameras will differ depending on how you connect to the camera (whether you choose, remote, ffmpeg, or libvlc in ZM).&lt;br /&gt;
&lt;br /&gt;
===Example Camera===&lt;br /&gt;
Here&amp;#039;s an example of one camera setup in ZM. Note that this is not the only way to setup cameras. There are a lot of other approaches that would&amp;#039;ve been equally viable. But in this example, we use FFMPEG, motion detection, a preview of 800x600, and h264 passthrough so that recorded videos are the full resolution (1920x1280). Also note that with this camera it&amp;#039;s possible to set parameters via the address (e.g. the ? at the end of the URL can have fps or resolution set) which makes it easier to maintain the cameras instead of having to use the Web interface of the camera.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Zmcamera example1.png|General Tab|link=https://wiki.zoneminder.com/images/a/ae/Zmcamera_example1.png&lt;br /&gt;
File:Zmcamera example2.png|Source Tab|link=https://wiki.zoneminder.com/images/5/52/Zmcamera_example2.png&lt;br /&gt;
File:Zmcamera example3.png|Storage Tab|link=https://wiki.zoneminder.com/images/f/ff/Zmcamera_example3.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===User Manual===&lt;br /&gt;
&lt;br /&gt;
Reputable name brand cameras will provide video stream paths in the user manual or website. If you bought an unbranded cheap camera or one of the proprietary &amp;#039;cloud&amp;#039; cameras sold in retail stores then you must move onto the other options.&lt;br /&gt;
&lt;br /&gt;
[[File:Usermanualexample1.png|350px|thumb|right|Here, the user manual indicates the RTSP path.]]&lt;br /&gt;
&lt;br /&gt;
===Onvif===&lt;br /&gt;
&lt;br /&gt;
Starting with Zoneminder 1.30.4 there is an Onvif probe option in the camera configuration. You can also use external Onvif programs. Onvif is an open standard protocol, where you can get the path information from the cameras, and possibly other information such as PTZ commands or motion detection. https://en.wikipedia.org/wiki/ONVIF&lt;br /&gt;
&lt;br /&gt;
===Web Search Online===&lt;br /&gt;
&lt;br /&gt;
Ispyconnect has a large database of URLs available for cameras. The ZM wiki has some. Use a search engine. You may also come across a telnet or ssh password, which can be used to gain access to the camera shell.&lt;br /&gt;
&lt;br /&gt;
===Camera Shell===&lt;br /&gt;
&lt;br /&gt;
Many cameras run GNU/Linux. If you can get access to the files on the camera, through telnet, or through exploiting a vulnerability in the camera, then you can look around for paths. You may be able to send files from the camera to your local machine using FTP. Cameras often have busybox, or similar utils. Running the command &amp;quot;strings&amp;quot; on binaries may come up with something. Run nmap on the camera to see what ports are open. See more details in external links at the bottom.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap -p1-65535 &amp;lt;ipaddressofcamera&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also try (from:https://ipcamtalk.com/threads/imou-ranger-pro-rtsp-problems-solved.60271/) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap --script rtsp-url-brute -p 554 &amp;lt;ipaddress&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wireshark/TCPdump===&lt;br /&gt;
&lt;br /&gt;
Watch the packets coming from the camera when accessing the video stream, and determine where the stream is located if possible. Some cameras require custom authentication, so if your camera is proprietary, then things are more difficult. This is the danger of purchasing cameras that don&amp;#039;t follow the standard (onvif). Some cameras will also announce the camera stream URL when they boot on the network. Wireshark and or TCPdump can be useful for this. At the least, they may indicate the IP address.&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering===&lt;br /&gt;
&lt;br /&gt;
Reverse engineering is one possibly time-intensive method of getting information from a given camera. See the reverse engineering links below.&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
* Some cameras have limited space for username / password. Be wary of the camera cutting off the end of the password.&lt;br /&gt;
* Some cameras don&amp;#039;t handle special characters in passwords well. https://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=117987#p117987&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
&lt;br /&gt;
*[https://www.ispyconnect.com/userguide-connecting-cameras.aspx iSpy Connect cameras guide]&lt;br /&gt;
*[https://www.ispyconnect.com/sources.aspx  iSpy Database]&lt;br /&gt;
*[http://zoneminder.readthedocs.io/en/latest/userguide/definemonitor.html Official ZM Documentation] on this subject&lt;br /&gt;
*[https://shinobi.video/docs/cameras Shinobi List]&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering Links===&lt;br /&gt;
*https://web.archive.org/web/20180124024708/https://github.com/sgayou/medfusion-4000-research/blob/master/doc/README.md Advanced reverse engineering/exploitation of a medical device&lt;br /&gt;
*https://www.contextis.com/blog/push-hack-reverse-engineering-ip-camera Reverse Engineering an IP Camera&lt;br /&gt;
*https://alexhude.github.io/2019/01/24/hacking-leica-m240.html Reverse Engineering a consumer camera&lt;br /&gt;
&lt;br /&gt;
*http://web.archive.org/web/20190609073446/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-i/  Wyzesensor reverse engineering (1/3)&lt;br /&gt;
*http://web.archive.org/web/20190606222131/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-ii/ Wyzesensor reverse engineering (2/3)&lt;br /&gt;
*https://hclxing.wordpress.com/2019/06/06/reverse-engineering-wyzesense-bridge-protocol-part-iii/ Wyzesensor reverse engineering (3/3)&lt;br /&gt;
*https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks Xiaomi / Wyzecam Camera Reverse Engineering&lt;br /&gt;
*https://www.eionix.co.in/2019/10/10/reverse-engineer-ddpai-firmware.html Reverse Engineering a Dashcam&lt;br /&gt;
*Huang, Andrew &amp;quot;Bunnie&amp;quot;, (2017) The Hardware Hacker. pg 279. No Starch Press.&lt;br /&gt;
*http://web.archive.org/web/20201102155358/https://wrongbaud.github.io/Holiday-Teardown/ &lt;br /&gt;
*http://web.archive.org/web/20210212100444/https://frdmtoplay.com/patching-in-fahrenheit/ - Disassembly and patching.&lt;br /&gt;
*https://unnamedre.com/ Podcast on reverse engineering. I haven&amp;#039;t listened to it yet, but it may be a valuable reference.&lt;br /&gt;
*https://www.eevblog.com/forum/reviews/identifying-the-mcu-from-rt85-handheld-radio/ - firmware hacking of a handheld radio&lt;br /&gt;
*http://web.archive.org/web/20230210164816/https://eta.st/2023/01/31/rail-tickets.html - qr codes&lt;br /&gt;
*https://github.com/racerxdl/stm32f0-pico-dump&lt;br /&gt;
*https://hackaday.com/2022/05/04/dumping-encrypted-at-rest-firmware-of-xiaomi-smart-kettle/&lt;br /&gt;
*https://hackaday.com/2023/02/05/need-to-dump-a-protected-stm32f0x-use-your-pico/&lt;br /&gt;
*https://youtu.be/Y7Z5Q_sNqUw  SUPERCON 2022: Kuba Tyszko Cracks Encrypted Software&lt;br /&gt;
*https://hackaday.com/2024/01/19/alarm-panel-hack-defeats-encryption-by-ignoring-it/ - Sometimes you can just go right to the display and buttons and ignore the rest of the device&lt;br /&gt;
*https://youtu.be/uGfVn-cyz3o https://youtu.be/lbSalKp_ldA IP Camera firmware extraction and disassembly of a hardcoded password &lt;br /&gt;
*https://hackaday.com/2026/02/14/reverse-engineering-a-dash-robot-with-ghidra/ - Ghidra disassembly of binaries.&lt;br /&gt;
*https://www.robopenguins.com/reverse-dash/ - From the previous link. &lt;br /&gt;
*https://fippi.io/reverse-engineering-adventure-canoe/ - Finding passwords with ghidra and gdb for an old arcade game. This is pretty well written and easy to follow. A good example of shallow reverse engineering (i.e. not going into something too difficult). Also rearranges the files for MAME.&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17937</id>
		<title>Finding Camera Stream Paths</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17937"/>
		<updated>2026-04-12T13:08:14Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Reverse Engineering Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains methods and approaches for getting cameras to work with ZM. The best results will be with cameras tested by users in the [[Hardware Compatibility List]]. Next will be with cameras that detail the path in user manuals, and or are Onvif compliant. Proprietary and undocumented cameras are more difficult.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Overall, this can be as simple as looking in the user manual, or as complicated as reverse engineering and breaking into the device.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Typical methods of obtaining the cameras paths in order of easiest to hardest are:&lt;br /&gt;
&lt;br /&gt;
*User Manual/Website&lt;br /&gt;
*Onvif probe&lt;br /&gt;
*Search online resources and forums&lt;br /&gt;
*Get access to the camera shell&lt;br /&gt;
*Intercept network packets with TCPDump or Wireshark&lt;br /&gt;
*Reverse Engineer&lt;br /&gt;
&lt;br /&gt;
Double check that you don&amp;#039;t have any other settings that may block cameras communicating to your computer (firewall, antivirus, etc). For new users who install using the [https://wiki.zoneminder.com/Helpful_user_contributed_resources#Installation_Procedure recommended install] guides, this should not be a concern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; While doing this testing, you want to keep in mind the following:&lt;br /&gt;
* Test outside of ZM, first. (this is faster)&lt;br /&gt;
* Verify that ffmpeg / vlc works (see below for examples of usage)&lt;br /&gt;
* use the info that works in ffmpeg or vlc in zm.&lt;br /&gt;
&lt;br /&gt;
==Testing out a Camera==&lt;br /&gt;
Easy tools to quickly check whether a stream path works in ZM or not are [[VLC]] and [[Ffmpeg]].&lt;br /&gt;
As an example, VLC from the gui (file -&amp;gt; connect to network stream) would connect with a path possibly like&lt;br /&gt;
 rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the hardware compatibility lists for more details. Port for RTSP is usually but not always 554.&lt;br /&gt;
&lt;br /&gt;
If you want to test from the terminal without X, you can use ffmpeg&lt;br /&gt;
 $ ffmpeg -i rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;  output.mp4&lt;br /&gt;
 or (from X)&lt;br /&gt;
 $ ffplay rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the stream connects, it will provide you with some information about the stream encoding, and also the resolution.&lt;br /&gt;
&lt;br /&gt;
Note that the above are examples for RTSP. You would use http for MJPEG. See the [[Hardware Compatibility List]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Required Fields==&lt;br /&gt;
&lt;br /&gt;
Not all fields are required to be filled in for Zoneminder. &lt;br /&gt;
&lt;br /&gt;
* Resolution must be right. &lt;br /&gt;
* Most cameras require username/password.&lt;br /&gt;
&lt;br /&gt;
If you are unsure how to fill in the information into Zoneminder, refer to the [[Hardware Compatibility List]] for other cameras, and copy them.&lt;br /&gt;
&lt;br /&gt;
Note that the results you get from cameras will differ depending on how you connect to the camera (whether you choose, remote, ffmpeg, or libvlc in ZM).&lt;br /&gt;
&lt;br /&gt;
===Example Camera===&lt;br /&gt;
Here&amp;#039;s an example of one camera setup in ZM. Note that this is not the only way to setup cameras. There are a lot of other approaches that would&amp;#039;ve been equally viable. But in this example, we use FFMPEG, motion detection, a preview of 800x600, and h264 passthrough so that recorded videos are the full resolution (1920x1280). Also note that with this camera it&amp;#039;s possible to set parameters via the address (e.g. the ? at the end of the URL can have fps or resolution set) which makes it easier to maintain the cameras instead of having to use the Web interface of the camera.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Zmcamera example1.png|General Tab|link=https://wiki.zoneminder.com/images/a/ae/Zmcamera_example1.png&lt;br /&gt;
File:Zmcamera example2.png|Source Tab|link=https://wiki.zoneminder.com/images/5/52/Zmcamera_example2.png&lt;br /&gt;
File:Zmcamera example3.png|Storage Tab|link=https://wiki.zoneminder.com/images/f/ff/Zmcamera_example3.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===User Manual===&lt;br /&gt;
&lt;br /&gt;
Reputable name brand cameras will provide video stream paths in the user manual or website. If you bought an unbranded cheap camera or one of the proprietary &amp;#039;cloud&amp;#039; cameras sold in retail stores then you must move onto the other options.&lt;br /&gt;
&lt;br /&gt;
[[File:Usermanualexample1.png|350px|thumb|right|Here, the user manual indicates the RTSP path.]]&lt;br /&gt;
&lt;br /&gt;
===Onvif===&lt;br /&gt;
&lt;br /&gt;
Starting with Zoneminder 1.30.4 there is an Onvif probe option in the camera configuration. You can also use external Onvif programs. Onvif is an open standard protocol, where you can get the path information from the cameras, and possibly other information such as PTZ commands or motion detection. https://en.wikipedia.org/wiki/ONVIF&lt;br /&gt;
&lt;br /&gt;
===Web Search Online===&lt;br /&gt;
&lt;br /&gt;
Ispyconnect has a large database of URLs available for cameras. The ZM wiki has some. Use a search engine. You may also come across a telnet or ssh password, which can be used to gain access to the camera shell.&lt;br /&gt;
&lt;br /&gt;
===Camera Shell===&lt;br /&gt;
&lt;br /&gt;
Many cameras run GNU/Linux. If you can get access to the files on the camera, through telnet, or through exploiting a vulnerability in the camera, then you can look around for paths. You may be able to send files from the camera to your local machine using FTP. Cameras often have busybox, or similar utils. Running the command &amp;quot;strings&amp;quot; on binaries may come up with something. Run nmap on the camera to see what ports are open. See more details in external links at the bottom.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap -p1-65535 &amp;lt;ipaddressofcamera&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also try (from:https://ipcamtalk.com/threads/imou-ranger-pro-rtsp-problems-solved.60271/) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap --script rtsp-url-brute -p 554 &amp;lt;ipaddress&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wireshark/TCPdump===&lt;br /&gt;
&lt;br /&gt;
Watch the packets coming from the camera when accessing the video stream, and determine where the stream is located if possible. Some cameras require custom authentication, so if your camera is proprietary, then things are more difficult. This is the danger of purchasing cameras that don&amp;#039;t follow the standard (onvif). Some cameras will also announce the camera stream URL when they boot on the network. Wireshark and or TCPdump can be useful for this. At the least, they may indicate the IP address.&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering===&lt;br /&gt;
&lt;br /&gt;
Reverse engineering is one possibly time-intensive method of getting information from a given camera. See the reverse engineering links below.&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
* Some cameras have limited space for username / password. Be wary of the camera cutting off the end of the password.&lt;br /&gt;
* Some cameras don&amp;#039;t handle special characters in passwords well. https://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=117987#p117987&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
&lt;br /&gt;
*[https://www.ispyconnect.com/userguide-connecting-cameras.aspx iSpy Connect cameras guide]&lt;br /&gt;
*[https://www.ispyconnect.com/sources.aspx  iSpy Database]&lt;br /&gt;
*[http://zoneminder.readthedocs.io/en/latest/userguide/definemonitor.html Official ZM Documentation] on this subject&lt;br /&gt;
*[https://shinobi.video/docs/cameras Shinobi List]&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering Links===&lt;br /&gt;
*https://web.archive.org/web/20180124024708/https://github.com/sgayou/medfusion-4000-research/blob/master/doc/README.md Advanced reverse engineering/exploitation of a medical device&lt;br /&gt;
*https://www.contextis.com/blog/push-hack-reverse-engineering-ip-camera Reverse Engineering an IP Camera&lt;br /&gt;
*https://alexhude.github.io/2019/01/24/hacking-leica-m240.html Reverse Engineering a consumer camera&lt;br /&gt;
&lt;br /&gt;
*http://web.archive.org/web/20190609073446/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-i/  Wyzesensor reverse engineering (1/3)&lt;br /&gt;
*http://web.archive.org/web/20190606222131/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-ii/ Wyzesensor reverse engineering (2/3)&lt;br /&gt;
*https://hclxing.wordpress.com/2019/06/06/reverse-engineering-wyzesense-bridge-protocol-part-iii/ Wyzesensor reverse engineering (3/3)&lt;br /&gt;
*https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks Xiaomi / Wyzecam Camera Reverse Engineering&lt;br /&gt;
*https://www.eionix.co.in/2019/10/10/reverse-engineer-ddpai-firmware.html Reverse Engineering a Dashcam&lt;br /&gt;
*Huang, Andrew &amp;quot;Bunnie&amp;quot;, (2017) The Hardware Hacker. pg 279. No Starch Press.&lt;br /&gt;
*http://web.archive.org/web/20201102155358/https://wrongbaud.github.io/Holiday-Teardown/ &lt;br /&gt;
*http://web.archive.org/web/20210212100444/https://frdmtoplay.com/patching-in-fahrenheit/ - Disassembly and patching.&lt;br /&gt;
*https://unnamedre.com/ Podcast on reverse engineering. I haven&amp;#039;t listened to it yet, but it may be a valuable reference.&lt;br /&gt;
*https://www.eevblog.com/forum/reviews/identifying-the-mcu-from-rt85-handheld-radio/ - firmware hacking of a handheld radio&lt;br /&gt;
*http://web.archive.org/web/20230210164816/https://eta.st/2023/01/31/rail-tickets.html - qr codes&lt;br /&gt;
*https://github.com/racerxdl/stm32f0-pico-dump&lt;br /&gt;
*https://hackaday.com/2022/05/04/dumping-encrypted-at-rest-firmware-of-xiaomi-smart-kettle/&lt;br /&gt;
*https://hackaday.com/2023/02/05/need-to-dump-a-protected-stm32f0x-use-your-pico/&lt;br /&gt;
*https://youtu.be/Y7Z5Q_sNqUw  SUPERCON 2022: Kuba Tyszko Cracks Encrypted Software&lt;br /&gt;
*https://hackaday.com/2024/01/19/alarm-panel-hack-defeats-encryption-by-ignoring-it/ - Sometimes you can just go right to the display and buttons and ignore the rest of the device&lt;br /&gt;
*https://youtu.be/uGfVn-cyz3o https://youtu.be/lbSalKp_ldA IP Camera firmware extraction and disassembly of a hardcoded password &lt;br /&gt;
*https://hackaday.com/2026/02/14/reverse-engineering-a-dash-robot-with-ghidra/ - Ghidra disassembly of binaries.&lt;br /&gt;
*https://www.robopenguins.com/reverse-dash/ - From the previous link. &lt;br /&gt;
*https://fippi.io/reverse-engineering-adventure-canoe/ - Finding passwords with ghidra and gdb for an old arcade game. This is pretty well written and easy to follow. A good example of shallow reverse engineering (i.e. not going into something too difficult).&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17936</id>
		<title>Finding Camera Stream Paths</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17936"/>
		<updated>2026-04-12T12:50:45Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Reverse Engineering Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains methods and approaches for getting cameras to work with ZM. The best results will be with cameras tested by users in the [[Hardware Compatibility List]]. Next will be with cameras that detail the path in user manuals, and or are Onvif compliant. Proprietary and undocumented cameras are more difficult.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Overall, this can be as simple as looking in the user manual, or as complicated as reverse engineering and breaking into the device.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Typical methods of obtaining the cameras paths in order of easiest to hardest are:&lt;br /&gt;
&lt;br /&gt;
*User Manual/Website&lt;br /&gt;
*Onvif probe&lt;br /&gt;
*Search online resources and forums&lt;br /&gt;
*Get access to the camera shell&lt;br /&gt;
*Intercept network packets with TCPDump or Wireshark&lt;br /&gt;
*Reverse Engineer&lt;br /&gt;
&lt;br /&gt;
Double check that you don&amp;#039;t have any other settings that may block cameras communicating to your computer (firewall, antivirus, etc). For new users who install using the [https://wiki.zoneminder.com/Helpful_user_contributed_resources#Installation_Procedure recommended install] guides, this should not be a concern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; While doing this testing, you want to keep in mind the following:&lt;br /&gt;
* Test outside of ZM, first. (this is faster)&lt;br /&gt;
* Verify that ffmpeg / vlc works (see below for examples of usage)&lt;br /&gt;
* use the info that works in ffmpeg or vlc in zm.&lt;br /&gt;
&lt;br /&gt;
==Testing out a Camera==&lt;br /&gt;
Easy tools to quickly check whether a stream path works in ZM or not are [[VLC]] and [[Ffmpeg]].&lt;br /&gt;
As an example, VLC from the gui (file -&amp;gt; connect to network stream) would connect with a path possibly like&lt;br /&gt;
 rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the hardware compatibility lists for more details. Port for RTSP is usually but not always 554.&lt;br /&gt;
&lt;br /&gt;
If you want to test from the terminal without X, you can use ffmpeg&lt;br /&gt;
 $ ffmpeg -i rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;  output.mp4&lt;br /&gt;
 or (from X)&lt;br /&gt;
 $ ffplay rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the stream connects, it will provide you with some information about the stream encoding, and also the resolution.&lt;br /&gt;
&lt;br /&gt;
Note that the above are examples for RTSP. You would use http for MJPEG. See the [[Hardware Compatibility List]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Required Fields==&lt;br /&gt;
&lt;br /&gt;
Not all fields are required to be filled in for Zoneminder. &lt;br /&gt;
&lt;br /&gt;
* Resolution must be right. &lt;br /&gt;
* Most cameras require username/password.&lt;br /&gt;
&lt;br /&gt;
If you are unsure how to fill in the information into Zoneminder, refer to the [[Hardware Compatibility List]] for other cameras, and copy them.&lt;br /&gt;
&lt;br /&gt;
Note that the results you get from cameras will differ depending on how you connect to the camera (whether you choose, remote, ffmpeg, or libvlc in ZM).&lt;br /&gt;
&lt;br /&gt;
===Example Camera===&lt;br /&gt;
Here&amp;#039;s an example of one camera setup in ZM. Note that this is not the only way to setup cameras. There are a lot of other approaches that would&amp;#039;ve been equally viable. But in this example, we use FFMPEG, motion detection, a preview of 800x600, and h264 passthrough so that recorded videos are the full resolution (1920x1280). Also note that with this camera it&amp;#039;s possible to set parameters via the address (e.g. the ? at the end of the URL can have fps or resolution set) which makes it easier to maintain the cameras instead of having to use the Web interface of the camera.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Zmcamera example1.png|General Tab|link=https://wiki.zoneminder.com/images/a/ae/Zmcamera_example1.png&lt;br /&gt;
File:Zmcamera example2.png|Source Tab|link=https://wiki.zoneminder.com/images/5/52/Zmcamera_example2.png&lt;br /&gt;
File:Zmcamera example3.png|Storage Tab|link=https://wiki.zoneminder.com/images/f/ff/Zmcamera_example3.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===User Manual===&lt;br /&gt;
&lt;br /&gt;
Reputable name brand cameras will provide video stream paths in the user manual or website. If you bought an unbranded cheap camera or one of the proprietary &amp;#039;cloud&amp;#039; cameras sold in retail stores then you must move onto the other options.&lt;br /&gt;
&lt;br /&gt;
[[File:Usermanualexample1.png|350px|thumb|right|Here, the user manual indicates the RTSP path.]]&lt;br /&gt;
&lt;br /&gt;
===Onvif===&lt;br /&gt;
&lt;br /&gt;
Starting with Zoneminder 1.30.4 there is an Onvif probe option in the camera configuration. You can also use external Onvif programs. Onvif is an open standard protocol, where you can get the path information from the cameras, and possibly other information such as PTZ commands or motion detection. https://en.wikipedia.org/wiki/ONVIF&lt;br /&gt;
&lt;br /&gt;
===Web Search Online===&lt;br /&gt;
&lt;br /&gt;
Ispyconnect has a large database of URLs available for cameras. The ZM wiki has some. Use a search engine. You may also come across a telnet or ssh password, which can be used to gain access to the camera shell.&lt;br /&gt;
&lt;br /&gt;
===Camera Shell===&lt;br /&gt;
&lt;br /&gt;
Many cameras run GNU/Linux. If you can get access to the files on the camera, through telnet, or through exploiting a vulnerability in the camera, then you can look around for paths. You may be able to send files from the camera to your local machine using FTP. Cameras often have busybox, or similar utils. Running the command &amp;quot;strings&amp;quot; on binaries may come up with something. Run nmap on the camera to see what ports are open. See more details in external links at the bottom.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap -p1-65535 &amp;lt;ipaddressofcamera&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also try (from:https://ipcamtalk.com/threads/imou-ranger-pro-rtsp-problems-solved.60271/) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap --script rtsp-url-brute -p 554 &amp;lt;ipaddress&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wireshark/TCPdump===&lt;br /&gt;
&lt;br /&gt;
Watch the packets coming from the camera when accessing the video stream, and determine where the stream is located if possible. Some cameras require custom authentication, so if your camera is proprietary, then things are more difficult. This is the danger of purchasing cameras that don&amp;#039;t follow the standard (onvif). Some cameras will also announce the camera stream URL when they boot on the network. Wireshark and or TCPdump can be useful for this. At the least, they may indicate the IP address.&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering===&lt;br /&gt;
&lt;br /&gt;
Reverse engineering is one possibly time-intensive method of getting information from a given camera. See the reverse engineering links below.&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
* Some cameras have limited space for username / password. Be wary of the camera cutting off the end of the password.&lt;br /&gt;
* Some cameras don&amp;#039;t handle special characters in passwords well. https://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=117987#p117987&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
&lt;br /&gt;
*[https://www.ispyconnect.com/userguide-connecting-cameras.aspx iSpy Connect cameras guide]&lt;br /&gt;
*[https://www.ispyconnect.com/sources.aspx  iSpy Database]&lt;br /&gt;
*[http://zoneminder.readthedocs.io/en/latest/userguide/definemonitor.html Official ZM Documentation] on this subject&lt;br /&gt;
*[https://shinobi.video/docs/cameras Shinobi List]&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering Links===&lt;br /&gt;
*https://web.archive.org/web/20180124024708/https://github.com/sgayou/medfusion-4000-research/blob/master/doc/README.md Advanced reverse engineering/exploitation of a medical device&lt;br /&gt;
*https://www.contextis.com/blog/push-hack-reverse-engineering-ip-camera Reverse Engineering an IP Camera&lt;br /&gt;
*https://alexhude.github.io/2019/01/24/hacking-leica-m240.html Reverse Engineering a consumer camera&lt;br /&gt;
&lt;br /&gt;
*http://web.archive.org/web/20190609073446/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-i/  Wyzesensor reverse engineering (1/3)&lt;br /&gt;
*http://web.archive.org/web/20190606222131/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-ii/ Wyzesensor reverse engineering (2/3)&lt;br /&gt;
*https://hclxing.wordpress.com/2019/06/06/reverse-engineering-wyzesense-bridge-protocol-part-iii/ Wyzesensor reverse engineering (3/3)&lt;br /&gt;
*https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks Xiaomi / Wyzecam Camera Reverse Engineering&lt;br /&gt;
*https://www.eionix.co.in/2019/10/10/reverse-engineer-ddpai-firmware.html Reverse Engineering a Dashcam&lt;br /&gt;
*Huang, Andrew &amp;quot;Bunnie&amp;quot;, (2017) The Hardware Hacker. pg 279. No Starch Press.&lt;br /&gt;
*http://web.archive.org/web/20201102155358/https://wrongbaud.github.io/Holiday-Teardown/ &lt;br /&gt;
*http://web.archive.org/web/20210212100444/https://frdmtoplay.com/patching-in-fahrenheit/ - Disassembly and patching.&lt;br /&gt;
*https://unnamedre.com/ Podcast on reverse engineering. I haven&amp;#039;t listened to it yet, but it may be a valuable reference.&lt;br /&gt;
*https://www.eevblog.com/forum/reviews/identifying-the-mcu-from-rt85-handheld-radio/ - firmware hacking of a handheld radio&lt;br /&gt;
*http://web.archive.org/web/20230210164816/https://eta.st/2023/01/31/rail-tickets.html - qr codes&lt;br /&gt;
*https://github.com/racerxdl/stm32f0-pico-dump&lt;br /&gt;
*https://hackaday.com/2022/05/04/dumping-encrypted-at-rest-firmware-of-xiaomi-smart-kettle/&lt;br /&gt;
*https://hackaday.com/2023/02/05/need-to-dump-a-protected-stm32f0x-use-your-pico/&lt;br /&gt;
*https://youtu.be/Y7Z5Q_sNqUw  SUPERCON 2022: Kuba Tyszko Cracks Encrypted Software&lt;br /&gt;
*https://hackaday.com/2024/01/19/alarm-panel-hack-defeats-encryption-by-ignoring-it/ - Sometimes you can just go right to the display and buttons and ignore the rest of the device&lt;br /&gt;
*https://youtu.be/uGfVn-cyz3o https://youtu.be/lbSalKp_ldA IP Camera firmware extraction and disassembly of a hardcoded password &lt;br /&gt;
*https://hackaday.com/2026/02/14/reverse-engineering-a-dash-robot-with-ghidra/ - Ghidra disassembly of binaries.&lt;br /&gt;
*https://www.robopenguins.com/reverse-dash/ - From the previous link. &lt;br /&gt;
*https://fippi.io/reverse-engineering-adventure-canoe/ - Finding passwords with ghidra and gdb for an old arcade game.&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17935</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17935"/>
		<updated>2026-04-08T08:15:18Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Timelapse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
===Timelapse===&lt;br /&gt;
&lt;br /&gt;
 today=date +%Y_%m_%d&lt;br /&gt;
 0 12 * * *   root wget http://user:password@ipaddress/jpg/image.jpg -O /externalstorage/timelapse/$(${today}).jpg&lt;br /&gt;
 #tricky business with the quoting, as always&lt;br /&gt;
 #see https://stackoverflow.com/questions/3639415/how-can-i-use-variables-in-my-crontab-entries&lt;br /&gt;
&lt;br /&gt;
There is no need to use zm for a timelapse. You can just grab photos manually using cron. The path to the jpg will differ depending upon&lt;br /&gt;
the make/model camera. This example is for Axis cameras&lt;br /&gt;
&lt;br /&gt;
One thing about timelapses, is how well can you keep storage without losing files. Over time it&amp;#039;s easy to have&lt;br /&gt;
a hdd fail. so you will want to backup offsite.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Ffmpeg&amp;diff=17934</id>
		<title>Ffmpeg</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Ffmpeg&amp;diff=17934"/>
		<updated>2026-04-07T06:29:19Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Convert Portion of Video to GIF/MP4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ffmpeg is a set of video processing tools used by ZoneMinder to generate video files from the network camera streams. There is a binary, as well as c/c++ libraries. It is likely that ffmpeg is used by many (if not most) surveillance video DVRs, as well as large software companies such as Google or Amazon.&lt;br /&gt;
&lt;br /&gt;
== About FFMPEG ==&lt;br /&gt;
&lt;br /&gt;
One thing to know about ffmpeg&lt;br /&gt;
is that it is versatile in what&lt;br /&gt;
inputs and outputs it can use.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
&lt;br /&gt;
you can input:    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from the desktop screen (there&amp;#039;s a couple of these. see the wiki)&lt;br /&gt;
x11grab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from the framebuffer itself&lt;br /&gt;
fbdev and /dev/fb0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from a network video stream&lt;br /&gt;
http://ongoingstream.mjpeg or rtsp://&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from a udp socket&lt;br /&gt;
udp://ipaddress:port&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from a video on your local machine&lt;br /&gt;
/directory/file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from a file on the internet&lt;br /&gt;
http://justafile.mp4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
from a pipe &lt;br /&gt;
rgbledoutput &amp;gt; ffmpeg&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
and you can also output to &lt;br /&gt;
most of these locations. More information is found on the ffmpeg wiki. https://trac.ffmpeg.org/wiki/&lt;br /&gt;
&lt;br /&gt;
===Where is ffmpeg in Zoneminder?===&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?t=32450&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We only use the ffmpeg executable when generating thumbnails and still frame images from the saved mp4.&lt;br /&gt;
&lt;br /&gt;
For encoding, we use the LIBRARIES so, you would need to alter the LD_LIBRARY_PATH.&lt;br /&gt;
&lt;br /&gt;
encoding works fine on my old nvidia hardware using standard ubuntu packages. Or at least it did the last time I checked.&lt;br /&gt;
&lt;br /&gt;
hwaccel should be of great benefit in ENCODING. It is not useful for decoding at this time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Obtaining FFMPEG ==&lt;br /&gt;
You should first check your distribution&amp;#039;s package manager. Aside from that you have the option of compiling from source, or downloading a binary, which are linked from the main ffmpeg website. &lt;br /&gt;
&lt;br /&gt;
==Using FFMPEG==&lt;br /&gt;
===Testing a Stream Path with FFMPEG===&lt;br /&gt;
e.g.&lt;br /&gt;
 $ ffmpeg -i rtsp://admin:password@192.168.1.64:554/video/1 output.mp4&lt;br /&gt;
If ffmpeg is successful it will output the encoding of the stream and the resolution. ffplay can also be used (if you are running a GUI such as X), and is easier in this case. But, if you are testing from a headless machine, use ffmpeg and output to a file.&lt;br /&gt;
 $ ffplay rtsp://admin:password@192.168.1.64:554/video/1&lt;br /&gt;
&lt;br /&gt;
=== A note on the RPI ===&lt;br /&gt;
The RPI has its own build of FFMPEG which includes support for the omx and mmal hardware peripherals. It is recommended to obtain it from the official RPI repos. Note that this provides hardware support for exporting, but not necessarily for recording videos (see above paragraphs). (last checked 2020 or so).&lt;br /&gt;
&lt;br /&gt;
== FFMPEG Video Export Options ==&lt;br /&gt;
Ffmpeg is used in exporting events to downloadable video files. Exporting video is done using the [http://www.zoneminder.com/wiki/index.php?title=Special%3ASearch&amp;amp;search=zmvideo.pl&amp;amp;go=Go zmvideo.pl] script.&lt;br /&gt;
&lt;br /&gt;
You can control the options that get passed to ffmpeg during the export process using 2 config options found in the Images tab of the options dialog.&lt;br /&gt;
=== FFMPEG_INPUT_OPTIONS ===&lt;br /&gt;
usually leave this empty&lt;br /&gt;
=== FFMPEG_OUTPUT_OPTIONS ===&lt;br /&gt;
In 1.36 these generally are not used. But for historical purposes: here are some possible settings:&lt;br /&gt;
&lt;br /&gt;
To obtain a good quality export x264 based mp4 video file - the following example works...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-r 30 -vcodec libx264 -threads 2 -b 2000k -minrate 800k -maxrate 5000k&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want as fast as possible h264(with some sacrifice in quality) you can try&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;-c:v libx264 -preset ultrafast &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Examples==&lt;br /&gt;
&lt;br /&gt;
===Output video to UDP socket===&lt;br /&gt;
 ffmpeg -i myvideo.mp4 -f h264 udp://127.0.0.1:12345&lt;br /&gt;
The -f is required and specifies the output format for the udp stream. &lt;br /&gt;
This could easily be used with say /dev/video0 (webcam) to restream from&lt;br /&gt;
a small SBC (although you would probably have better luck with mjpeg-streamer,&lt;br /&gt;
as this solution might not handle disconnects.).&lt;br /&gt;
&lt;br /&gt;
===Download Only Part of a Video===&lt;br /&gt;
 ffmpeg -t 5 -i input video_output_first_5_seconds.mp4&lt;br /&gt;
===Single Screenshot of a Video===&lt;br /&gt;
 ffmpeg -ss 87.52 -i /mnt/zm1/8/2023-01-26/5643528/5643528-video.mp4 -frames:v 1 /mnt/zm1/8/2023-01-26/5643528/01145-capture.jpg&lt;br /&gt;
(from forum, this is what ZM uses to make thumbnails for the timeline)&lt;br /&gt;
&lt;br /&gt;
===Single Stream Screenshot===&lt;br /&gt;
For live stream images it&amp;#039;s possible to do:&lt;br /&gt;
 zmu -m &amp;lt;monitor #&amp;gt; -i -U &amp;lt;username&amp;gt; -P &amp;lt;password&amp;gt; &lt;br /&gt;
which will output to Monitor##.jpg. This uses the resolution set in Zoneminder. &lt;br /&gt;
To grab the image direct from the camera it would be something like:&lt;br /&gt;
 ffmpeg -i http://user:password@ipaddress/videostream -frames:v 1 -y snapshot.jpg&lt;br /&gt;
&lt;br /&gt;
===Joining Jpegs===&lt;br /&gt;
 ffmpeg -framerate 5 -i %05d-capture.jpg output.mp4&lt;br /&gt;
&lt;br /&gt;
Use ffmpeg to concatenate jpeg images stored by zoneminder to an mp4. Note that %05d-capture.jpg here means, escape (&amp;#039;&amp;#039;&amp;#039;%&amp;#039;&amp;#039;&amp;#039;),&lt;br /&gt;
search for numbers (&amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;), search for &amp;#039;&amp;#039;&amp;#039;5&amp;#039;&amp;#039;&amp;#039; of them, increment numbers &amp;#039;&amp;#039;&amp;#039;d&amp;#039;&amp;#039;&amp;#039;, then the rest is a string common to all jpg files. Edit framerate as needed. This is the format used by Zoneminder to store jpegs.&lt;br /&gt;
&lt;br /&gt;
(Reference: [https://askubuntu.com/questions/610903/how-can-i-create-a-video-file-from-a-set-of-jpg-images])&lt;br /&gt;
&lt;br /&gt;
While the above would be used for Zoneminder, a non-ZM solution might use the glob feature of Ffmpeg. (note that you must pass the -pattern_type glob, you can&amp;#039;t simple use an asterisk on its own)&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -r 1 -pattern_type glob -i &amp;#039;test_*.jpg&amp;#039; -c:v libx264 out.mp4&lt;br /&gt;
&lt;br /&gt;
https://superuser.com/questions/624567/how-to-create-a-video-from-images-using-ffmpeg&lt;br /&gt;
&lt;br /&gt;
===Joining Videos===&lt;br /&gt;
Use ffmpeg to concatenate a number of audio / video files.&lt;br /&gt;
&lt;br /&gt;
first put all desired files into a list&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;for f in ./*.mp4; do echo &amp;quot;file &amp;#039;$f&amp;#039;&amp;quot; &amp;gt;&amp;gt; mylist.txt; done&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
combine files using concat filter&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that special characters and spaces can be troublesome.&lt;br /&gt;
&lt;br /&gt;
(Reference: [https://trac.ffmpeg.org/wiki/Concatenate#samecodec]&lt;br /&gt;
&lt;br /&gt;
===Extract Portion of Video/Audio===&lt;br /&gt;
 ffmpeg -i sample.avi -ss 00:03:05 -t 00:00:45.0 -q:a 0 -map a sample.mp3&lt;br /&gt;
Use the -ss option to specify the starting timestamp, and the -t option to specify the encoding duration, eg from 3 minutes and 5 seconds in for 45 seconds. The timestamps need to be in HH:MM:SS.xxx format or in seconds. If you don&amp;#039;t specify the -t option it will go to the end.&lt;br /&gt;
&lt;br /&gt;
Ref:https://stackoverflow.com/questions/9913032/how-can-i-extract-audio-from-video-with-ffmpeg&lt;br /&gt;
&lt;br /&gt;
Note: This doesn&amp;#039;t always work as you expect it. ffmpeg is always jumping around where the end of the file is, in my experience, so&lt;br /&gt;
don&amp;#039;t be surprised if your extract starts earlier or later than you thought.&lt;br /&gt;
&lt;br /&gt;
===Convert Portion of Video to GIF/MP4===&lt;br /&gt;
 ffmpeg -i video.mp4 -ss 00:03:05 -t 00:00:05.0  output.gif&lt;br /&gt;
 ffmpeg -i video.mp4 -ss 00:03:05 -t 00:00:05.0  output.mp4&lt;br /&gt;
===Playback Video at 2x Speed===&lt;br /&gt;
 ffmpeg -i input.mp4 -vf &amp;quot;setpts=0.5*PTS&amp;quot; output.mp4&lt;br /&gt;
From: https://ottverse.com/how-to-speed-up-slow-down-video-playback-using-ffmpeg/#How_to_Speed_Up_Video_with_FFmpeg&lt;br /&gt;
&lt;br /&gt;
==Lower Resolution of Video==&lt;br /&gt;
 $ ffmpeg -i example.mp4 -vf scale=640:480 output.mp4&lt;br /&gt;
Here, the -vf option stands for video filter, and the scale=640:480 parameter tells FFmpeg to resize the video to 640 pixels wide and 480 pixels high.&lt;br /&gt;
&lt;br /&gt;
We can also use -1 as a placeholder for either width or height, and FFmpeg automatically calculates the other dimension to preserve the video’s aspect ratio.&lt;br /&gt;
 $ ffmpeg -i example.mp4 -vf scale=640:-1 output.mp4&lt;br /&gt;
&lt;br /&gt;
reference: https://www.baeldung.com/linux/video-downsample-lower-resolution&lt;br /&gt;
&lt;br /&gt;
===Get Image from Network Stream and Output to Remote Framebuffer Using dd===&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/bash &lt;br /&gt;
ffmpeg -i http://user:password@ipaddress/videostream -frames:v 1 -y snapshot.jpg&lt;br /&gt;
ffmpeg -i snapshot.jpg -s 320x240 -f rawvideo -pix_fmt rgb565 -vcodec rawvideo -r 1 -y  output.raw&lt;br /&gt;
#scp doesn&amp;#039;t work&lt;br /&gt;
#scp output.raw root@ipaddress:/dev/fb0&lt;br /&gt;
#trick: # dd if=/dev/mtd0 | ssh me@myhost &amp;quot;dd of=mtd0.img&amp;quot;&lt;br /&gt;
#https://unix.stackexchange.com/questions/189722/can-you-scp-a-device-file&lt;br /&gt;
dd if=./output.raw | ssh root@ipaddress &amp;quot;dd of=/dev/fb0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is an example of taking an image from a network ip camera and outputting to the framebuffer of a monitor/lcd. The above is not optimized, and is meant as a demonstration (it is slow). It might be used, e.g. for an RPI with an external or tft lcd attached. Note that the pixel format and resolution above are for a 16bits per pixel tft that is 320x240. Your framebuffer will likely be different. You can find your parameters by taking a snapshot from the framebuffer with ffmpeg and looking at the output. While that isn&amp;#039;t working for me as I return to this at this later date, Refer to: /sys/class/drm/card0/card0-HDMI-A-1/ for a BBB and /sys/class/graphics/. It&amp;#039;s not critical if you get the resolution wrong (when testing). An image sized too small will just appear as a sort of tile in the framebuffer, clearly indicating that the size is wrong. From there you can adjust as needed.&lt;br /&gt;
&lt;br /&gt;
===Display Video Feed on LCD Connected to Beaglebone Using FFMPEG and the Framebuffer===&lt;br /&gt;
I have only tested this with a BBB, but it likely works with an RPi as well. In fact, it probably works better on one of the newer Beagleboards, or RPis, as the BBB is limited in its performance (which is good and bad). Nonetheless, it is possible to stream a video easily from the terminal. Note that I run the OS in console mode, so there is no X running. This is just a test as such. In practice, you would either do something more formal (I have read of the DRM mechanism) or add a watchdog to this, to restart the video if it crashes. Or you might just throw ZMNinja at it and not try with the framebuffer. Still, I found this interesting.&lt;br /&gt;
&lt;br /&gt;
 display an image:&lt;br /&gt;
 ffmpeg -i http://user:pass@ipaddress/axis-cgi/jpg/image.cgi?resolution=1280x720 -pix_fmt rgb565le -f fbdev /dev/fb0&lt;br /&gt;
 display a video:&lt;br /&gt;
 ffmpeg -i &amp;quot;rtsp://user:pass@ipaddress/axis-media/media.amp?videocodec=h264&amp;amp;resolution=1280x720&amp;quot; -pix_fmt rgb565le -f fbdev /dev/fb0&lt;br /&gt;
 # camera is limited to 10FPS. LCD resolution is 1280x720.&lt;br /&gt;
 reference:https://unix.stackexchange.com/questions/342815/how-to-send-ffmpeg-output-to-framebuffer&lt;br /&gt;
&lt;br /&gt;
===RTSP Streaming with FFmpeg===&lt;br /&gt;
I haven&amp;#039;t tested the below command, but I believe it was taken from the forum and should work with hopefully only minor adjustments necessary if any. When in doubt, also see the ffmpeg wiki link here: https://trac.ffmpeg.org/wiki/StreamingGuide and ctrl-f for rtsp.&lt;br /&gt;
&lt;br /&gt;
 LIBVA_DRIVER_NAME=i965 ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_device foo -i https://stream-eu1-delta.dropcam.com/ne ... ZZZZZZZZZZ -f rtsp -rtsp_transport udp rtsp://192.168.109.29:5545/doorbell&lt;br /&gt;
&lt;br /&gt;
===Overlay second video on a video stream===&lt;br /&gt;
&amp;lt;pre&amp;gt; ffmpeg -i &amp;quot;rtsp://user:pass@ipaddress:554/videostream&amp;quot;  &lt;br /&gt;
 -i myvideo.mp4 -filter_complex overlay -f h264 udp://127.0.0.1:12345&lt;br /&gt;
&lt;br /&gt;
 ffplay udp://localhost:12345&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -i &amp;quot;rtsp://user:pass@ipaddress:554/videostream&amp;quot; -f image2&lt;br /&gt;
 -stream_loop -1 -i overlay.png -filter_complex overlay -f h264 udp://127.0.0.1:12345&amp;lt;/pre&amp;gt;&lt;br /&gt;
Here&amp;#039;s an example of overlaying a 2nd video on a live stream from an ip camera, and the&lt;br /&gt;
ffplay is viewing the stream. Here the myvideo.mp4 is smaller in resolution than the ip camera stream. You can&lt;br /&gt;
also of course overlay images, including transparent images that update. The 3rd example is the proper syntax for this.&lt;br /&gt;
&lt;br /&gt;
===Compile Four Individual Videos into a Quad Display Montage===&lt;br /&gt;
 ffmpeg -y &lt;br /&gt;
 -i http://cam01/image.jpg &lt;br /&gt;
 -i http://cam02/image.jpg &lt;br /&gt;
 -i http://cam03/image.jpg  &lt;br /&gt;
 -i http://cam04/image.jpg &lt;br /&gt;
 -filter_complex &lt;br /&gt;
 &amp;quot;[0][1] hstack [4] ; [2][3] hstack [5] ; [4][5] vstack&amp;quot; -s 640x480 out.jpg&lt;br /&gt;
&lt;br /&gt;
Per https://forums.zoneminder.com/viewtopic.php?t=33880&lt;br /&gt;
I was not able to get that to work, but I did find the following worked from the Ffmpeg wiki (though it did time out, because the -t flag is set for thirty seconds, so remove the -t flag in order to get it to stream indefinitely (hopefully)) I did notice that the cameras were not synced up but that may be a network problem particular to my setup.&lt;br /&gt;
&lt;br /&gt;
 ffmpeg \&lt;br /&gt;
   -i videos/01.mkv \&lt;br /&gt;
   -i videos/02.mkv \&lt;br /&gt;
   -i videos/03.mkv \&lt;br /&gt;
   -i videos/04.mkv \&lt;br /&gt;
   -i videos/05.mkv \&lt;br /&gt;
   -i videos/06.mkv \&lt;br /&gt;
   -i videos/07.mkv \&lt;br /&gt;
   -i videos/08.mkv \&lt;br /&gt;
   -i videos/09.mkv \&lt;br /&gt;
  -filter_complex &amp;quot; \&lt;br /&gt;
      [0:v] setpts=PTS-STARTPTS, scale=qvga [a0]; \&lt;br /&gt;
      [1:v] setpts=PTS-STARTPTS, scale=qvga [a1]; \&lt;br /&gt;
      [2:v] setpts=PTS-STARTPTS, scale=qvga [a2]; \&lt;br /&gt;
      [3:v] setpts=PTS-STARTPTS, scale=qvga [a3]; \&lt;br /&gt;
      [4:v] setpts=PTS-STARTPTS, scale=qvga [a4]; \&lt;br /&gt;
      [5:v] setpts=PTS-STARTPTS, scale=qvga [a5]; \&lt;br /&gt;
      [6:v] setpts=PTS-STARTPTS, scale=qvga [a6]; \&lt;br /&gt;
      [7:v] setpts=PTS-STARTPTS, scale=qvga [a7]; \&lt;br /&gt;
      [8:v] setpts=PTS-STARTPTS, scale=qvga [a8]; \&lt;br /&gt;
      [a0][a1][a2][a3][a4][a5][a6][a7][a8]xstack=inputs=9:layout=0_0|w0_0|w0+w1_0|0_h0|w0_h0|w0+w1_h0|0_h0+h1|w0_h0+h1|w0+w1_h0+h1[out] \&lt;br /&gt;
      &amp;quot; \&lt;br /&gt;
    -map &amp;quot;[out]&amp;quot; \&lt;br /&gt;
    -c:v libx264 -t &amp;#039;30&amp;#039; -f matroska -  | ffplay -autoexit  -left 30 -top 30  - &lt;br /&gt;
&lt;br /&gt;
See also: https://trac.ffmpeg.org/wiki/Create%20a%20mosaic%20out%20of%20several%20input%20videos%20using%20xstack&lt;br /&gt;
&lt;br /&gt;
===Debugging Media streams===&lt;br /&gt;
 ffmpeg -loglevel [info,debug,etc] -i input output.mp4 &lt;br /&gt;
 ffmpeg -debug mmco -i rtsp://user:password@ipaddress:554/streampath output.mp4&lt;br /&gt;
&lt;br /&gt;
The first is the standard method to debug. The second is for certain parts of ffmpeg. These may be useful, if you are trying to determine why a camera is failing to connect properly to ffmpeg. (reference book: FFMPEG Basics). Note that the -debug flag has a number of parameters other than mmco (which is only valid for h264) that can be passed. A few other possible values are &lt;br /&gt;
buffers, pict, bitstream, rc.&lt;br /&gt;
&lt;br /&gt;
===Demo Camera to Test ZM===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;quot;Is there a way to do a dummy test to see if there&amp;#039;s a problem with my software installation? It seems to me that it&amp;#039;s quite complex, like instead of a camera, use a file as video output of a camera to test the software installation.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Yeah, with ffmpeg. I do it for a generated monitor that displays weather/alert data. Also to visualize audio from my lorex doorbell (been meaning to write a thread about that, alarms from audio are just crazy specific and has lots of use cases (just think, with zoneminder, how specific you can be when choosing your zones on a audio wave &amp;#039;showcqt&amp;#039; where your zones are frequencies and you control the amplitude and color variation)).&lt;br /&gt;
&lt;br /&gt;
Here is a simple rtp example to generate a monitor:&lt;br /&gt;
&lt;br /&gt;
 ffmpeg -re -f lavfi -i testsrc=s=1280x720:r=20 -f rtp_mpegts -pix_fmt yuv420p  rtp://127.0.0.1:4004/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
reference: https://forums.zoneminder.com/viewtopic.php?p=130232&lt;br /&gt;
&lt;br /&gt;
http://trac.ffmpeg.org/wiki/FancyFilteringExamples&lt;br /&gt;
&lt;br /&gt;
 or use something like the following for an mp4 video:&lt;br /&gt;
 ffmpeg -re -i movie.mp4 -f rtp_mpegts -pix_fmt yuv420p  rtp://127.0.0.1:4004/&lt;br /&gt;
 test with zm or alternatively:&lt;br /&gt;
 ffplay rtp://127.0.0.1:4004&lt;br /&gt;
&lt;br /&gt;
==Framebuffer Notes==&lt;br /&gt;
&amp;lt;small&amp;gt;&lt;br /&gt;
Displaying to framebuffer / linux&lt;br /&gt;
see also: using a spi connected lcd&lt;br /&gt;
example:&lt;br /&gt;
https://elinux.org/MiniDisplay_Cape&lt;br /&gt;
https://github.com/jeidon/cfa_bmp_loader/blob/master/sample-code/main.c&lt;br /&gt;
essentially: init code for hardware, then write via spi.&lt;br /&gt;
you can have multiple spi screens, possibly (if you have multiple spi bus&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
see general notes on framebuffer writing here:&lt;br /&gt;
https://elinux.org/RPi_Framebuffer&lt;br /&gt;
&lt;br /&gt;
this is interesting. you can get a usb to lcd (16 character)&lt;br /&gt;
and just write to it as a serial port.&lt;br /&gt;
http://web.archive.org/web/20211207191549/https://hamvoip.org/hamradio/USBLCD/&lt;br /&gt;
&lt;br /&gt;
there may be higher resolution screens, but...&lt;br /&gt;
more research needed. this one looks limited. although&lt;br /&gt;
easier to use.&lt;br /&gt;
https://www.cnx-software.com/2022/04/29/turing-smart-screen-a-low-cost-3-5-inch-usb-type-c-information-display/&lt;br /&gt;
maybe also consider an uno to a tft shield.&lt;br /&gt;
&lt;br /&gt;
more general notes on writing to fb&lt;br /&gt;
https://web.archive.org/web/20210512060006/https://avikdas.com/2019/01/23/writing-gui-applications-on-raspberry-pi-without-x.html&lt;br /&gt;
&lt;br /&gt;
you can also ofc, read from the framebuffer, not just write.&lt;br /&gt;
 sudo ffmpeg -f fbdev -framerate 1 -i /dev/fb0 -frames:v 1 screenAA3.jpeg&lt;br /&gt;
https://stackoverflow.com/questions/71549386/ffmpeg-output-to-framebuffer-fbdev-raspberry-pi-4&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tips/Techniques==&lt;br /&gt;
===Unnecessary Encoding of Joining Videos with FFmpeg===&lt;br /&gt;
You may think you need a GPU to speed up encoding of videos, if you were to combine them. This is not necessarily true. If you keep the codecs the same, then FFmpeg (or Mencoder) is able to do a type of semi-encode (or transcode) where it will reorganize the MP4 files to join them together, without doing a full re-encode.&lt;br /&gt;
&lt;br /&gt;
For more details, see:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?p=137923&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?p=137922&lt;br /&gt;
===Moving the Mov Atom (video metadata) to the Beginning of the Video Will Fix Some Issues With Mono Audio===&lt;br /&gt;
Please read the forum thread. This is a bug unique to a 1.36 release, but it is generally useful for MP4 encoding, so I thought I would include it here. Reference: https://forums.zoneminder.com/viewtopic.php?t=34111&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I figured out why nginx_mod_module doesn&amp;#039;t want to play mono audio. It&amp;#039;s because the metadata is at the end of the file. If you move it to the beginning of the file:&lt;br /&gt;
&lt;br /&gt;
Code: Select all&lt;br /&gt;
&lt;br /&gt;
ffmpeg -i 748604-video.mp4 -movflags faststart -c copy output.mp4&lt;br /&gt;
&lt;br /&gt;
This moves the moov-atom metadata to the beginning of the file. And then it plays perfectly: &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Yes, add movflags=frag_keyframe+empty_moov+faststart to options. The value here is what is used in 1.37. Although I think empty_moov might be deprecated in newer ffmpeg.&lt;br /&gt;
The default in 1.36 is frag_keyframe+empty_moov.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[GPU_passthrough_in_VMWare]] - Some info on using a GPU w/ZM&lt;br /&gt;
&lt;br /&gt;
* FFMPEG Basics by Frantisek Korbel. This book is based around command line usage, and does not necessarily go into detail on the source code.&lt;br /&gt;
&lt;br /&gt;
* https://johnvansickle.com/ffmpeg/ For ready-made binaries&lt;br /&gt;
&lt;br /&gt;
* http://web.archive.org/web/20221123101906/https://img.ly/blog/ultimate-guide-to-ffmpeg/ - tutorial on ffmpeg&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;br /&gt;
&lt;br /&gt;
* https://directfb2.github.io&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] - Some examples of ffmpeg reading from a pipe, outputting to a JPEG file, and also ffserver.&lt;br /&gt;
&lt;br /&gt;
* https://gist.github.com/cbarraco/f6cb40e3f5eb1f2733b5 - Ffmpeg screen sharing (ad-hoc vnc)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_the_latest_frame_of_a_camera&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Axis&amp;diff=17932</id>
		<title>Axis</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Axis&amp;diff=17932"/>
		<updated>2026-03-04T19:58:59Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* AXIS M3113-R */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Axis cameras.jpg]]&lt;br /&gt;
&lt;br /&gt;
ZoneMinder will work well with almost any [http://www.axis.com Axis camera], including the 205, 206, 207, 209, 210, 211 and M10 ranges. It will also work with the 213 and 2130 cameras and support their [[PTZ]] functions through the web interface. For cameras that don&amp;#039;t work see [[Axis#Issues]].&lt;br /&gt;
&lt;br /&gt;
How to Offload the Motion to cameras [[AxisMotionDetection]]&lt;br /&gt;
&lt;br /&gt;
Axis publishes their full, open API named VAPIX; documentation may be found at [http://www.axis.com/techsup/cam_servers/dev/index.htm Axis Developer Pages].  Note in particular the HTTP API which defines the remote host path arguments which may be used by Zoneminder.&lt;br /&gt;
&lt;br /&gt;
== Cameras == &lt;br /&gt;
&lt;br /&gt;
=== AXIS 2110 ===&lt;br /&gt;
&lt;br /&gt;
/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS 207W ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS P33XX-V/VE ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/mjpg/video.mjpg&lt;br /&gt;
&lt;br /&gt;
=== AXIS P1311 / P1344 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/mjpg/video.mjpg&lt;br /&gt;
&lt;br /&gt;
=== AXIS P1357-E ===&lt;br /&gt;
This is set up to have the camera send an event to zoneminder. &lt;br /&gt;
* General&lt;br /&gt;
** Source type: Ffmpeg&lt;br /&gt;
** Function: Nodect&lt;br /&gt;
** Maximum FPS: &amp;lt;blank&amp;gt;&lt;br /&gt;
* Source&lt;br /&gt;
** rtsp://&amp;lt;CAM IP/HOSTNAME&amp;gt;/axis-media/media.amp?videocodec=h264&amp;amp;resolution=2592x1944&amp;amp;streamprofile=Quality&amp;amp;tcp&amp;amp;compression=0&lt;br /&gt;
** Capture Width: 2592&lt;br /&gt;
** Capture Height: 1944&lt;br /&gt;
&lt;br /&gt;
modify /etc/init.d/zoneminder:&lt;br /&gt;
add to start section:&lt;br /&gt;
* /usr/bin/zmtrigger.pl&amp;amp;&lt;br /&gt;
to stop section:&lt;br /&gt;
* pkill zmtrigger.pl&lt;br /&gt;
* Options&lt;br /&gt;
** Images&lt;br /&gt;
*** OPT_FFMPEG: checked&lt;br /&gt;
*** PATH_FFMPEG: /usr/bin/avconv&lt;br /&gt;
&lt;br /&gt;
For the camera:&lt;br /&gt;
* Detectors&lt;br /&gt;
** Motion Detection&amp;lt;br /&amp;gt;Add a window for detection. Adjust Object Size, History, Sensitivity. Check Activity to determine whether the settings are correct.&lt;br /&gt;
* Events&lt;br /&gt;
** Recipients&amp;lt;br /&amp;gt;Add a recipient. Choose Name, Type is TCP. Address is zoneminder name or IP address.&lt;br /&gt;
** Action Rules&amp;lt;br /&amp;gt;Enable rule. &lt;br /&gt;
*** Trigger&lt;br /&gt;
**** Detectors&lt;br /&gt;
**** Motion Detection&lt;br /&gt;
**** Name of detector set above&lt;br /&gt;
**** Motion: Yes&lt;br /&gt;
**** Schedule: Always&lt;br /&gt;
*** Actions:&lt;br /&gt;
**** Type: Send Notification&lt;br /&gt;
**** Recipient: Name as set above&lt;br /&gt;
**** Message: 1|on+5|5|cause|text|showtext&lt;br /&gt;
**** Check box for send notifications continuously&lt;br /&gt;
**** Send notification every 1 second&lt;br /&gt;
&lt;br /&gt;
=== AXIS 213PTZ ===&lt;br /&gt;
The axis 213PTZ works perfectly. Use the folowing settings:&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: RTSP&lt;br /&gt;
 Remote Method: RTP/RTSP&lt;br /&gt;
 Remote Host Name: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: 554&lt;br /&gt;
 Remote Host Path: /mpeg4/media.amp&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CONTROL&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Controllable: Yes&lt;br /&gt;
 Control Type: Axis API v2&lt;br /&gt;
 Control Address: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resolution must match the one especified in the camera settings. Resolutions up to CIF will work without any problems but 2CIF and 4CIF will need the shared memory tweak (lean more at the [[FAQ]])&lt;br /&gt;
&lt;br /&gt;
The [[AxisMotionDetection]] trick works quite well with this camera.&lt;br /&gt;
&lt;br /&gt;
The Max FPS option of zoneminder introduces very big latency, so I use the option of the camera for limiting the FPS.&lt;br /&gt;
&lt;br /&gt;
This was tested with zoneminder 1.24.2 running on Gentoo stable&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1011-W ===&lt;br /&gt;
&lt;br /&gt;
[http://www.axis.com/products/cam_m1011w/ M1011-W]&lt;br /&gt;
&lt;br /&gt;
I get a lower load by using the MJPEG stream compared to the JPEG still images. [[User:Mathieumd|Mathieumd]] 15:52, 17 May 2012 (BST)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Tab/Label&lt;br /&gt;
! MJPEG Stream&lt;br /&gt;
! JPEG Stills&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | &amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Source Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Remote&lt;br /&gt;
|- &lt;br /&gt;
| Maximum FPS&lt;br /&gt;
|&lt;br /&gt;
| 5&lt;br /&gt;
|- &lt;br /&gt;
| Alarm Maximum FPS&lt;br /&gt;
|&lt;br /&gt;
| 15&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | &amp;#039;&amp;#039;&amp;#039;Source&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Remote Protocol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | HTTP&lt;br /&gt;
|- &lt;br /&gt;
| Remote Method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Simple&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Name&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | [&amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@]&amp;#039;&amp;#039;&amp;#039;&amp;lt;CAM IP/HOSTNAME&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Port&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | &amp;lt;CAM PORT&amp;gt; (usually 80 or 443)&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Path&lt;br /&gt;
| /axis-cgi/&amp;#039;&amp;#039;&amp;#039;mjpg/video&amp;#039;&amp;#039;&amp;#039;.cgi?resolution=640x480&amp;amp;fps=15&lt;br /&gt;
| /axis-cgi/&amp;#039;&amp;#039;&amp;#039;jpg/image&amp;#039;&amp;#039;&amp;#039;.cgi?resolution=640x480&lt;br /&gt;
|- &lt;br /&gt;
| Capture Width (pixels)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | 640&lt;br /&gt;
|- &lt;br /&gt;
| Capture Height (pixels)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | 480&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1031-W ===&lt;br /&gt;
&lt;br /&gt;
[http://www.axis.com/products/cam_m1031w/ M1031-W]&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: HTTP&lt;br /&gt;
 Remote Method: Simple&lt;br /&gt;
 Remote Host Name: &amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: &amp;lt;CAM PORT&amp;gt;&lt;br /&gt;
 Remote Host Path: /axis-cgi/mjpg/video.cgi?resolution=640x480&lt;br /&gt;
&lt;br /&gt;
OR for mpeg-4&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: RTSP&lt;br /&gt;
 Remote Method: RTP/RTSP/HTTP&lt;br /&gt;
 Remote Host Name: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: &amp;lt;CAM PORT&amp;gt;&lt;br /&gt;
 Remote Host Path: /mpeg4/media.amp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Cameras]]&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1054 ===&lt;br /&gt;
&lt;br /&gt;
Working just fine with my zoneminder setup under Ubuntu 10.04 and 11.04, using MJPEG setup.&lt;br /&gt;
&lt;br /&gt;
My camera setup:&lt;br /&gt;
* Source type: remote&lt;br /&gt;
* Function: modect&lt;br /&gt;
* maximum fps 8.00&lt;br /&gt;
* alarm fps 30.00&lt;br /&gt;
* remote protocol: http&lt;br /&gt;
* remote method: simple&lt;br /&gt;
* remote host name: the DNS name of the camera (or IP adress I suppose)&lt;br /&gt;
* remote host port: 80&lt;br /&gt;
* remote host path: /axis-cgi/mjpg/video.cgi&lt;br /&gt;
* capture width: 1280&lt;br /&gt;
* capture height: 800&lt;br /&gt;
&lt;br /&gt;
I just captured some thiefs with this setup, police caught them and used the pictures as proof. High quality pictures for that price of a camera and very reliable (running 1/2 year now without a single crash or disfunction).&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1114 ===&lt;br /&gt;
works with following entrys&lt;br /&gt;
* Source type: remote&lt;br /&gt;
* Function: [what_you_want]&lt;br /&gt;
* maximum fps 0 # don&amp;#039;t put any value here&lt;br /&gt;
* alarm fps 0 # don&amp;#039;t put any value here&lt;br /&gt;
* remote protocol: http&lt;br /&gt;
* remote method: simple&lt;br /&gt;
* remote host name: user:password@IP-Address or user:password@DNS_Name&lt;br /&gt;
* remote host port: 80&lt;br /&gt;
* remote host path: /mjpg/video.mjpg?resolution=480x360&lt;br /&gt;
* capture width: 480  #depends on your &amp;quot;remote host path&amp;quot; setting, must to be the same!&lt;br /&gt;
* capture height: 360  #depends on your &amp;quot;remote host path&amp;quot; setting, must to be the same!&lt;br /&gt;
&lt;br /&gt;
Using remote host path and arguments from the Axis VAPIX HTTP API.  Includes limiting the frame rate (fps=x)&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /axis-cgi/mjpg/video.cgi?fps=15&amp;amp;resolution=1024x640&lt;br /&gt;
* Remote Image Colours: 24 bit color&lt;br /&gt;
* Capture Width (pixels): 1024&lt;br /&gt;
* Capture Height (pixels): 640&lt;br /&gt;
&lt;br /&gt;
=== AXIS Q6032-E ===&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /mjpg/video.mjpg&lt;br /&gt;
* Remote Image Colours: &amp;lt;24 bit color|32 bit color&amp;gt;&lt;br /&gt;
* Capture Width (pixels): 704&lt;br /&gt;
* Capture Height (pixels): 480&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3007 ===&lt;br /&gt;
[http://www.axis.com/products/cam_m3007pv/ M3007]&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: &lt;br /&gt;
    Overview - /mjpg/video.mjpg or /mjpg/1/video.mjpg&lt;br /&gt;
    Panorama - /mjpg/video.mjpg?camera=2 or /mjpg/2/video.mjpg&lt;br /&gt;
    Double Panorama - /mjpg/video.mjpg?camera=3 or /mjpg/3/video.mjpg&lt;br /&gt;
    Quad - /mjpg/video.mjpg?camera=4 or /mjpg/4/video.mjpg&lt;br /&gt;
    Feed 1 - /mjpg/video.mjpg?camera=5 or /mjpg/5/video.mjpg&lt;br /&gt;
    Feed 2 - /mjpg/video.mjpg?camera=6 or /mjpg/6/video.mjpg&lt;br /&gt;
    Feed 3 - /mjpg/video.mjpg?camera=7 or /mjpg/7/video.mjpg&lt;br /&gt;
    Feed 4 - /mjpg/video.mjpg?camera=8 or /mjpg/8/video.mjpg&lt;br /&gt;
&lt;br /&gt;
To make the PTZ work on feeds 1-4&lt;br /&gt;
&lt;br /&gt;
* Control Type: Axis API V2&lt;br /&gt;
* Control Device: &amp;amp;camera=5 (6,7 or 8 depending on Feed 1,2,3 or 4)&lt;br /&gt;
* Control Address: user:pass@ipaddress:80&lt;br /&gt;
* Edit AxisV2.pm and change the following in the sendCmd subroutine. Rebooting seems to be the only way to make ZM reload the modified module.&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CODE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 my $req = HTTP::Request-&amp;gt;new( GET=&amp;gt;&amp;quot;http://&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlAddress}.&amp;quot;$cmd&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
to this&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CODE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 my $req = HTTP::Request-&amp;gt;new( GET=&amp;gt;&amp;quot;http://&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlAddress}.&amp;quot;$cmd&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlDevice} );&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3044-V ===&lt;br /&gt;
* General&lt;br /&gt;
** Source type: Remote&lt;br /&gt;
** Function: Modect&lt;br /&gt;
** Maximum FPS: 40 (camera set to 30)&lt;br /&gt;
* Source&lt;br /&gt;
** Remote Protocol: RTSP&lt;br /&gt;
** Remote Method: RTP/RTSP&lt;br /&gt;
** Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;/axis-media/media.amp&lt;br /&gt;
** Remote Host Port: 554&lt;br /&gt;
** Capture Width: 1280 (same as camera)&lt;br /&gt;
** Capture Height: 720&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS Companion Bullet LE ===&lt;br /&gt;
* General&lt;br /&gt;
** Source type: ffmpeg&lt;br /&gt;
* Source&lt;br /&gt;
** Remote Method: TCP&lt;br /&gt;
** Source Path: rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;/axis-media/media.amp/?overview=0&amp;amp;Axis-Orig-Sw=true&lt;br /&gt;
** Capture Width: 1920&lt;br /&gt;
** Capture Height: 1080&lt;br /&gt;
&lt;br /&gt;
Axis companion cameras require Windows to setup. see [[Axis#Issues]]. The password will be the one you configured for the site via axis companion software.&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3113-R ===&lt;br /&gt;
Resolution is low (max 800x600) however, these cameras are outdoor rated, and latency is very low. No delay in video stream to ZM. The outdoor enclosure is not ideal, as the cable runs out the back, so they are best suited for somewhere there is existing water egress protection, or where you can drill behind where they will be mounted. 7/10 for outdoor protection, 6/10 for resolution, 10/10 for latency. Good picture. I saw network performance suffer after installing this camera, but upgrading from 10/100 to gigabit seemed to fix most problems.&lt;br /&gt;
&lt;br /&gt;
* General&lt;br /&gt;
** Source type: ffmpeg&lt;br /&gt;
* Source&lt;br /&gt;
** Source Path: rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:&amp;lt;port&amp;gt;/axis-media/media.amp?videocodec=h264&lt;br /&gt;
** Capture Width: 800&lt;br /&gt;
** Capture Height: 600&lt;br /&gt;
&lt;br /&gt;
** JPG path: http://&amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@ipaddress/jpg/image.jpg&lt;br /&gt;
&lt;br /&gt;
== Other Hardware ==&lt;br /&gt;
&lt;br /&gt;
=== AXIS M7014 ===&lt;br /&gt;
&lt;br /&gt;
-4 channel video encoder with receives signal from a Closed-Circuit-style camera via a BNC connector for each channel.&lt;br /&gt;
&lt;br /&gt;
Works very well with zoneminder using the following settings:&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /axis-cgi/jpg/image.cgi?camera=X  where X is 1,2,3 or 4 - for each channel&lt;br /&gt;
* Remote Image Colours: &amp;lt;24 bit color|32 bit color&amp;gt;&lt;br /&gt;
* Capture Width (pixels): 704&lt;br /&gt;
* Capture Height (pixels): 480&lt;br /&gt;
&lt;br /&gt;
Note: An axis tech suggested using:&lt;br /&gt;
rtsp://&amp;lt;ip&amp;gt;/axis-media/media.amp?camera=X  but I didn&amp;#039;t try it.&lt;br /&gt;
This is a really nice device for ZoneMinder - lets you use legacy cams easily.  Highly recommended.&lt;br /&gt;
&lt;br /&gt;
=== AXIS M7016 ===&lt;br /&gt;
&lt;br /&gt;
16 Channel Encoder.&lt;br /&gt;
&lt;br /&gt;
Same as above, but there is also an option to use &amp;#039;quad&amp;#039; for the cameras, instead of a number, and this quad option will give you a composite stream of all 4 cameras.&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?p=132442#p132442&lt;br /&gt;
&lt;br /&gt;
=== AXIS 240Q ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4 Channel video encoder. Works well. Somewhat awkward to place on a shelf as ethernet is on one side and coaxial is on opposite side. Requires a funny coaxial plug size (as all axis equipment seems to). Might want to buy a set of adaptors such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. Or use POE if possible.&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|200px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
Works with these settings (taken from the user manual for this device which explicitly details paths):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Protocol: HTTP&lt;br /&gt;
Method: Simple&lt;br /&gt;
Hostname: user:pass@&amp;lt;ipaddress&amp;gt;&lt;br /&gt;
Port: 80&lt;br /&gt;
Path: /mjpg/1/video.mjpg?user=&amp;lt;user&amp;gt;&amp;amp;pwd=&amp;lt;pass&amp;gt;&lt;br /&gt;
Width: 704&lt;br /&gt;
Height: 480&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issues==&lt;br /&gt;
&lt;br /&gt;
Early 207&amp;#039;s have hardware issues, see [http://www.zoneminder.com/forums/viewtopic.php?t=5022 this thread] in the forum for details.&lt;br /&gt;
&lt;br /&gt;
The [http://www.axis.com/techsup/cam_servers/cam_2100/index.htm 2100 has been discontinued by Axis] and no longer supported, possibly due to hardware problems. It&amp;#039;s noted in the [http://www.zoneminder.com/forums/viewtopic.php?t=10079 forums that the camera sends the pictures it captures somewhat diced up.]&lt;br /&gt;
&lt;br /&gt;
There were murmurs about Companion cameras not being compatible, (see also axis forums), but these may be supported, albeit with a nonstandard path. [http://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=26868]. Requires Windows to setup camera username/password. The Ios and Android app do not allow configuration. And you must make an axis account.&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Axis&amp;diff=17931</id>
		<title>Axis</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Axis&amp;diff=17931"/>
		<updated>2026-03-04T19:58:34Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* AXIS M3113-R */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Axis cameras.jpg]]&lt;br /&gt;
&lt;br /&gt;
ZoneMinder will work well with almost any [http://www.axis.com Axis camera], including the 205, 206, 207, 209, 210, 211 and M10 ranges. It will also work with the 213 and 2130 cameras and support their [[PTZ]] functions through the web interface. For cameras that don&amp;#039;t work see [[Axis#Issues]].&lt;br /&gt;
&lt;br /&gt;
How to Offload the Motion to cameras [[AxisMotionDetection]]&lt;br /&gt;
&lt;br /&gt;
Axis publishes their full, open API named VAPIX; documentation may be found at [http://www.axis.com/techsup/cam_servers/dev/index.htm Axis Developer Pages].  Note in particular the HTTP API which defines the remote host path arguments which may be used by Zoneminder.&lt;br /&gt;
&lt;br /&gt;
== Cameras == &lt;br /&gt;
&lt;br /&gt;
=== AXIS 2110 ===&lt;br /&gt;
&lt;br /&gt;
/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS 207W ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS P33XX-V/VE ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/axis-cgi/mjpg/video.cgi?camera=&amp;amp;resolution=320×240&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/mjpg/video.mjpg&lt;br /&gt;
&lt;br /&gt;
=== AXIS P1311 / P1344 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;@&amp;lt;IP Address&amp;gt;/mjpg/video.mjpg&lt;br /&gt;
&lt;br /&gt;
=== AXIS P1357-E ===&lt;br /&gt;
This is set up to have the camera send an event to zoneminder. &lt;br /&gt;
* General&lt;br /&gt;
** Source type: Ffmpeg&lt;br /&gt;
** Function: Nodect&lt;br /&gt;
** Maximum FPS: &amp;lt;blank&amp;gt;&lt;br /&gt;
* Source&lt;br /&gt;
** rtsp://&amp;lt;CAM IP/HOSTNAME&amp;gt;/axis-media/media.amp?videocodec=h264&amp;amp;resolution=2592x1944&amp;amp;streamprofile=Quality&amp;amp;tcp&amp;amp;compression=0&lt;br /&gt;
** Capture Width: 2592&lt;br /&gt;
** Capture Height: 1944&lt;br /&gt;
&lt;br /&gt;
modify /etc/init.d/zoneminder:&lt;br /&gt;
add to start section:&lt;br /&gt;
* /usr/bin/zmtrigger.pl&amp;amp;&lt;br /&gt;
to stop section:&lt;br /&gt;
* pkill zmtrigger.pl&lt;br /&gt;
* Options&lt;br /&gt;
** Images&lt;br /&gt;
*** OPT_FFMPEG: checked&lt;br /&gt;
*** PATH_FFMPEG: /usr/bin/avconv&lt;br /&gt;
&lt;br /&gt;
For the camera:&lt;br /&gt;
* Detectors&lt;br /&gt;
** Motion Detection&amp;lt;br /&amp;gt;Add a window for detection. Adjust Object Size, History, Sensitivity. Check Activity to determine whether the settings are correct.&lt;br /&gt;
* Events&lt;br /&gt;
** Recipients&amp;lt;br /&amp;gt;Add a recipient. Choose Name, Type is TCP. Address is zoneminder name or IP address.&lt;br /&gt;
** Action Rules&amp;lt;br /&amp;gt;Enable rule. &lt;br /&gt;
*** Trigger&lt;br /&gt;
**** Detectors&lt;br /&gt;
**** Motion Detection&lt;br /&gt;
**** Name of detector set above&lt;br /&gt;
**** Motion: Yes&lt;br /&gt;
**** Schedule: Always&lt;br /&gt;
*** Actions:&lt;br /&gt;
**** Type: Send Notification&lt;br /&gt;
**** Recipient: Name as set above&lt;br /&gt;
**** Message: 1|on+5|5|cause|text|showtext&lt;br /&gt;
**** Check box for send notifications continuously&lt;br /&gt;
**** Send notification every 1 second&lt;br /&gt;
&lt;br /&gt;
=== AXIS 213PTZ ===&lt;br /&gt;
The axis 213PTZ works perfectly. Use the folowing settings:&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: RTSP&lt;br /&gt;
 Remote Method: RTP/RTSP&lt;br /&gt;
 Remote Host Name: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: 554&lt;br /&gt;
 Remote Host Path: /mpeg4/media.amp&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CONTROL&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Controllable: Yes&lt;br /&gt;
 Control Type: Axis API v2&lt;br /&gt;
 Control Address: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resolution must match the one especified in the camera settings. Resolutions up to CIF will work without any problems but 2CIF and 4CIF will need the shared memory tweak (lean more at the [[FAQ]])&lt;br /&gt;
&lt;br /&gt;
The [[AxisMotionDetection]] trick works quite well with this camera.&lt;br /&gt;
&lt;br /&gt;
The Max FPS option of zoneminder introduces very big latency, so I use the option of the camera for limiting the FPS.&lt;br /&gt;
&lt;br /&gt;
This was tested with zoneminder 1.24.2 running on Gentoo stable&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1011-W ===&lt;br /&gt;
&lt;br /&gt;
[http://www.axis.com/products/cam_m1011w/ M1011-W]&lt;br /&gt;
&lt;br /&gt;
I get a lower load by using the MJPEG stream compared to the JPEG still images. [[User:Mathieumd|Mathieumd]] 15:52, 17 May 2012 (BST)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Tab/Label&lt;br /&gt;
! MJPEG Stream&lt;br /&gt;
! JPEG Stills&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | &amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Source Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Remote&lt;br /&gt;
|- &lt;br /&gt;
| Maximum FPS&lt;br /&gt;
|&lt;br /&gt;
| 5&lt;br /&gt;
|- &lt;br /&gt;
| Alarm Maximum FPS&lt;br /&gt;
|&lt;br /&gt;
| 15&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | &amp;#039;&amp;#039;&amp;#039;Source&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
| Remote Protocol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | HTTP&lt;br /&gt;
|- &lt;br /&gt;
| Remote Method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | Simple&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Name&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | [&amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@]&amp;#039;&amp;#039;&amp;#039;&amp;lt;CAM IP/HOSTNAME&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Port&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | &amp;lt;CAM PORT&amp;gt; (usually 80 or 443)&lt;br /&gt;
|- &lt;br /&gt;
| Remote Host Path&lt;br /&gt;
| /axis-cgi/&amp;#039;&amp;#039;&amp;#039;mjpg/video&amp;#039;&amp;#039;&amp;#039;.cgi?resolution=640x480&amp;amp;fps=15&lt;br /&gt;
| /axis-cgi/&amp;#039;&amp;#039;&amp;#039;jpg/image&amp;#039;&amp;#039;&amp;#039;.cgi?resolution=640x480&lt;br /&gt;
|- &lt;br /&gt;
| Capture Width (pixels)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | 640&lt;br /&gt;
|- &lt;br /&gt;
| Capture Height (pixels)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot; | 480&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1031-W ===&lt;br /&gt;
&lt;br /&gt;
[http://www.axis.com/products/cam_m1031w/ M1031-W]&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: HTTP&lt;br /&gt;
 Remote Method: Simple&lt;br /&gt;
 Remote Host Name: &amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: &amp;lt;CAM PORT&amp;gt;&lt;br /&gt;
 Remote Host Path: /axis-cgi/mjpg/video.cgi?resolution=640x480&lt;br /&gt;
&lt;br /&gt;
OR for mpeg-4&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;SOURCE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 Remote Protocol: RTSP&lt;br /&gt;
 Remote Method: RTP/RTSP/HTTP&lt;br /&gt;
 Remote Host Name: &amp;lt;USER&amp;gt;:&amp;lt;PASS&amp;gt;@&amp;lt;CAM IP/HOSTNAME&amp;gt;&lt;br /&gt;
 Remote Host Port: &amp;lt;CAM PORT&amp;gt;&lt;br /&gt;
 Remote Host Path: /mpeg4/media.amp&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Cameras]]&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1054 ===&lt;br /&gt;
&lt;br /&gt;
Working just fine with my zoneminder setup under Ubuntu 10.04 and 11.04, using MJPEG setup.&lt;br /&gt;
&lt;br /&gt;
My camera setup:&lt;br /&gt;
* Source type: remote&lt;br /&gt;
* Function: modect&lt;br /&gt;
* maximum fps 8.00&lt;br /&gt;
* alarm fps 30.00&lt;br /&gt;
* remote protocol: http&lt;br /&gt;
* remote method: simple&lt;br /&gt;
* remote host name: the DNS name of the camera (or IP adress I suppose)&lt;br /&gt;
* remote host port: 80&lt;br /&gt;
* remote host path: /axis-cgi/mjpg/video.cgi&lt;br /&gt;
* capture width: 1280&lt;br /&gt;
* capture height: 800&lt;br /&gt;
&lt;br /&gt;
I just captured some thiefs with this setup, police caught them and used the pictures as proof. High quality pictures for that price of a camera and very reliable (running 1/2 year now without a single crash or disfunction).&lt;br /&gt;
&lt;br /&gt;
=== AXIS M1114 ===&lt;br /&gt;
works with following entrys&lt;br /&gt;
* Source type: remote&lt;br /&gt;
* Function: [what_you_want]&lt;br /&gt;
* maximum fps 0 # don&amp;#039;t put any value here&lt;br /&gt;
* alarm fps 0 # don&amp;#039;t put any value here&lt;br /&gt;
* remote protocol: http&lt;br /&gt;
* remote method: simple&lt;br /&gt;
* remote host name: user:password@IP-Address or user:password@DNS_Name&lt;br /&gt;
* remote host port: 80&lt;br /&gt;
* remote host path: /mjpg/video.mjpg?resolution=480x360&lt;br /&gt;
* capture width: 480  #depends on your &amp;quot;remote host path&amp;quot; setting, must to be the same!&lt;br /&gt;
* capture height: 360  #depends on your &amp;quot;remote host path&amp;quot; setting, must to be the same!&lt;br /&gt;
&lt;br /&gt;
Using remote host path and arguments from the Axis VAPIX HTTP API.  Includes limiting the frame rate (fps=x)&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /axis-cgi/mjpg/video.cgi?fps=15&amp;amp;resolution=1024x640&lt;br /&gt;
* Remote Image Colours: 24 bit color&lt;br /&gt;
* Capture Width (pixels): 1024&lt;br /&gt;
* Capture Height (pixels): 640&lt;br /&gt;
&lt;br /&gt;
=== AXIS Q6032-E ===&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /mjpg/video.mjpg&lt;br /&gt;
* Remote Image Colours: &amp;lt;24 bit color|32 bit color&amp;gt;&lt;br /&gt;
* Capture Width (pixels): 704&lt;br /&gt;
* Capture Height (pixels): 480&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3007 ===&lt;br /&gt;
[http://www.axis.com/products/cam_m3007pv/ M3007]&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: &lt;br /&gt;
    Overview - /mjpg/video.mjpg or /mjpg/1/video.mjpg&lt;br /&gt;
    Panorama - /mjpg/video.mjpg?camera=2 or /mjpg/2/video.mjpg&lt;br /&gt;
    Double Panorama - /mjpg/video.mjpg?camera=3 or /mjpg/3/video.mjpg&lt;br /&gt;
    Quad - /mjpg/video.mjpg?camera=4 or /mjpg/4/video.mjpg&lt;br /&gt;
    Feed 1 - /mjpg/video.mjpg?camera=5 or /mjpg/5/video.mjpg&lt;br /&gt;
    Feed 2 - /mjpg/video.mjpg?camera=6 or /mjpg/6/video.mjpg&lt;br /&gt;
    Feed 3 - /mjpg/video.mjpg?camera=7 or /mjpg/7/video.mjpg&lt;br /&gt;
    Feed 4 - /mjpg/video.mjpg?camera=8 or /mjpg/8/video.mjpg&lt;br /&gt;
&lt;br /&gt;
To make the PTZ work on feeds 1-4&lt;br /&gt;
&lt;br /&gt;
* Control Type: Axis API V2&lt;br /&gt;
* Control Device: &amp;amp;camera=5 (6,7 or 8 depending on Feed 1,2,3 or 4)&lt;br /&gt;
* Control Address: user:pass@ipaddress:80&lt;br /&gt;
* Edit AxisV2.pm and change the following in the sendCmd subroutine. Rebooting seems to be the only way to make ZM reload the modified module.&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CODE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 my $req = HTTP::Request-&amp;gt;new( GET=&amp;gt;&amp;quot;http://&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlAddress}.&amp;quot;$cmd&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
to this&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;CODE&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 my $req = HTTP::Request-&amp;gt;new( GET=&amp;gt;&amp;quot;http://&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlAddress}.&amp;quot;$cmd&amp;quot;.$self-&amp;gt;{Monitor}-&amp;gt;{ControlDevice} );&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3044-V ===&lt;br /&gt;
* General&lt;br /&gt;
** Source type: Remote&lt;br /&gt;
** Function: Modect&lt;br /&gt;
** Maximum FPS: 40 (camera set to 30)&lt;br /&gt;
* Source&lt;br /&gt;
** Remote Protocol: RTSP&lt;br /&gt;
** Remote Method: RTP/RTSP&lt;br /&gt;
** Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;/axis-media/media.amp&lt;br /&gt;
** Remote Host Port: 554&lt;br /&gt;
** Capture Width: 1280 (same as camera)&lt;br /&gt;
** Capture Height: 720&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AXIS Companion Bullet LE ===&lt;br /&gt;
* General&lt;br /&gt;
** Source type: ffmpeg&lt;br /&gt;
* Source&lt;br /&gt;
** Remote Method: TCP&lt;br /&gt;
** Source Path: rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;/axis-media/media.amp/?overview=0&amp;amp;Axis-Orig-Sw=true&lt;br /&gt;
** Capture Width: 1920&lt;br /&gt;
** Capture Height: 1080&lt;br /&gt;
&lt;br /&gt;
Axis companion cameras require Windows to setup. see [[Axis#Issues]]. The password will be the one you configured for the site via axis companion software.&lt;br /&gt;
&lt;br /&gt;
=== AXIS M3113-R ===&lt;br /&gt;
Resolution is low (max 800x600) however, these cameras are outdoor rated, and latency is very low. No delay in video stream to ZM. The outdoor enclosure is not ideal, as the cable runs out the back, so they are best suited for somewhere there is existing water egress protection, or where you can drill behind where they will be mounted. 7/10 for outdoor protection, 6/10 for resolution, 10/10 for latency. Good picture. I saw network performance suffer after installing this camera, but upgrading from 10/100 to gigabit seemed to fix most problems.&lt;br /&gt;
&lt;br /&gt;
* General&lt;br /&gt;
** Source type: ffmpeg&lt;br /&gt;
* Source&lt;br /&gt;
** Source Path: rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:&amp;lt;port&amp;gt;/axis-media/media.amp?videocodec=h264&lt;br /&gt;
** Capture Width: 800&lt;br /&gt;
** Capture Height: 600&lt;br /&gt;
&lt;br /&gt;
** JPG path: http://user:password@ipaddress/jpg/image.jpg&lt;br /&gt;
&lt;br /&gt;
== Other Hardware ==&lt;br /&gt;
&lt;br /&gt;
=== AXIS M7014 ===&lt;br /&gt;
&lt;br /&gt;
-4 channel video encoder with receives signal from a Closed-Circuit-style camera via a BNC connector for each channel.&lt;br /&gt;
&lt;br /&gt;
Works very well with zoneminder using the following settings:&lt;br /&gt;
&lt;br /&gt;
* Remote Protocol: HTTP&lt;br /&gt;
* Remote Method: Simple&lt;br /&gt;
* Remote Host Name: &amp;lt;user&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;hostname or IP&amp;gt;&lt;br /&gt;
* Remote Host Port: 80&lt;br /&gt;
* Remote Host Path: /axis-cgi/jpg/image.cgi?camera=X  where X is 1,2,3 or 4 - for each channel&lt;br /&gt;
* Remote Image Colours: &amp;lt;24 bit color|32 bit color&amp;gt;&lt;br /&gt;
* Capture Width (pixels): 704&lt;br /&gt;
* Capture Height (pixels): 480&lt;br /&gt;
&lt;br /&gt;
Note: An axis tech suggested using:&lt;br /&gt;
rtsp://&amp;lt;ip&amp;gt;/axis-media/media.amp?camera=X  but I didn&amp;#039;t try it.&lt;br /&gt;
This is a really nice device for ZoneMinder - lets you use legacy cams easily.  Highly recommended.&lt;br /&gt;
&lt;br /&gt;
=== AXIS M7016 ===&lt;br /&gt;
&lt;br /&gt;
16 Channel Encoder.&lt;br /&gt;
&lt;br /&gt;
Same as above, but there is also an option to use &amp;#039;quad&amp;#039; for the cameras, instead of a number, and this quad option will give you a composite stream of all 4 cameras.&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?p=132442#p132442&lt;br /&gt;
&lt;br /&gt;
=== AXIS 240Q ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4 Channel video encoder. Works well. Somewhat awkward to place on a shelf as ethernet is on one side and coaxial is on opposite side. Requires a funny coaxial plug size (as all axis equipment seems to). Might want to buy a set of adaptors such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. Or use POE if possible.&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|200px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
Works with these settings (taken from the user manual for this device which explicitly details paths):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Protocol: HTTP&lt;br /&gt;
Method: Simple&lt;br /&gt;
Hostname: user:pass@&amp;lt;ipaddress&amp;gt;&lt;br /&gt;
Port: 80&lt;br /&gt;
Path: /mjpg/1/video.mjpg?user=&amp;lt;user&amp;gt;&amp;amp;pwd=&amp;lt;pass&amp;gt;&lt;br /&gt;
Width: 704&lt;br /&gt;
Height: 480&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issues==&lt;br /&gt;
&lt;br /&gt;
Early 207&amp;#039;s have hardware issues, see [http://www.zoneminder.com/forums/viewtopic.php?t=5022 this thread] in the forum for details.&lt;br /&gt;
&lt;br /&gt;
The [http://www.axis.com/techsup/cam_servers/cam_2100/index.htm 2100 has been discontinued by Axis] and no longer supported, possibly due to hardware problems. It&amp;#039;s noted in the [http://www.zoneminder.com/forums/viewtopic.php?t=10079 forums that the camera sends the pictures it captures somewhat diced up.]&lt;br /&gt;
&lt;br /&gt;
There were murmurs about Companion cameras not being compatible, (see also axis forums), but these may be supported, albeit with a nonstandard path. [http://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=26868]. Requires Windows to setup camera username/password. The Ios and Android app do not allow configuration. And you must make an axis account.&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17930</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17930"/>
		<updated>2026-03-04T19:57:19Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Timelapse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
===Timelapse===&lt;br /&gt;
&lt;br /&gt;
 today=$(date +&amp;quot;%Y_%m_%d&amp;quot;)&lt;br /&gt;
 0 12 * * *   root wget http://user:password@ipaddress/jpg/image.jpg -O /externalstorage/timelapse/$today.jpg&lt;br /&gt;
There is no need to use zm for a timelapse. You can just grab photos manually using cron. The path to the jpg will differ depending upon&lt;br /&gt;
the make/model camera. This example is for Axis cameras&lt;br /&gt;
&lt;br /&gt;
One thing about timelapses, is how well can you keep storage without losing files. Over time it&amp;#039;s easy to have&lt;br /&gt;
a hdd fail. so you will want to backup offsite.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17929</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17929"/>
		<updated>2026-03-04T19:49:27Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Timelapse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
===Timelapse===&lt;br /&gt;
&lt;br /&gt;
 today=$(date +&amp;quot;%Y_%m_%d&amp;quot;)&lt;br /&gt;
 0 12 * * *   root wget http://user:password@ipaddress/jpg/image.jpg -O /externalstorage/timelapse/$today.jpg&lt;br /&gt;
There is no need to use zm for a timelapse. just grab photos manually using cron. the path to the jpg will differ depending upon&lt;br /&gt;
camera. This example is for Axis cameras&lt;br /&gt;
&lt;br /&gt;
One thing about timelapses, is how well can you keep storage without losing files. Over time it&amp;#039;s easy to have&lt;br /&gt;
a hdd fail. so you will want to backup offsite.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17928</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17928"/>
		<updated>2026-03-04T19:49:09Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Embedding ZM in a webpage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
===Timelapse===&lt;br /&gt;
&lt;br /&gt;
 today=$(date +&amp;quot;%Y_%m_%d&amp;quot;)&lt;br /&gt;
 0 12 * * *   root wget http://user:password@ipaddress/jpg/image.jpg -O /externalstorage/timelapse/$today.jpg&lt;br /&gt;
There is no need to use zm for a timelapse. just grab photos manually. the path to the jpg will differ depending upon&lt;br /&gt;
camera. This example is for Axis cameras&lt;br /&gt;
&lt;br /&gt;
One thing about timelapses, is how well can you keep storage without losing files. Over time it&amp;#039;s easy to have&lt;br /&gt;
a hdd fail. so you will want to backup offsite.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17927</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17927"/>
		<updated>2026-03-04T19:48:57Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Timelapse */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17926</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17926"/>
		<updated>2026-03-04T19:48:37Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Zone Tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
===Timelapse===&lt;br /&gt;
&lt;br /&gt;
 today=$(date +&amp;quot;%Y_%m_%d&amp;quot;)&lt;br /&gt;
 0 12 * * *   root wget http://user:password@ipaddress/jpg/image.jpg -O /externalstorage/timelapse/$today.jpg&lt;br /&gt;
There is no need to use zm for a timelapse. just grab photos manually. the path to the jpg will differ depending upon&lt;br /&gt;
camera. This example is for Axis cameras&lt;br /&gt;
&lt;br /&gt;
One thing about timelapses, is how well can you keep storage without losing files. Over time it&amp;#039;s easy to have&lt;br /&gt;
a hdd fail. so you will want to backup offsite.&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17925</id>
		<title>Finding Camera Stream Paths</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Finding_Camera_Stream_Paths&amp;diff=17925"/>
		<updated>2026-02-24T09:09:42Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Reverse Engineering Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains methods and approaches for getting cameras to work with ZM. The best results will be with cameras tested by users in the [[Hardware Compatibility List]]. Next will be with cameras that detail the path in user manuals, and or are Onvif compliant. Proprietary and undocumented cameras are more difficult.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Overall, this can be as simple as looking in the user manual, or as complicated as reverse engineering and breaking into the device.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Typical methods of obtaining the cameras paths in order of easiest to hardest are:&lt;br /&gt;
&lt;br /&gt;
*User Manual/Website&lt;br /&gt;
*Onvif probe&lt;br /&gt;
*Search online resources and forums&lt;br /&gt;
*Get access to the camera shell&lt;br /&gt;
*Intercept network packets with TCPDump or Wireshark&lt;br /&gt;
*Reverse Engineer&lt;br /&gt;
&lt;br /&gt;
Double check that you don&amp;#039;t have any other settings that may block cameras communicating to your computer (firewall, antivirus, etc). For new users who install using the [https://wiki.zoneminder.com/Helpful_user_contributed_resources#Installation_Procedure recommended install] guides, this should not be a concern.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; While doing this testing, you want to keep in mind the following:&lt;br /&gt;
* Test outside of ZM, first. (this is faster)&lt;br /&gt;
* Verify that ffmpeg / vlc works (see below for examples of usage)&lt;br /&gt;
* use the info that works in ffmpeg or vlc in zm.&lt;br /&gt;
&lt;br /&gt;
==Testing out a Camera==&lt;br /&gt;
Easy tools to quickly check whether a stream path works in ZM or not are [[VLC]] and [[Ffmpeg]].&lt;br /&gt;
As an example, VLC from the gui (file -&amp;gt; connect to network stream) would connect with a path possibly like&lt;br /&gt;
 rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the hardware compatibility lists for more details. Port for RTSP is usually but not always 554.&lt;br /&gt;
&lt;br /&gt;
If you want to test from the terminal without X, you can use ffmpeg&lt;br /&gt;
 $ ffmpeg -i rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;  output.mp4&lt;br /&gt;
 or (from X)&lt;br /&gt;
 $ ffplay rtsp://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;ipaddress&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;somepath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the stream connects, it will provide you with some information about the stream encoding, and also the resolution.&lt;br /&gt;
&lt;br /&gt;
Note that the above are examples for RTSP. You would use http for MJPEG. See the [[Hardware Compatibility List]] for more details.&lt;br /&gt;
&lt;br /&gt;
==Required Fields==&lt;br /&gt;
&lt;br /&gt;
Not all fields are required to be filled in for Zoneminder. &lt;br /&gt;
&lt;br /&gt;
* Resolution must be right. &lt;br /&gt;
* Most cameras require username/password.&lt;br /&gt;
&lt;br /&gt;
If you are unsure how to fill in the information into Zoneminder, refer to the [[Hardware Compatibility List]] for other cameras, and copy them.&lt;br /&gt;
&lt;br /&gt;
Note that the results you get from cameras will differ depending on how you connect to the camera (whether you choose, remote, ffmpeg, or libvlc in ZM).&lt;br /&gt;
&lt;br /&gt;
===Example Camera===&lt;br /&gt;
Here&amp;#039;s an example of one camera setup in ZM. Note that this is not the only way to setup cameras. There are a lot of other approaches that would&amp;#039;ve been equally viable. But in this example, we use FFMPEG, motion detection, a preview of 800x600, and h264 passthrough so that recorded videos are the full resolution (1920x1280). Also note that with this camera it&amp;#039;s possible to set parameters via the address (e.g. the ? at the end of the URL can have fps or resolution set) which makes it easier to maintain the cameras instead of having to use the Web interface of the camera.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Zmcamera example1.png|General Tab|link=https://wiki.zoneminder.com/images/a/ae/Zmcamera_example1.png&lt;br /&gt;
File:Zmcamera example2.png|Source Tab|link=https://wiki.zoneminder.com/images/5/52/Zmcamera_example2.png&lt;br /&gt;
File:Zmcamera example3.png|Storage Tab|link=https://wiki.zoneminder.com/images/f/ff/Zmcamera_example3.png&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===User Manual===&lt;br /&gt;
&lt;br /&gt;
Reputable name brand cameras will provide video stream paths in the user manual or website. If you bought an unbranded cheap camera or one of the proprietary &amp;#039;cloud&amp;#039; cameras sold in retail stores then you must move onto the other options.&lt;br /&gt;
&lt;br /&gt;
[[File:Usermanualexample1.png|350px|thumb|right|Here, the user manual indicates the RTSP path.]]&lt;br /&gt;
&lt;br /&gt;
===Onvif===&lt;br /&gt;
&lt;br /&gt;
Starting with Zoneminder 1.30.4 there is an Onvif probe option in the camera configuration. You can also use external Onvif programs. Onvif is an open standard protocol, where you can get the path information from the cameras, and possibly other information such as PTZ commands or motion detection. https://en.wikipedia.org/wiki/ONVIF&lt;br /&gt;
&lt;br /&gt;
===Web Search Online===&lt;br /&gt;
&lt;br /&gt;
Ispyconnect has a large database of URLs available for cameras. The ZM wiki has some. Use a search engine. You may also come across a telnet or ssh password, which can be used to gain access to the camera shell.&lt;br /&gt;
&lt;br /&gt;
===Camera Shell===&lt;br /&gt;
&lt;br /&gt;
Many cameras run GNU/Linux. If you can get access to the files on the camera, through telnet, or through exploiting a vulnerability in the camera, then you can look around for paths. You may be able to send files from the camera to your local machine using FTP. Cameras often have busybox, or similar utils. Running the command &amp;quot;strings&amp;quot; on binaries may come up with something. Run nmap on the camera to see what ports are open. See more details in external links at the bottom.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap -p1-65535 &amp;lt;ipaddressofcamera&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Also try (from:https://ipcamtalk.com/threads/imou-ranger-pro-rtsp-problems-solved.60271/) &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ nmap --script rtsp-url-brute -p 554 &amp;lt;ipaddress&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wireshark/TCPdump===&lt;br /&gt;
&lt;br /&gt;
Watch the packets coming from the camera when accessing the video stream, and determine where the stream is located if possible. Some cameras require custom authentication, so if your camera is proprietary, then things are more difficult. This is the danger of purchasing cameras that don&amp;#039;t follow the standard (onvif). Some cameras will also announce the camera stream URL when they boot on the network. Wireshark and or TCPdump can be useful for this. At the least, they may indicate the IP address.&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering===&lt;br /&gt;
&lt;br /&gt;
Reverse engineering is one possibly time-intensive method of getting information from a given camera. See the reverse engineering links below.&lt;br /&gt;
&lt;br /&gt;
==Tips/Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
* Some cameras have limited space for username / password. Be wary of the camera cutting off the end of the password.&lt;br /&gt;
* Some cameras don&amp;#039;t handle special characters in passwords well. https://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=117987#p117987&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
&lt;br /&gt;
*[https://www.ispyconnect.com/userguide-connecting-cameras.aspx iSpy Connect cameras guide]&lt;br /&gt;
*[https://www.ispyconnect.com/sources.aspx  iSpy Database]&lt;br /&gt;
*[http://zoneminder.readthedocs.io/en/latest/userguide/definemonitor.html Official ZM Documentation] on this subject&lt;br /&gt;
*[https://shinobi.video/docs/cameras Shinobi List]&lt;br /&gt;
&lt;br /&gt;
===Reverse Engineering Links===&lt;br /&gt;
*https://web.archive.org/web/20180124024708/https://github.com/sgayou/medfusion-4000-research/blob/master/doc/README.md Advanced reverse engineering/exploitation of a medical device&lt;br /&gt;
*https://www.contextis.com/blog/push-hack-reverse-engineering-ip-camera Reverse Engineering an IP Camera&lt;br /&gt;
*https://alexhude.github.io/2019/01/24/hacking-leica-m240.html Reverse Engineering a consumer camera&lt;br /&gt;
&lt;br /&gt;
*http://web.archive.org/web/20190609073446/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-i/  Wyzesensor reverse engineering (1/3)&lt;br /&gt;
*http://web.archive.org/web/20190606222131/https://hclxing.wordpress.com/2019/05/30/reverse-engineering-wyzesense-bridge-protocol-part-ii/ Wyzesensor reverse engineering (2/3)&lt;br /&gt;
*https://hclxing.wordpress.com/2019/06/06/reverse-engineering-wyzesense-bridge-protocol-part-iii/ Wyzesensor reverse engineering (3/3)&lt;br /&gt;
*https://github.com/EliasKotlyar/Xiaomi-Dafang-Hacks Xiaomi / Wyzecam Camera Reverse Engineering&lt;br /&gt;
*https://www.eionix.co.in/2019/10/10/reverse-engineer-ddpai-firmware.html Reverse Engineering a Dashcam&lt;br /&gt;
*Huang, Andrew &amp;quot;Bunnie&amp;quot;, (2017) The Hardware Hacker. pg 279. No Starch Press.&lt;br /&gt;
*http://web.archive.org/web/20201102155358/https://wrongbaud.github.io/Holiday-Teardown/ &lt;br /&gt;
*http://web.archive.org/web/20210212100444/https://frdmtoplay.com/patching-in-fahrenheit/ - Disassembly and patching.&lt;br /&gt;
*https://unnamedre.com/ Podcast on reverse engineering. I haven&amp;#039;t listened to it yet, but it may be a valuable reference.&lt;br /&gt;
*https://www.eevblog.com/forum/reviews/identifying-the-mcu-from-rt85-handheld-radio/ - firmware hacking of a handheld radio&lt;br /&gt;
*http://web.archive.org/web/20230210164816/https://eta.st/2023/01/31/rail-tickets.html - qr codes&lt;br /&gt;
*https://github.com/racerxdl/stm32f0-pico-dump&lt;br /&gt;
*https://hackaday.com/2022/05/04/dumping-encrypted-at-rest-firmware-of-xiaomi-smart-kettle/&lt;br /&gt;
*https://hackaday.com/2023/02/05/need-to-dump-a-protected-stm32f0x-use-your-pico/&lt;br /&gt;
*https://youtu.be/Y7Z5Q_sNqUw  SUPERCON 2022: Kuba Tyszko Cracks Encrypted Software&lt;br /&gt;
*https://hackaday.com/2024/01/19/alarm-panel-hack-defeats-encryption-by-ignoring-it/ - Sometimes you can just go right to the display and buttons and ignore the rest of the device&lt;br /&gt;
*https://youtu.be/uGfVn-cyz3o https://youtu.be/lbSalKp_ldA IP Camera firmware extraction and disassembly of a hardcoded password &lt;br /&gt;
*https://hackaday.com/2026/02/14/reverse-engineering-a-dash-robot-with-ghidra/ - Ghidra disassembly of binaries.&lt;br /&gt;
*https://www.robopenguins.com/reverse-dash/ - From the previous link. &lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17890</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17890"/>
		<updated>2026-01-21T04:05:14Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Other Users */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere to see a timelapse.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17889</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17889"/>
		<updated>2026-01-21T04:03:15Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Other Users */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge. You might also want to take photos once a day and store them somewhere for fun.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17888</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17888"/>
		<updated>2026-01-21T03:52:30Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Other Users */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=34242 - Recording once a day for something like a liquid level gauge.&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17887</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17887"/>
		<updated>2026-01-21T03:49:45Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440 (Note that I have not found this necessary with ~40 cameras)&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17886</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17886"/>
		<updated>2026-01-21T03:46:20Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Overlaying Text Data onto a Video Feed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. &lt;br /&gt;
&lt;br /&gt;
Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to the [https://zoneminder.readthedocs.io/en/stable/userguide/components.html Official Docs] or the zmtrigger.pl script for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17885</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17885"/>
		<updated>2026-01-21T03:46:03Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Overlaying Text Data onto a Video Feed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. &lt;br /&gt;
&lt;br /&gt;
Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to [https://zoneminder.readthedocs.io/en/stable/userguide/components.html The Official Documentation] or the zmtrigger.pl script for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17884</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17884"/>
		<updated>2026-01-21T03:44:55Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Overlaying Text Data onto a Video Feed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. &lt;br /&gt;
&lt;br /&gt;
Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to [https://zoneminder.readthedocs.io/en/stable/userguide/components.html] or the zmtrigger.pl script for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17883</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17883"/>
		<updated>2026-01-21T03:44:39Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Overlaying Text Data onto a Video Feed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. &lt;br /&gt;
&lt;br /&gt;
Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to [[https://zoneminder.readthedocs.io/en/stable/userguide/components.html]] for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17882</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17882"/>
		<updated>2026-01-21T03:44:23Z</updated>

		<summary type="html">&lt;p&gt;Burger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. &lt;br /&gt;
&lt;br /&gt;
Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to [[Documentation]] for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17881</id>
		<title>ZMTrigger</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMTrigger&amp;diff=17881"/>
		<updated>2026-01-21T03:44:13Z</updated>

		<summary type="html">&lt;p&gt;Burger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/usr/bin/zmtrigger.pl (debian location) is an optional program for Zoneminder that listens on the network for commands. Read the perl script for more information. It is a telnet server.&lt;br /&gt;
&lt;br /&gt;
It can be used in different ways. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1)&amp;#039;&amp;#039;&amp;#039; it can be used is to overlay text information (e.g. temperature sensor) onto the video feed. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;2)&amp;#039;&amp;#039;&amp;#039; It can also be used as an external trigger / alarm source for cameras. By using an external alarm, you can avoid some of the problems inherent in ZM software modect - false alarms, and CPU usage. False alarms are commonly caused when the video feed has an ambient change come across it, e.g. weather events, wildlife, or the transition from daylight to night ir filter. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;3)&amp;#039;&amp;#039;&amp;#039; You can monitor which alarms are active or not at a given time. ZMTrigger reports when alarms are active, and when they are closed. This data can be queried by external programs.&lt;br /&gt;
&lt;br /&gt;
Note that if you have a house, or single breaker, you might want to consider using [[X10]] for Zoneminder. This will save you the need for ethernet wiring, or setting up wifi. Some notes on ZMTrigger from the official docs here: https://zoneminder.readthedocs.io/en/stable/userguide/components.html&lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Enable it first, by going into options, config, and checking Enable Triggers (OPT_TRIGGER).&lt;br /&gt;
&lt;br /&gt;
Then restart ZM.&lt;br /&gt;
 # /etc/init.d/zoneminder restart&lt;br /&gt;
Verify it is running with &lt;br /&gt;
 ps auxw | grep zmtrigger&lt;br /&gt;
Verify the port is 6802 and tcp&lt;br /&gt;
 netstat -ntulp&lt;br /&gt;
 or&lt;br /&gt;
 ss -ntulp&lt;br /&gt;
Make sure no firewall is blocking it on port 6802.&lt;br /&gt;
 iptables -L&lt;br /&gt;
 or&lt;br /&gt;
 nft list tables&lt;br /&gt;
 nft list table &amp;lt;result of previous command&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
===Overlaying Text Data onto a Video Feed===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After you have verified the script is running, test it is working.&lt;br /&gt;
&lt;br /&gt;
Choose a monitor by monitor ID, say monitor 1, then add %Q to the monitors timestamp section.&lt;br /&gt;
&lt;br /&gt;
The monitor &amp;#039;&amp;#039;&amp;#039;must be&amp;#039;&amp;#039;&amp;#039; in either modect, mocord, or nodect mode.&lt;br /&gt;
&lt;br /&gt;
Open the video feed for monitor 1.&lt;br /&gt;
&lt;br /&gt;
Then type in another terminal&lt;br /&gt;
&amp;lt;pre&amp;gt;telnet ipaddress 6802&amp;lt;/pre&amp;gt;&lt;br /&gt;
in the telnet session type the following&lt;br /&gt;
&amp;lt;pre&amp;gt;1|show||||testingOSD&amp;lt;/pre&amp;gt;&lt;br /&gt;
then press return.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Refer to [[Documentation]] for what this command means. A brief explanation for this is: &amp;lt;pre&amp;gt;MonitorID # | Show text mode |||| text to put in.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should immediately see testingOSD in place of the %Q you put in the timestamps section.&lt;br /&gt;
&lt;br /&gt;
For more examples and scripts of ZMTrigger search the [https://forums.zoneminder.com forums].&lt;br /&gt;
&lt;br /&gt;
Note: You can also send this to telnet in a shell script via:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
# call script and pass monitor number&lt;br /&gt;
# e.g.&lt;br /&gt;
# &amp;quot;$ ./telnet_zmtrigger_test.sh 12&amp;quot;&lt;br /&gt;
# fields are:&lt;br /&gt;
# B&amp;lt;id&amp;gt;|B&amp;lt;action&amp;gt;|B&amp;lt;score&amp;gt;|B&amp;lt;cause&amp;gt;|B&amp;lt;text&amp;gt;|B&amp;lt;showtext&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IPADDRESSOFZMSRV=192.168.1.178&lt;br /&gt;
&lt;br /&gt;
telnet $IPADDRESS 6802 &amp;lt;&amp;lt;EOF&lt;br /&gt;
$1|on+3|10|ZMTEST||&lt;br /&gt;
EOF&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Example Setup====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is a script that connects to an ipaddress which serves a sensor value. &lt;br /&gt;
Wget is not as fast as possible, but this is simple and works quickly as a test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
counter=1&lt;br /&gt;
&lt;br /&gt;
while [$counter -le 10]&lt;br /&gt;
do&lt;br /&gt;
PRESSURE=`wget ipaddress -q -O -`&lt;br /&gt;
echo &amp;quot;1|show||||$PRESSURE&amp;quot; | telnet ipaddress 6802&lt;br /&gt;
sleep 4&lt;br /&gt;
&lt;br /&gt;
#((counter++))&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This text overlay can be used for any information, not just from the LAN. Maybe you want to overlay information from an online database or website. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Possible uses of text trigger&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* temperature&lt;br /&gt;
* air pressure&lt;br /&gt;
* humidity&lt;br /&gt;
* sunset/sunrise time&lt;br /&gt;
* which alarm activated&lt;br /&gt;
* which person entered an electronically locked door&lt;br /&gt;
* random quote / message&lt;br /&gt;
* id of last camera alarm that went off on system&lt;br /&gt;
* the name of the person buying something from the POS system&lt;br /&gt;
* insert idea here&lt;br /&gt;
&lt;br /&gt;
===As an External Trigger===&lt;br /&gt;
&lt;br /&gt;
It is possible with minor effort, to communicate with ZMTrigger.pl at the Zoneminder Server IP Address, using a microcontroller and a device that does the actual triggering.  Common options would be 8-bit microcontrollers such as the Arduino Uno, the ESP8266, or an ARM based SBC such as the Raspberry Pi, Beaglebone, and others.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some benefits&lt;br /&gt;
* Fully customizable&lt;br /&gt;
* Less false positives&lt;br /&gt;
* Less CPU usage&lt;br /&gt;
* No zone configuration required&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some drawbacks&lt;br /&gt;
* Some assembly required&lt;br /&gt;
* Zone configuration isn&amp;#039;t necessary, but you may have to install these, which is slow and requires fish tape, drywall saw, experience with installing an ethernet or electrical outlet, etc...&lt;br /&gt;
&lt;br /&gt;
====Types of Controllers====&lt;br /&gt;
[[File:ArduinoUno.jpg|thumb|right|upright=0.5|alt=Uno||Arduino Uno DIP]]&lt;br /&gt;
This is up to you. If you have a wired ethernet connection available for the external sensor, then an [[Arduino]] Uno is a good choice. If you don&amp;#039;t want to run ethernet, then an ESP8266 or Arduino w/wifi should do. An Arduino Uno will require a separate ethernet board. You can also connect an Arduino via USB, if the computer is within 15 feet.&lt;br /&gt;
&lt;br /&gt;
====Types of Sensors====&lt;br /&gt;
&lt;br /&gt;
You will need to decide which sensors to use. There are many options. This is what I&amp;#039;ve used.&lt;br /&gt;
&lt;br /&gt;
=====PIR Sensors=====&lt;br /&gt;
&lt;br /&gt;
PIR stands for Passive Infrared. These can be obtained from $4 and up online. Across auction sites from China for the cheapest, to [https://www.sparkfun.com/products/13968 hobbyist electronics stores] for tested chinese products, and then for brand name sensors from electronics distributors like Digikey, Mouser, and Farnell. These sensors are useful, but have limitations.&lt;br /&gt;
&lt;br /&gt;
* Range is limited to 10-20 Feet. Sensitivity can be tuned.&lt;br /&gt;
* Sunlight will cause false triggers. Direct OR indirect. Software or hardware may be able to mitigate this (TODO).&lt;br /&gt;
* Works good in a hallway, or room where no outdoor sunlight will penetrate.&lt;br /&gt;
&lt;br /&gt;
Overall, the PIR Sensors are good if you have the right environment. They are not feasible outside, but indoors, away from sunlight, they work well.&lt;br /&gt;
&lt;br /&gt;
=====Microwave Sensors=====&lt;br /&gt;
[[File:hb100.jpeg|frame|HB100 10GHz Microwave module without circuitry||HB100]]&lt;br /&gt;
&lt;br /&gt;
Microwave sensors operate in the 5-24GHz radio bands. The 10 GHz sensors have a range of about 20-30 feet for a person, more for large vehicles (reflective metal objects). The 24GHz sensors have shorter range. There are a variety of these, from brand name, to cheap. The best sensor currently available at the lowest price is the HFS-DC06H. &lt;br /&gt;
&lt;br /&gt;
* Relatively short range for radio. Depends on RF frequency, but typically you get 5GHz = 10M, 10GHz = 5M, 24GHz = &amp;lt;3M&lt;br /&gt;
* Some of these can interfere with each other (some do not, depends on model).&lt;br /&gt;
* Detection of items depends on conductivity (large metal objects such as cars are detected from a larger distance than people. This is expected).&lt;br /&gt;
* May work too well - Mice can set off alarms (not false, but essentially unwanted alarms)(sensitivity can usually be adjusted). &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Why don&amp;#039;t I make a radio sensor that goes longer than 10M?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/Ttl/fmcw It&amp;#039;s been done]. And if they are within the ISM bands they can be used without FCC testing and approval. More details here: [https://hackaday.com/2014/02/24/guest-post-try-radar-for-your-next-project/ make FMCW radars].  Not easy but doable. The trick will be to make one that is practical enough but also not $100 each.&lt;br /&gt;
&lt;br /&gt;
=====Ultrasonic Sensors=====&lt;br /&gt;
&lt;br /&gt;
I do not use ultrasonic sensors, but maybe someone else has some experience they can chime in with here (no pun intended).&lt;br /&gt;
&lt;br /&gt;
* Uses high frequency sound, may disrupt animals.&lt;br /&gt;
&lt;br /&gt;
=====Infrared Trip Sensors=====&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s easy to find infrared trip sensors (think a laser going from 10-50 feet across). These can be setup with a microcontroller, and if someone walks across the beam, you can activate the alarm. Some brands are [http://www.sick.com/us/en Sick] or Seco-larm Enforcer. If you need a real short IR (inches), off the shelf Arduino modules will work (ir photo beam detector). These can be purchased from distributors such as [http://www.allelectronics.com] and others online. Search the opto-electronics section (subject to change). Buy used if you are on a budget.&lt;br /&gt;
&lt;br /&gt;
* Requires a bit of installation, though works well, when installed.&lt;br /&gt;
* Requires power at both ends of the laser.&lt;br /&gt;
* More Immune to sun interference than PIR&lt;br /&gt;
* One end must connect back to server somehow (ethernet/wifi/usb/X10)&lt;br /&gt;
* Reasonably long distance. Some are up to 100M.&lt;br /&gt;
* Possible to avoid if you step over them. Put these aiming at a device that moves such as a door or gate. You can also get larger sensors, which can be a 6-7 feet tall, and are used in elevators to detect people in the doorway (search &amp;quot;[https://www.pepperl-fuchs.com/global/en/classid_104.htm elevator door sensors]&amp;quot;).&lt;br /&gt;
* These are all in the class of &amp;quot;photo electric sensors&amp;quot;&lt;br /&gt;
* the single beam modules (that don&amp;#039;t have a receiver) may require a reflective sticker (bike reflector) on the other side&lt;br /&gt;
&lt;br /&gt;
An example sketch is included in the links at the bottom.&lt;br /&gt;
&lt;br /&gt;
=====Inductive Sensors=====&lt;br /&gt;
There are products that, similar to capacitive sensors, (think a Theremin https://en.wikipedia.org/wiki/theremin) you can for example attach a wire to a doorknob (or any piece of metal), then when someone touches the other side of the doorknob, the alarm is set off. These can be purchased on eBay advertised as &amp;quot;120db Wireless Touch Sensor Security Alarm Loud Door Knob&amp;quot; or some variation thereof, with even a loud buzzer should room service try to enter your room (oops). &lt;br /&gt;
[[File:Hotel_door_alarm.jpg|400px|thumb|right|For security purposes, tracking contact on any piece of metal is easy.]]&lt;br /&gt;
&lt;br /&gt;
=====Other Sensors=====&lt;br /&gt;
&lt;br /&gt;
An infinite amount of devices could be used as triggers. House alarms use reed switches on windows and doors. If you have the capital, then there are many off the shelf products that can be purchased including expensive but powerful RF modect sensors.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tail -f  /var/log/zm/zmtrigger.log&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enable debug on it in the logs and set to 9. The logs that contain the /var/log/zm/ logs are the component logs in options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After following forum recommendations to use mysqltuner (see [[MySQL]]), mysqltuner told me to add wait_timeout=300 to my.cnf.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, ZMTrigger will disconnect every five minutes, if this is enabled. It appears that ZMTrigger will &amp;quot;Loading monitors&amp;quot; every five minutes, so you can&amp;#039;t have a wait_timeout equal or lower than that. Otherwise the MySQL server will go away. If the wait timeout is higher, then ZMTrigger will &amp;quot;Loading monitors&amp;quot; without error.&lt;br /&gt;
&lt;br /&gt;
This timeout error doesn&amp;#039;t seem to adversely affect any other features of ZM so, a low wait_timeout may be acceptable if you don&amp;#039;t use ZMTrigger.&lt;br /&gt;
&lt;br /&gt;
The default wait timeout is 8 hours for MySQL. The solution seems to be add a wait_timeout &amp;gt;300, or use the default. Note that this might be fixed for ZM &amp;gt; 1.30.4&lt;br /&gt;
Reference:[https://forums.zoneminder.com/viewtopic.php?t=26316]&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
* It&amp;#039;s possible to have the source name of the device reporting the trigger to ZMTrigger [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26819 show up in the video feed]. &lt;br /&gt;
This means you could have multiple sensors, each triggering a different location. A reed switch on a window, a laser&lt;br /&gt;
on a door, etc... When the alarm goes off, the video feed displays the alarm that was triggered.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Can I have these arduino sketches set off multiple cameras?&amp;quot; Yes. You can edit the Arduino sketch to send more packets, or &amp;quot;link monitors&amp;quot; in Zoneminder. Two approaches (the latter is easier). https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=26794&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[How to use your external camera&amp;#039;s motion detection with ZM]] - A good writeup on ZMTrigger from the original developer of ZMNinja&lt;br /&gt;
&lt;br /&gt;
* https://sparxeng.com/blog/software/zoneminder-network-triggering - More explanations&lt;br /&gt;
&lt;br /&gt;
* [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=25704 ZM Forums: Add temperature to image]&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]]&lt;br /&gt;
&lt;br /&gt;
* Arduino Infrared Tripwire Sketch via ethernet: [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=27442]&lt;br /&gt;
&lt;br /&gt;
* Arduino Sketch via USB [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26945]&lt;br /&gt;
&lt;br /&gt;
* [[Arduino]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17880</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17880"/>
		<updated>2026-01-21T03:39:55Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
* If possible, you might want to consider shutting off cameras when they are not needed to save on energy use. A managed POE switch should be able to do this. Cameras, are about 500mA of 12V so that is perhaps 6W each.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17873</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17873"/>
		<updated>2026-01-09T20:55:02Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A. For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17872</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17872"/>
		<updated>2026-01-09T20:54:51Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A. For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17871</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17871"/>
		<updated>2026-01-09T20:52:02Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A. For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17870</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17870"/>
		<updated>2026-01-09T20:49:55Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A. For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17869</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17869"/>
		<updated>2026-01-09T20:49:42Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A.For more details see http://strftime.org and http://zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17868</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17868"/>
		<updated>2026-01-09T20:49:20Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A.For more details see [strftime.org] and [zoneminder.readthedocs.io]&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17867</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17867"/>
		<updated>2026-01-09T20:48:26Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have Sun Sep 15 07:06:05 2015 Format===&lt;br /&gt;
&lt;br /&gt;
This benefits from having the day of the week in the string. Not necessary for legal use, but is useful if you review videos between two days of the week. &lt;br /&gt;
&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %c&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The day of the week is either %a (shorthand) or %A.For more details see strftime.org and zoneminder.readthedocs.io&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17856</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17856"/>
		<updated>2025-12-25T19:29:29Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Events Count on the Console if Event Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17855</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17855"/>
		<updated>2025-12-25T19:25:34Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Events Count on the Console if Event Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17854</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17854"/>
		<updated>2025-12-25T19:25:08Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Events Count on the Console if Event Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
&lt;br /&gt;
for i in {1..100}&lt;br /&gt;
do&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;#039;$i&amp;#039;) where MonitorID=&amp;#039;$i&amp;#039;;&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17853</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17853"/>
		<updated>2025-12-25T19:10:00Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36. (You could also use something like Zabbix, or some other monitoring solution).&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17852</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17852"/>
		<updated>2025-12-25T19:09:21Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Events Count on the Console if Event Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
 for i in {1..100}&lt;br /&gt;
 do&lt;br /&gt;
 update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;quot;$i&amp;quot;) where MonitorID=&amp;quot;$i&amp;quot;;&lt;br /&gt;
 done&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17851</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17851"/>
		<updated>2025-12-25T19:05:04Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Events Count on the Console if Event Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
 update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
 update Event_Summaries set TotalEventDiskSpace=    (Select Sum(DiskSpace) from Events where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEventDiskSpace=     (Select Sum(DiskSpace) from Events_Hour where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEventDiskSpace=      (Select Sum(DiskSpace) from Events_Day where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEventDiskSpace=     (Select Sum(DiskSpace) from Events_Week where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEventDiskSpace=    (Select Sum(DiskSpace) from Events_Month where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEventDiskSpace= (Select Sum(DiskSpace) from Events_Archived where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17850</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17850"/>
		<updated>2025-12-25T18:58:25Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Zone Count on the Console if Zone Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Update Events Count on the Console if Event Count is Incorrect===&lt;br /&gt;
 update Event_Summaries set TotalEvents=     (Select count(*) from Events where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set HourEvents=      (Select count(*) from Events_Hour where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set DayEvents=       (Select count(*) from Events_Day where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set WeekEvents=      (Select count(*) from Events_Week where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set MonthEvents=     (Select count(*) from Events_Month where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
 update Event_Summaries set ArchivedEvents=  (Select count(*) from Events_Archived where MonitorID=&amp;quot;1&amp;quot;) where MonitorID=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17849</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17849"/>
		<updated>2025-12-25T18:41:55Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Print the Last 50 Times from a Camera Monitor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Given Monitor&amp;#039;s Recordings===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17848</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17848"/>
		<updated>2025-12-25T18:41:14Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Print the Last 50 Times from a Camera Monitor */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Camera Monitor===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Order by StartDateTime Desc Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17847</id>
		<title>MySQL</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=MySQL&amp;diff=17847"/>
		<updated>2025-12-25T18:38:47Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Update Zone Count on the Console if Zone Count is Incorrect */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setup==&lt;br /&gt;
&lt;br /&gt;
MySQL (or MariaDB) creates a db named zm after ZoneMinder is installed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ mysql -u root -p &lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;gt;use zm;&lt;br /&gt;
&amp;gt;show tables;&lt;br /&gt;
&amp;gt;select * from Monitors\G&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some .sql setup scripts. And typically, permissions are granted for zmuser to access the zm database. This may or may not be  done manually depending on what install guide you follow. It is recommended to use the guides here: [[Debian]] or [[Ubuntu]]. Sometimes things break, and you will need to rebuild the database, so for reference the steps are kept below (example from Debian):&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root -p -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 mysqladmin -u root -p reload&lt;br /&gt;
&lt;br /&gt;
==Backup==&lt;br /&gt;
&lt;br /&gt;
There are two options: 1) Backup the full database (with events). 2) Backup only the configuration.&lt;br /&gt;
 &lt;br /&gt;
For 1), It does not backup any videos or images. So you will have a copy of all metadata referring to events, yet the video files on the filesystem will not be saved. If it&amp;#039;s necessary to have an offsite backup, you may want to consider a VPS as storage. Amazon S3FS support is built into Zoneminder and that is one option. Though it can be as simple as rsync-ing videos to a network share. See [https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815 link on the forums] &lt;br /&gt;
&lt;br /&gt;
For 2), the config saved will allow you to restore all the camera configuration, zones, filters, runstates, etc... It will not, however save any event data, nor will it save any videos. If you have a hardware failure, you will lose all camera footage, and event data. For less critical installations, this is acceptable. Since most events are exported shortly after they happen, most users will want to use option 2.&lt;br /&gt;
&lt;br /&gt;
If the database is restored from a config /usr/bin/zmaudit.pl must be run to remove the old video files from the filesystem. &lt;br /&gt;
&lt;br /&gt;
===Full Backup===&lt;br /&gt;
This may take a while. It is recommended to stop the Zoneminder service while this backup is running. [https://forums.zoneminder.com/viewtopic.php?p=138526#p138526 *]&lt;br /&gt;
 su - root&lt;br /&gt;
 mysqldump -u root  zm &amp;gt; zmdb.sql&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
&lt;br /&gt;
===Backup config only===&lt;br /&gt;
This will run quickly: usually less than a second. The Zoneminder service does not usually need to be stopped.&lt;br /&gt;
&amp;lt;pre&amp;gt;DATE=&amp;quot;$(date +%F)&amp;quot;&lt;br /&gt;
 mysqldump -u root  zm --ignore-table=zm.Events --ignore-table=zm.Frames --ignore-table=zm.Logs --ignore-table=zm.Stats --ignore-table=zm.Events_Day --ignore-table=zm.Events_Hour --ignore-table=zm.Events_Month --ignore-table=zm.Events_Week --ignore-table=zm.Event_Summaries &amp;gt; zmdb_configonly_$DATE.sql&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Restore from config only or Recreate db&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
As mentioned above, if restoring to a new machine and starting from scratch, you will need to add permissions for zmuser to mysql. You will also need to recreate the db. &lt;br /&gt;
 mysql -u root  -e &amp;quot;drop database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
 mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
 mysql -u root  zm &amp;lt; zmdb.sql&lt;br /&gt;
 mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
 zmaudit.pl&lt;br /&gt;
&lt;br /&gt;
You may also want to run zmupdate.pl -f to make sure the database is updated properly.&lt;br /&gt;
From the forum:&lt;br /&gt;
 To update db structure:&lt;br /&gt;
 sudo zmupdate.pl&lt;br /&gt;
 Tp update the contents of the configuration table:&lt;br /&gt;
 sudo zmupdate.pl -f&lt;br /&gt;
&lt;br /&gt;
===Regular Backups===&lt;br /&gt;
You should use cron to do regular backups (where mysql_config_backup.sh is the script above, with chmod +x) . You may also want to keep copies offsite, in case of catastrophic hard drive failure.&lt;br /&gt;
 in /etc/crontab&lt;br /&gt;
 0 12 1 * * root cd /home/user/zmbackups &amp;amp;&amp;amp; /home/user/mysql_config_backup.sh&lt;br /&gt;
&lt;br /&gt;
==Example Queries==&lt;br /&gt;
Here are a number of MySQL queries that may be useful for Zoneminder. Often, accessing the database from the terminal will be faster than using the web gui.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how you can change a parameter in the ZM database by logging into MySQL:&lt;br /&gt;
 su - root&lt;br /&gt;
 mysql -u root zm&lt;br /&gt;
 &amp;gt; show tables;&lt;br /&gt;
 &amp;gt; select * from Users\G&lt;br /&gt;
 &amp;gt; update Users set MaxBandwidth = &amp;#039;Low&amp;#039; where Username = &amp;#039;user1&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
Here is a one line command for changing a parameter without logging into MySQL.&lt;br /&gt;
 mysql -u root  zm -e &amp;quot;update Monitors set DecoderHWAccelName = &amp;#039;NULL&amp;#039; where DecoderHWAccelName = &amp;#039;vaapi&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A full list of db columns can be found in the [https://www.github.com/zoneminder/zoneminder/ source code] under the db folder. If any of these queries fail, review the field names. Things change in the db from time to time.&lt;br /&gt;
&lt;br /&gt;
===Change Storage Area for Multiple Cameras===&lt;br /&gt;
If you have multiple cameras set to a storage area. It would be tedious to manually update each one.&lt;br /&gt;
&lt;br /&gt;
Storage Area is the key StorageID in Monitors (1.32.3), therefore&lt;br /&gt;
&lt;br /&gt;
use tmux to view mysql&lt;br /&gt;
 select * from Monitors LIMIT 1\G  #review fields&lt;br /&gt;
 select StorageId from Monitors \G #see current settings&lt;br /&gt;
use ctrl-b pageup pagedn to navigate and review fields.&lt;br /&gt;
&lt;br /&gt;
press q to exit this view.&lt;br /&gt;
 update Monitors set StorageId = 2 where StorageId = 0;&lt;br /&gt;
&lt;br /&gt;
In practice you would probably set specific monitors, not all of them.&lt;br /&gt;
&lt;br /&gt;
===Set all Cameras to Use H264 Encode===&lt;br /&gt;
Per previous example: (1.32.3 tested, review your tables for changes)&lt;br /&gt;
&lt;br /&gt;
 update Monitors set VideoWriter = 1 where VideoWriter = 0;&lt;br /&gt;
&lt;br /&gt;
In 1.36 you should also set the following, otherwise HEVC aka H265 will be used (H265 support in 2024 is still limited in browsers and not recommended).&lt;br /&gt;
&lt;br /&gt;
 update Monitors set OutputCodec = 27;&lt;br /&gt;
 update Monitors set Encoder     = &amp;quot;libx264&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
You may also want to disable JPEG encoding.&lt;br /&gt;
&lt;br /&gt;
 update Monitors set SaveJPEGs = 0 where SaveJPEGs = 3;&lt;br /&gt;
&lt;br /&gt;
Though, you may want to use passthrough instead of encode when possible. This example is more of an example of ZM SQL administration, not a recommendation for Zoneminder settings.&lt;br /&gt;
&lt;br /&gt;
===Set all cameras to limit zma to 2 FPS===&lt;br /&gt;
Framerate in the analysis (previously zma) can be limited to lower CPU use.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.30.4 or older:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
 update Monitors set AnalysisFPS=&amp;quot;2.00&amp;quot; where AnalysisFPS=&amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;1.34 or newer:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Analysisfps cell in zm.Monitors table has changed, therefore:&lt;br /&gt;
instead of = 0.00 or = null we must do is null&lt;br /&gt;
&lt;br /&gt;
 update Monitors set AnalysisFPSLimit=&amp;quot;2.00&amp;quot; where AnalysisFPSLimit is NULL;&lt;br /&gt;
&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy Instead of dd/mm/yy in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m-%d-%Y %H:%M:%S %z&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
===Change All Cameras to Have mm/dd/yy and 12 hour / AM/PM in Timestamp===&lt;br /&gt;
(1.34)&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %Y-%m-%d %H:%M:%S %z&amp;quot;;&lt;br /&gt;
The %z is for offset from GMT, which most people won&amp;#039;t need. These can be found from the man page for date.&lt;br /&gt;
Or:&lt;br /&gt;
 UPDATE Monitors SET LabelFormat =&amp;quot;%N - %m/%d/%Y %l:%M:%S %p&amp;quot; WHERE LabelFormat =&amp;quot;%N - %d/%m/%y %H:%M:%S&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
You can review the existing Timestamps with:&lt;br /&gt;
 select LabelFormat from Monitors\G&lt;br /&gt;
&lt;br /&gt;
Zoneminder must be restarted for changes to take effect.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note&amp;#039;&amp;#039;&amp;#039; that for fail2ban, you may want to use the &amp;#039;&amp;#039;&amp;#039;DATETIME_OVERRIDE_PATTERN&amp;#039;&amp;#039;&amp;#039; in options. See [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
===Check Value of AUTH_RELAY===&lt;br /&gt;
If you set Auth relay to none, then it&amp;#039;s possible to access cameras from wan via a direct monitor link. So check any WAN accessible installations.&lt;br /&gt;
 &lt;br /&gt;
 cd zoneminder&lt;br /&gt;
 grep -ri auth_relay&lt;br /&gt;
 select * from Config where Name = &amp;quot;ZM_AUTH_RELAY&amp;quot;\G&lt;br /&gt;
&lt;br /&gt;
This also means that you can get direct video URLs from a secure LAN without authentication, if desired.&lt;br /&gt;
 &lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28144&amp;amp;p=117900#p117900&lt;br /&gt;
&lt;br /&gt;
===Add API/Mobile User with View Permissions===&lt;br /&gt;
 mysql -u zmuser -p&lt;br /&gt;
  use zm;&lt;br /&gt;
  INSERT INTO Users(Username,Password,Language,Enabled,Stream,Events,Monitors,APIEnabled)   VALUES(&amp;quot;testguy&amp;quot;,Password(&amp;quot;somepass&amp;quot;),&amp;quot;en_us&amp;quot;,&amp;quot;1&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;View&amp;quot;,&amp;quot;1&amp;quot;);&lt;br /&gt;
  \q&lt;br /&gt;
 zmupdate.pl -f &lt;br /&gt;
&amp;lt;small&amp;gt;(-f will &amp;#039;freshen&amp;#039; up the db, encrypting password with bcrypt, handled by perl in zmupdate.pl.in)&lt;br /&gt;
Note: If you add a user and don&amp;#039;t specify APIEnabled or not, it will default to enabled.&lt;br /&gt;
&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delete User===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
select * from Users where Username=&amp;quot;Defunct User&amp;quot;\G&lt;br /&gt;
delete from Users where Username=&amp;quot;Defunct User&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Estimate RAM usage from Monitors===&lt;br /&gt;
&amp;lt;pre&amp;gt;select x.Id, x.Width, x.Height, x.ImageBufferCount, x.Colours, x.BufferSpace as BufferMB, 1.2*sum(x.BufferSpace) over (Order by Id) as RunningTotalMB_w_OH from (select Id, Width,Height,ImageBufferCount,Colours,(Width*Height*ImageBufferCount*Colours/1024/1024) as BufferSpace  from Monitors order by Id) x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
results:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
| Id | Width | Height | ImageBufferCount | Colours | BufferMB      | RunningTotalMB_w_OH |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
|  1 |  1920 |   1080 |              100 |       3 |  593.26171875 |       711.914062500 |&lt;br /&gt;
|  2 |  1920 |   1080 |               50 |       3 |  296.63085938 |      1067.871093756 |&lt;br /&gt;
|  5 |  1920 |   1080 |               40 |       3 |  237.30468750 |      1352.636718756 |&lt;br /&gt;
|  6 |   704 |    480 |               20 |       3 |   19.33593750 |      1375.839843756 |&lt;br /&gt;
|  7 |   704 |    480 |               20 |       3 |   19.33593750 |      1399.042968756 |&lt;br /&gt;
|  8 |  1920 |   1080 |               20 |       3 |  118.65234375 |      1541.425781256 |&lt;br /&gt;
|  9 |   704 |    480 |               20 |       3 |   19.33593750 |      1564.628906256 |&lt;br /&gt;
| 10 |   704 |    480 |               20 |       3 |   19.33593750 |      1587.832031256 |&lt;br /&gt;
| 11 |   640 |    480 |               20 |       1 |    5.85937500 |      1594.863281256 |&lt;br /&gt;
| 12 |   480 |    360 |               20 |       1 |    3.29589844 |      1598.818359384 |&lt;br /&gt;
| 13 |  2560 |   1920 |              110 |       4 | 2062.50000000 |      4073.818359384 |&lt;br /&gt;
| 14 |  2560 |   1920 |              121 |       4 | 2268.75000000 |      6796.318359384 |&lt;br /&gt;
| 15 |   640 |    480 |               20 |       4 |   23.43750000 |      6824.443359384 |&lt;br /&gt;
+----+-------+--------+------------------+---------+---------------+---------------------+&lt;br /&gt;
13 rows in set (3.46 sec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;p=119899&amp;amp;sid=c115f6a9443d70e8a4cb00c5e04883f8#p119899&lt;br /&gt;
&lt;br /&gt;
===Disable Logging via cli===&lt;br /&gt;
Here is an example where mysql is scripted from the shell.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;Disabling logging by setting to -5 (1 for debug, -5 for nothing)&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_SYSLOG&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_FILE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_DATABASE&amp;#039;;&amp;quot;&lt;br /&gt;
mysql -u root zm -e &amp;quot;Update Config set Value = &amp;#039;-5&amp;#039; where Name = &amp;#039;ZM_LOG_LEVEL_WEBLOG&amp;#039;;&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And restart zm.&lt;br /&gt;
&lt;br /&gt;
===Set all video lengths to be 1 hour===&lt;br /&gt;
 UPDATE Monitors SET SectionLength = &amp;quot;3600&amp;quot; where SectionLength = &amp;quot;600&amp;quot;;&lt;br /&gt;
When in record/mocord, this can be useful for smaller setups, or where you want to limit the number of videos created. It can, however&lt;br /&gt;
make finding motion events more difficult, so it is not ideal for all scenarios. You might do this in a situation where you have two monitors for a camera, one with modect, and one with record (in a small setup), with the record camera having 1 hour videos.&lt;br /&gt;
&lt;br /&gt;
===Set AlarmMaxFrame to 3===&lt;br /&gt;
From [[Understanding_ZoneMinder%27s_Zoning_system_for_Dummies]]:&lt;br /&gt;
 update zm.Monitors set AlarmFrameCount=&amp;quot;3&amp;quot; where AlarmFrameCount=&amp;quot;1&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
The default value is 1. This may avoid glitches causing alarms (camera feed errors can cause a blank screen for 1 frame).&lt;br /&gt;
===Search the Config table for an Option===&lt;br /&gt;
All items in the &amp;#039;Option&amp;#039; menu of the website are stored in the config table. This table has over two hundred entries. It&amp;#039;s not easy to find a particular setting. While you can run MySQL from shell and export to a file, here&amp;#039;s a way to do it within SQL. Say for example you wanted to search for the timezone setting (reference:https://forums.zoneminder.com/posting.php?t=33626)&lt;br /&gt;
 select * from Config where Name like &amp;#039;%time%&amp;#039;\G&lt;br /&gt;
Here the percentage sign serves as a wildcard, meaning that the string (not case sensitive) time will appear somewhere within the Name field.&lt;br /&gt;
===Update Zone Count on the Console if Zone Count is Incorrect===&lt;br /&gt;
 Update Monitors set ZoneCount=(SELECT COUNT(*) FROM Zones WHERE MonitorId=Monitors.Id);&lt;br /&gt;
This is a good demonstration of updating one field in SQL from the count of the rows of another table. &lt;br /&gt;
&lt;br /&gt;
From: https://forums.zoneminder.com/viewtopic.php?p=137027&lt;br /&gt;
&lt;br /&gt;
===Print the Last 50 Times from a Camera Monitor===&lt;br /&gt;
 mysql -u root zm -e &amp;quot;select StartDateTime from Events_Week where MonitorID=&amp;quot;1&amp;quot; Limit 50\G&amp;quot; | grep -v row | cut -c 15-40&lt;br /&gt;
This might be used in e.g. a weekly email to make sure that your camera is not dropping out. Adjust MonitorID and Limit as needed. Tested in 1.36.&lt;br /&gt;
&lt;br /&gt;
==Optimization==&lt;br /&gt;
&lt;br /&gt;
===MySQLTuner===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqltuner&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then read the output, and perform any recommended database tweaks.&lt;br /&gt;
&lt;br /&gt;
===Other===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysqlcheck -u root -p --optimize --databases zm&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will attempt to optimize your databases. Functions are limited with InnoDB format, however.&lt;br /&gt;
 mytop&lt;br /&gt;
Will list active connections, similar to top or htop. ? will list options. Of particular interest, is V to display all mysql/mariadb variables.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
===API Can&amp;#039;t Connect===&lt;br /&gt;
&lt;br /&gt;
If you change the DB password from the default, the API CakePHP config files will need&lt;br /&gt;
to have their password changed as well.&lt;br /&gt;
&lt;br /&gt;
===IBData files Large===&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder 1.28, I had an issue with the ibdata1 file in /var/lib/mysql/ growing too large. It includes some database information and in my 10GB root partition, was taking up 8GB. This was because the DB was not in InnoDB format. Zoneminder 1.32 and newer, defaults to InnoDB, and this section can be ignored.&lt;br /&gt;
&lt;br /&gt;
The solutions I found were:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;backup zm database, delete zm db, delete ibdata file, then restore database&amp;#039;&amp;#039; [http://stackoverflow.com/questions/3456159/how-to-shrink-purge-ibdata1-file-in-mysql  How to Shrink/Purge Ibdata1 file]&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Move the ibdata file to another partition&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
OR&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;Change DB type to InnoDB (requires backup, deletion, and restoring db, per first solution)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Changing the database type to have an innodb file per each table as mentioned in the &amp;quot;how to shrink purge ibdata1 file in mysql&amp;quot; link will keep less data used in the ibdata1 file in the future, allowing the former to be deleted when not needed. On the other hand the ibdata file by default, will not shrink, ever. This may not be an issue in MariaDB.&lt;br /&gt;
&lt;br /&gt;
Looking for the least invasive procedure, I went with moving /var/lib/mysql, and adding the optional my.cnf parameter. This required the following tricks (may only apply to Ubuntu 14.04).&lt;br /&gt;
&lt;br /&gt;
There are a number of guides on moving Mysql, yet many of them omit adding the alias to apparmors settings. This is required. Failing to do so will result in &amp;quot;Job failed to start&amp;quot; when mysql is run with &amp;lt;code&amp;gt;#service mysql start&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A guide that covers all the steps required to move mysql on Ubuntu Trusty without omitting anything is here: [http://askubuntu.com/questions/137424/moving-mysql-datadir  Ask Ubuntu: Moving Mysql datadir]&lt;br /&gt;
Note that within my mysql installation there was no socket file in /var/lib or in my.cnf.&lt;br /&gt;
&lt;br /&gt;
After moving the Data directory, I ended up backing up the zm db and restoring it anyways, in order to get the ibdata files to split correctly. This is not hard to do. The only DB you need to mysqldump from a stock ZM installation is the ZM db. And it&amp;#039;s also the only DB you need restore.&lt;br /&gt;
&lt;br /&gt;
For a full walkthrough on converting a MyISAM DB to InnoDB  (also covers backing up ZM DB) see [https://wiki.zoneminder.com/Enable_and_convert_MySQL_to_innodb_file_per_table_for_Zoneminder Enable and convert MySQL to innodb file per table for Zoneminder].&lt;br /&gt;
&lt;br /&gt;
===MySQL server has gone away error with ZMTrigger===&lt;br /&gt;
See [[ZMTrigger#MySQL_server_has_gone_away_error]]&lt;br /&gt;
&lt;br /&gt;
===MySQL Out Of Memory===&lt;br /&gt;
If you have recently added more cameras (especially higher resolution and framerate) and you find that periodically ZM is crashing, it may be caused by MySQL running out of RAM. As an example, I have 26 cameras, ranging from 1024x720 to SD analog resolution with framerates of 3 for the HD, and 5 for the SD. This is running under 8GB of RAM. If I add two more 1024x720 cameras with a higher framerate of 5 or 6 (and double the ZMA/ZMC CPU usage)  my server will periodically run out of memory and crash. Now, it&amp;#039;s important to note that the memory doesn&amp;#039;t run out immediately - instead, over a period of an hour or 30 minutes, or two hours (or more), the RAM will become overloaded and begin swapping, at which point there is a user mode crash from numerous programs. The lesson to all of this, is to beware of overloading a system. You may need more powerful hardware. Or split the load over multiple servers.&lt;br /&gt;
&lt;br /&gt;
===Forgot Root Password for MySQL===&lt;br /&gt;
dpkg-reconfigure mysql-server-#.# works in older Debian releases, but not as of Bullseye. &lt;br /&gt;
&lt;br /&gt;
Other options:&lt;br /&gt;
https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/7534056/mysql-root-password-change&lt;br /&gt;
&lt;br /&gt;
===Forgot Admin Password for Zoneminder===&lt;br /&gt;
&lt;br /&gt;
There are different ways to resolve this. The easiest method, is probably option 3.&lt;br /&gt;
&lt;br /&gt;
* Option 1: black out password&lt;br /&gt;
If this happens, blank out the password for admin, and you should be able to login with a blank password.&lt;br /&gt;
&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
Here is a hash (1.37) for the the word password instead of it being blank:&lt;br /&gt;
 mysql -u root -p -e &amp;#039;update Users set Password = &amp;quot;$2y$10$4Hg40fdwsq.DhiSPSRRAA.NONOj0mJK4yYMvFmL14T1IVJpsNhy2.&amp;quot; where Username = &amp;quot;admin&amp;quot;;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
ref: https://forums.zoneminder.com/viewtopic.php?f=5&amp;amp;t=14543&lt;br /&gt;
&lt;br /&gt;
Alternatively you can add a new password to the ZM DB. Note that mysql passwords for ZM must be encrypted. You can&amp;#039;t just query add a new plaintext password. The following should work with mariaDB, and mysql &amp;lt; 8.0.11 (untested). You may also need to run zmupdate.pl -f (passwords on 1.34+ are encrypted with bcrypt and this will use perl libraries to encrypt the password if it is not. To explain this clearly, what you do is enter a plaintext password, and then run zmupdate.pl which will encrypt it for you.&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;MariaDB&amp;#039;&amp;#039;&amp;#039; [zm]&amp;gt; update Users set Password=PASSWORD(NewPassword) where Username=&amp;quot;David&amp;quot;; &lt;br /&gt;
&lt;br /&gt;
Reference: [https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_password  Mysql Reference Docs 8 : Password Function Deprecated]&lt;br /&gt;
&lt;br /&gt;
* Option 2: Delete DB and restore from backup. &lt;br /&gt;
&lt;br /&gt;
* Option 3: Turn off Auth, fix, turn auth on&lt;br /&gt;
From the forums.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Best bet is to turn off auth, use UI to change admin password, turn auth back on.&lt;br /&gt;
&lt;br /&gt;
So to turn if off use mysql&lt;br /&gt;
&lt;br /&gt;
mysql -u zmuser -p zm&lt;br /&gt;
UPDATE Config set Value=0 where Name=&amp;#039;ZM_OPT_USE_AUTH&amp;#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Manually Update MySQL if zmupdate.pl fails===&lt;br /&gt;
This shouldn&amp;#039;t be required but for reference (from: https://forums.zoneminder.com/viewtopic.php?p=131434#p131434)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mysql -u root &lt;br /&gt;
  use zm&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.16.sql&lt;br /&gt;
  source /usr/share/zoneminder/db/zm_update-1.36.18.sql&lt;br /&gt;
  quit&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Where you would substitute the source entries for whichever updates you need.&lt;br /&gt;
===Corrupt Database Rebuild===&lt;br /&gt;
For example with an &amp;quot;[ERROR] InnoDB: Missing FILE_CHECKPOINT at ########## between the checkpoint ########## and the end&amp;quot; error&lt;br /&gt;
This error happens for me with a larger ZM setup that suffers an abrupt power loss. (It does not occur with smaller deployments, i.e. 4 cameras I don&amp;#039;t see this error, but I see it with 40 cameras.) Or sometimes the&lt;br /&gt;
database will corrupt itself when shutting down. What happens is that&lt;br /&gt;
mysql will fail to start. And if you run it in debug mode with &amp;#039;&amp;#039;&amp;#039;mysqld --verbose&amp;#039;&amp;#039;&amp;#039; it may give the &lt;br /&gt;
error message above as the first reason why it won&amp;#039;t start. &lt;br /&gt;
&lt;br /&gt;
The official steps to resolve this, are to start the db in innodb recovery mode, dump the full database, delete all&lt;br /&gt;
files from /var/lib/mysql except for the mysql folder (careful!), start mysql again, then recreate zm and restore&lt;br /&gt;
the dump. There is a chance that dumping the database can fail, so you will want to have other db backups available.&lt;br /&gt;
You should have a cron script that regularly backs up at least the config.&lt;br /&gt;
&lt;br /&gt;
reference: https://dba.stackexchange.com/questions/317572/mariadb-missing-file-checkpoint&lt;br /&gt;
&lt;br /&gt;
However, I&amp;#039;ve not been able to repair the database in innodb recovery mode. Therefore, I restore from a config only backup.&lt;br /&gt;
The downside of this, is that you will lose events. Otherwise, it&amp;#039;s easy to get the system backup and &lt;br /&gt;
running.&lt;br /&gt;
&lt;br /&gt;
Here is a script for Debian for this (assuming you can&amp;#039;t repair the database). It is recommended you run this manually as things can easily break. Run through each step one at a time (or in blocks).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Please pass the backup file as the first argument to this script.&lt;br /&gt;
# The file should contain the string .sql&lt;br /&gt;
sleep 5&lt;br /&gt;
#note that this script assumes you are using the default mysql location for Debian. /var/lib/mysql/&lt;br /&gt;
&lt;br /&gt;
#if database not passed to script, then exit&lt;br /&gt;
echo $1 | grep .sql&lt;br /&gt;
if test $? -ne 0 ;&lt;br /&gt;
then&lt;br /&gt;
echo &amp;quot;Please pass a file containing .sql to the script&amp;quot;&lt;br /&gt;
echo &amp;quot;Exiting&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Repairing mysql.&amp;quot;&lt;br /&gt;
/etc/init.d/zoneminder stop&lt;br /&gt;
/etc/init.d/mysql stop&lt;br /&gt;
cp -r /var/lib/mysql/mysql /tmp/mysql_backup&lt;br /&gt;
mv /var/lib/mysql/mysql /tmp/.&lt;br /&gt;
rm -rf /var/lib/mysql/*&lt;br /&gt;
cp -r /tmp/mysql /var/lib/mysql/.&lt;br /&gt;
chown -R mysql:mysql /var/lib/mysql/*&lt;br /&gt;
/etc/init.d/mysql start&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Restoring database from backup file&amp;quot;&lt;br /&gt;
sleep 5&lt;br /&gt;
mysql -u root  -e &amp;quot;create database zm;&amp;quot;&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; /usr/share/zoneminder/db/zm_create.sql&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  zm &amp;lt; $1&lt;br /&gt;
sleep 2&lt;br /&gt;
mysql -u root  -e &amp;quot;grant all on zm.* to &amp;#039;zmuser&amp;#039;@localhost identified by &amp;#039;zmpass&amp;#039;;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
echo &amp;quot;Cleaning up orphaned filesystem movie files&amp;quot;&lt;br /&gt;
zmaudit.pl&lt;br /&gt;
echo &amp;quot;Starting Apache&amp;quot;&lt;br /&gt;
/etc/init.d/apache2 restart&lt;br /&gt;
echo &amp;quot;Restore done. Please double check everything is working.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 todo:&lt;br /&gt;
  add date and time to /tmp/mysql move&lt;br /&gt;
  add variable for the database location&lt;br /&gt;
&lt;br /&gt;
===Logging MySQL to RAM===&lt;br /&gt;
&lt;br /&gt;
With Zoneminder, the mysql logs will cause a lot of disc writes, so it is probably wise to log to RAM (/dev/shm). For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mysqld]&lt;br /&gt;
log_error        = /dev/shm/error.log&lt;br /&gt;
general_log_file = /dev/shm/mysql.log&lt;br /&gt;
general_log      = 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
These can be rotated with the instructions here: https://dev.mysql.com/doc/refman/8.4/en/log-file-maintenance.html&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [http://zoneminder.blogspot.co.id/p/blog-page_19.html Zoneminder Blogspot]&lt;br /&gt;
&lt;br /&gt;
* [http://mysql.rjweb.org/doc.php/memory rjweb.org mysql docs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17844</id>
		<title>Dummies Guide</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Dummies_Guide&amp;diff=17844"/>
		<updated>2025-12-23T14:25:48Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a lot of what I know about surveillance cameras and ZM.&lt;br /&gt;
&lt;br /&gt;
If you wish to view the full ZM Documentation, I recommend viewing it through the PDF view, as the sphinx website is not efficient and requires javascript. https://zoneminder.readthedocs.io/en/stable/&lt;br /&gt;
If you want a hard copy, you can order the documentation through a self publishing service like lulu.com&lt;br /&gt;
&lt;br /&gt;
Zoneminder is a powerful tool, but it has a learning curve. The forums are there to answer questions. Search then post if its not already answered.&lt;br /&gt;
&lt;br /&gt;
On the learning curve: It can be some work (depending on how complex your system is), but you will become a proficient gnulinux sysadmin if you familiarize yourself with ZM and its many features. If you buy an off the shelf DVR you won&amp;#039;t learn nearly as much (if anything). Additionally, these skills are valuable for &amp;#039;any&amp;#039; Unix-based server (DB, website, email server, kiosk, etc).&lt;br /&gt;
&lt;br /&gt;
If you are already knowledgeable about unix based computers, then you shouldn&amp;#039;t have any trouble.&lt;br /&gt;
&lt;br /&gt;
==Install==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use the install guides provided by Bbunge on the wiki:&lt;br /&gt;
[https://wiki.zoneminder.com/Contents#Installation_Procedure Zoneminder Wiki: Contents]&lt;br /&gt;
These are the best supported install guides.&lt;br /&gt;
&lt;br /&gt;
[[Debian]] is recommended. Ubuntu always has problems with updates.&lt;br /&gt;
&lt;br /&gt;
Even numbers are stable. Use those. Odd numbers are testing/development. &lt;br /&gt;
&lt;br /&gt;
Here&amp;#039;s a guide for using an external HDD: [https://wiki.zoneminder.com/Using_a_dedicated_Hard_Drive Using a dedicated Hard Drive]&lt;br /&gt;
&lt;br /&gt;
==Test out a Camera==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you get ZM installed, you will want to test out a camera.&lt;br /&gt;
You can do a webcam, or you can do an IP camera. &lt;br /&gt;
See the [[Hardware_Compatibility_List]]&lt;br /&gt;
&lt;br /&gt;
I recommend you start with an early [[Axis]]. They are well documented and easy to setup. &lt;br /&gt;
Old ones go for $10-20. Follow the instructions on either the Zoneminder Hardware compatibility list,&lt;br /&gt;
on ispyconnect&amp;#039;s url list, or in the user manual for the camera. Any respectable camera will document it&amp;#039;s RTSP and MJPEG / JPG paths for you to access. ONVIF is also an option to find the path for RTSP cameras. This is covered in more detail in [[Finding Camera Stream Paths]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the instructions in the Hardware Compatibility List for parameters&lt;br /&gt;
for setting up a camera the first time. If you have an error, look at the logs. FFMPEG and VLC can be used to test that the streams are valid. e.g. from terminal: ffmpeg -i rtsp://username:password@&amp;lt;ipaddress&amp;gt;:554/path output.mp4 This is faster than using ZM.&lt;br /&gt;
&lt;br /&gt;
In ZM, IP address, path, port, and Resolution must be correct. Most other fields can be left at defaults.&lt;br /&gt;
&lt;br /&gt;
Use vlc or ffplay like this:&lt;br /&gt;
 ffplay http://192.168.1.5/mjpg/video.mjpg&lt;br /&gt;
 or ffmpeg&lt;br /&gt;
 ffmpeg -i http://192.168.1.5/mjpg/video.mjpg output.mp4&lt;br /&gt;
 or&lt;br /&gt;
 ffplay rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&amp;amp;resolution=320x240&lt;br /&gt;
 or &lt;br /&gt;
 ffprobe rtsp://&amp;lt;user&amp;gt;:&amp;lt;pass&amp;gt;@&amp;lt;hostname/ip&amp;gt;:554/axis-media/media.amp?videocodec=h264&lt;br /&gt;
If the camera requires authorization, consult the user manual, or you can try adding the username and password before the ip like so username:password@ipaddress This is an alternative to 192.168.1.5?username=root&amp;amp;pwd=mypass which most guides tell you to do. Both will work, however the former is easier.&lt;br /&gt;
&lt;br /&gt;
If pass is blank, you type in root:@192.168.1.5&lt;br /&gt;
&lt;br /&gt;
RTSP usually specifies the port and uses rtsp, instead of http. e.g. &amp;lt;code&amp;gt;rtsp://user:password@192.168.1.10:554/somepath&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obtaining more Cameras==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ZoneMinder, when you add a camera, you have a few options: &lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;LOCAL&amp;#039;&amp;#039;&amp;#039; Camera connected directly to computer (webcam, or analog camera thorugh bttv card)(typically /dev/video0)&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;REMOTE&amp;#039;&amp;#039;&amp;#039; (obsolete) Precursor to ffmpeg. &lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FILE&amp;#039;&amp;#039;&amp;#039; Grab a jpg file somewhere locally and display that (you provide images that change from anywhere on the filesystem). Can be used in unusual ways (i.e. a slide show, &amp;lt;insert use here&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;LIBVLC&amp;#039;&amp;#039;&amp;#039; use the respective libraries to pull a stream similar to REMOTE does for RTSP only. They can also watch MJPEG streams and the former can loop local video files.&lt;br /&gt;
&lt;br /&gt;
And some others...&lt;br /&gt;
&lt;br /&gt;
FFMPEG / LibVLC is recommended. Don&amp;#039;t confuse [[LibVNC]] with LibVLC. LibVNC is for recording VNC (i.e. screenrecording).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;FFMPEG&amp;#039;&amp;#039;&amp;#039; has the option of RTSP (h264) or MJPEG streams. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MJPEG===&lt;br /&gt;
Older cameras from 2000&amp;#039;s. E.g.[[Arecont Vision]], [[Axis]], Bosch, [[Foscam]], [[Grandstream]], Instar, Messoa, Zavio and others. &lt;br /&gt;
The prices scale with features. Old indoor Axis cameras at 480p-720p resolution (no IR) can be found&lt;br /&gt;
online easily for $10-30. These are generally obsolete.&lt;br /&gt;
&lt;br /&gt;
===RTSP===&lt;br /&gt;
2010&amp;#039;s and newer cameras: These cameras use h264 (or h265) compression. They serve it on an RTSP server. h264 means less bytes, so you end up using less HDD space than compared with MJPEG. H264 is recommended when possible.&lt;br /&gt;
&lt;br /&gt;
Note: Users with 1.32+ can use &amp;#039;&amp;#039;&amp;#039;H264 passthrough&amp;#039;&amp;#039;&amp;#039;, which writes the h264 direct to mp4, and saves some CPU usage. .&lt;br /&gt;
&lt;br /&gt;
===How Powerful of a Computer to Use===&lt;br /&gt;
&lt;br /&gt;
High-end server hardware will perform better than desktop, or low end server hardware. I have seen this firsthand between two servers: KFSN4-DRE and the KGPE-D16.  The latter runs ZM with 25+ cameras, not breaking a sweat. The former reaches a limit at about 10. Another limitation is HDD size. &lt;br /&gt;
&lt;br /&gt;
I currently recommend buying Axis (new is expensive, so you&amp;#039;ll probably purchase used), although many do not have IR. This is not a problem, as outdoors IR on cameras attracts spider webs, and external IR is recommended. Another recommended brand is Hikvision. Hikvision can be bought new for a lower price if warranty is an issue (for business clients that can&amp;#039;t afford Axis). The cameras work well with ZM, and are configurable without Windows, Otherwise, any respectable name brand camera will work. Look through the hardware compatibility list. Read the user manual before you purchase the camera, and look for the following: Outdoors/indoors, IR/no-IR, Resolution. IR can be supplemented with external appliances. You can also put pesticide on the cameras to deter bugs... (although I wouldn&amp;#039;t).&lt;br /&gt;
&lt;br /&gt;
=== A note on Analog Cameras ===&lt;br /&gt;
&lt;br /&gt;
There is an option to use a coax to ethernet adapter. You need two pieces. One is the sender, one is the receiver. They may or may not be identical. These allow the use of IP Cameras over coax. Search ebay. Altronix ebridge ones are about $120 for a pair or adapters (you need a pair for each camera). If this is too much money, you may keep the old coax cameras. See: IP Video Encoders [https://wiki.zoneminder.com/Hardware_Compatibility_List#IP_Video_Encoder]. Honestly, just run ethernet if you have a chance. Customers expect HD these days. &lt;br /&gt;
&lt;br /&gt;
I have not worked with HD analog over coax, and I don&amp;#039;t recommend it. I did try to keep old coax cameras but they became obsolete. IP cameras are the way to go.&lt;br /&gt;
&lt;br /&gt;
==Watching the Cameras==&lt;br /&gt;
&lt;br /&gt;
Cameras can be watched from the ZM apache server website and/or ZMNinja.&lt;br /&gt;
&lt;br /&gt;
For business customers offer both choices to the customer. Or build something custom if you like. HTML imagemaps work well.&lt;br /&gt;
&lt;br /&gt;
You can make fully customizable pages i.e. make an html file on a remote machine with the following code embedded in an img tag. Adjust monitor ID as needed.&lt;br /&gt;
[https://wiki.zoneminder.com/How_to_stream_from_another_ZoneMinder_installation   How to stream from another ZoneMinder installation]. Also an easy way to embed video in a website (img tag). See [[Dedicated SBC Camera Monitor]] for an example of a computer that only displays the streams. [[https://wiki.zoneminder.com/Example_Camera_View_HTML]] has the HTML code for API/non-API usage.&lt;br /&gt;
&lt;br /&gt;
If you embed the URL in an img tag, include http prefix or it wont work.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
img width=&amp;quot;500px&amp;quot; height=&amp;quot;500px&amp;quot; src=&amp;quot;http://zmserveripaddress/zm/cgi-bin/nph-zms?mode=jpeg&amp;amp;monitor=#&amp;amp;scale=100&amp;amp;maxfps=5&amp;amp;user=username&amp;amp;pass=password&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call it locally:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
firefox file:///home/username/file.html&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you have &amp;gt; 6 cameras, you can either use firefox and edit about:config (explained below in guide), or see&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=28168&amp;amp;p=113934#p113934&lt;br /&gt;
for instructions regarding multi port. &lt;br /&gt;
&lt;br /&gt;
Watch the scale parameter. That can be adjusted for clients with low power CPUs (ARM SBCs) if whole img boxes seem to drop out. Note that scale does require some CPU on the server side.&lt;br /&gt;
&lt;br /&gt;
One note: If you have alternative high/low resolution cameras (motion detect on the low res, record on the high res). You might not want customers to view the low res cameras. In this case, make a group of the high res cameras, and set that to be the default view.&lt;br /&gt;
&lt;br /&gt;
=== Daily Video Compilations ===&lt;br /&gt;
Watching videos is better on VLC, mplayer, or mpv, as opposed to the bloated web browsers. Recommended.&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135958#p135958&lt;br /&gt;
&lt;br /&gt;
Another approach:&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?t=34045&lt;br /&gt;
&lt;br /&gt;
=== Embedding ZM in a webpage ===&lt;br /&gt;
&lt;br /&gt;
[[Example Camera View HTML]]&lt;br /&gt;
&lt;br /&gt;
[https://forums.zoneminder.com/viewtopic.php?f=37&amp;amp;t=26982 Embedding Streaming Video in External Website] from Forums&lt;br /&gt;
&lt;br /&gt;
https://wiki.zoneminder.com/External_Live_Stream#Imagemap_of_Cameras - Highly recommended for medium / large installations.&lt;br /&gt;
&lt;br /&gt;
==Monitor Settings in Zoneminder==&lt;br /&gt;
The zmc binary handles recording and analysis (1.36).&lt;br /&gt;
&lt;br /&gt;
    * use full res stream as the source&lt;br /&gt;
    * set camera in zm to use passthrough (not decode) (must be h264, not h265).&lt;br /&gt;
    * set resolution in zm to be lower than the actual stream. if you have a 2,3,or 4K stream, &lt;br /&gt;
      set it to somewhere around 320x240 or 640x480. Note that it must be the same aspect ratio (so &lt;br /&gt;
      some fraction of the original stream, e.g. 1920x1080 would be 480x270).&lt;br /&gt;
    * set analysis fps to 2&lt;br /&gt;
    * mode can be modect or mocord. I prefer modect with some exceptions.&lt;br /&gt;
    * set the zone similar to the example zone image below.&lt;br /&gt;
    * set Maximum Image Buffer Size (frames) to 0. (reference: https://forums.zoneminder.com/viewtopic.php?p=137844)&lt;br /&gt;
&lt;br /&gt;
By doing this you will get a low res live view and analysis, but the recorded videos will be full res when watched. This is the easiest way to setup ZM. You can also use linked monitors or have multiple streams, but neither of those options are worth the trouble. Note that there may be a warning in ZM about the stream not matching the resolution but that can be ignored (it is a warning, not an error). This has been discussed on the forums, search there for further details.&lt;br /&gt;
&lt;br /&gt;
https://forums.zoneminder.com/viewtopic.php?f=10&amp;amp;t=31334&amp;amp;p=124410&lt;br /&gt;
&lt;br /&gt;
In ZM 1.32+, you can use multiple HDs (as many as you like), and assign cameras to where they should be saved. These are &amp;#039;&amp;#039;&amp;#039;storage areas&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
==Motion Detection==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;What&amp;#039;s all this motion detection stuff, anyhow?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
The challenge of all surveillance systems lies in its motion detection analysis (thus the &amp;#039;zone&amp;#039; in zoneminder, being the motion detection zones). See: [https://wiki.zoneminder.com/Understanding_ZoneMinder%27s_Zoning_system_for_Dummies  Understanding Zoneminder&amp;#039;s Zoning system for Dummies]. Zones have their gotchas, and you may want to consider ZMES. Like AI, expect 90% but do not ever expect 100%. You will need hardware motion sensors for 100%.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Help, I missed an event!?&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You can re run analysis on old videos with: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=24686 and https://forums.zoneminder.com/viewtopic.php?f=8&amp;amp;t=28013&amp;amp;p=109190   You can re-create videos from your (JPEG ONLY) footage, and then reanalyze them. (those with ffmpeg mp4s created, may need to combine the footage into one video, then make that a video source in zm as file.).&lt;br /&gt;
&lt;br /&gt;
See also: https://forums.zoneminder.com/viewtopic.php?f=11&amp;amp;t=31355 to run zm on files on the server filesystem.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sizing Zones Tip&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;My first thought is the threshold is too low. It happened to me when I &lt;br /&gt;
first started with ZM. I figured out a little trick:&lt;br /&gt;
&lt;br /&gt;
Draw a new zone a little smaller than you appear in the video. The zone &lt;br /&gt;
will tell you the number of pixels or the percent of the whole frame. &lt;br /&gt;
Compare that to the size you have setup to detect. If you are using &lt;br /&gt;
percent try changing to pixels, that will not require the math to adjust &lt;br /&gt;
the percent.&amp;lt;/pre&amp;gt;&lt;br /&gt;
ref: http://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30570&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;I&amp;#039;m still getting false alerts!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
You may want to run [[ZMES]]. It&amp;#039;s not too difficult to setup, but it will require more resources.&lt;br /&gt;
See https://wiki.zoneminder.com/ZMES&lt;br /&gt;
&lt;br /&gt;
====Example Zone====&lt;br /&gt;
[[File:Filters example.png|300px|thumb|right|Basic zone for a 320x240 stream that won&amp;#039;t miss events. Though it will still detect false ones without ZMES.]]&lt;br /&gt;
Start out with Best, High Sensitivity. Change to pixels instead of percent, and start around 500 (or even 200 depending on whether you are around 640x480 or 320x240). This is a good start, but it may still require [[ZMES]]. For bounding boxes, you should try to use rectangles or squares. I believe someone in the forum mentioned this will save on calculation of the CPU, but regardless, it just looks better. Use the boxes in the bottom to line up X and Y appropriately. See image.&lt;br /&gt;
&lt;br /&gt;
===Zone Tips===&lt;br /&gt;
&lt;br /&gt;
* Zones should be as small as possible, and you should use as few zones per monitor, to lower CPU usage. &lt;br /&gt;
* Analysis FPS can be limited to 2 FPS to lower CPU usage. &amp;#039;&amp;#039;&amp;#039;IMPORTANT&amp;#039;&amp;#039;&amp;#039; (do not limit Max FPS, only analysis).&lt;br /&gt;
* Aggressive Modect usage can run into issues with [[PurgeWhenFull]] &lt;br /&gt;
* Transitions from [https://forums.zoneminder.com/viewtopic.php?f=36&amp;amp;t=27141 daylight to IR] cause false alarms. The solution is to &amp;quot;Set a max alarmed area so it doesn&amp;#039;t alarm if the whole area is changing&amp;quot; or use ZMES. &lt;br /&gt;
* You can use external hardware motion sensors via [[ZMTrigger]] over modect, when high reliability / low false alarms is required. More setup cost / time though.&lt;br /&gt;
* JPEG saving, should be avoided on H264 streams when possible. Use H264 passthrough. Consider how decoding the H264 stream to JPEG uses CPU, while passthrough will avoid this conversion step.&lt;br /&gt;
* From forum: &amp;quot;In zones, switch to pixels, reduce minimum area/pixels/blobs etc to less than 1000. I find either 500 or 1000 works well.&amp;quot; Note that this is often used with Blobs (start with the Best most sensitive defaults).&lt;br /&gt;
* From forum: &amp;quot;My trick is to find a person sized object in the frame and draw a tight zone around it. The zone properties will tell me the pixel count. I delete the test zone and set the detection size to the same pixel count as the test box. Once that is done, I adjust up or down as needed, but those adjustments are usually small.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Hardware Advice==&lt;br /&gt;
&lt;br /&gt;
When setting up the cameras, here is some advice.&lt;br /&gt;
* Don&amp;#039;t do anything but 802.3af POE. Passive POE is more trouble than its worth. There are 5/8 port POE switches, use those.&lt;br /&gt;
* If you purchase axis cameras, be aware that the cameras are 5V and the barrel plug is 4.0mm x 1.7mm. It&amp;#039;s easiest to use POE on these (and all cameras actually).&lt;br /&gt;
* Installing areas where the temperature is high may cause early camera failure (especially for cheaper cameras). Camera modules can be damaged by direct sunlight (UV and other radiation). Heat is less of an issue with newer cameras, as well as Outdoor rated cameras. But I would recommend not pointing cameras directly at the sun, or where it will get a lot of direct sunlight into the actual camera view. At least, point the camera towards the ground, not towards the sky. Direct sunlight on the outside of a camera case, is of course, OK.&lt;br /&gt;
* See the forum and the Hardware Queries sub board https://forums.zoneminder.com/viewforum.php?f=14 where there are a number of threads on what server to purchase. The general concensus is that more cores is better. But you should size appropriately for your location. A home setup of 4 cameras (average) doesn&amp;#039;t need much. Beware of old servers that are dinosaur sized huge. Either towers or server rack servers can be used. Check sound specifications if it&amp;#039;s going to go where people will be working (make sure adjustable speed on the fans works, or that people don&amp;#039;t report the server as &amp;#039;loud&amp;#039;. This is generally not an issue, but it&amp;#039;s something to be aware of). See: https://wiki.zoneminder.com/Dummies_Guide#How_Powerful_of_a_Computer_to_Use&lt;br /&gt;
* For servers, get one with JBOD / HBA support. Not just a RAID. It will be easier to repair the physical disk if you don&amp;#039;t have to reboot, just to remount it. A mistake would be to buy an old used Dell with a PERC that doesn&amp;#039;t support HBA/JBOD (newer ones are a bit better, see links). In which case any hdd corruption requires re-importing the foreign disk back into the RAID through the menus after a full reboot. This is if you are only using the HDDs in RAID 0 configuration (which is good enough for a camera server of my 32 or so cameras, which I run). Another related problem, is that you won&amp;#039;t be able to import RAID discs into another computer (maybe it&amp;#039;s technically possible but probably of high difficulty. See: https://serverfault.com/questions/61823/moving-a-raid-array-from-one-machine-to-another). Search online regarding this before buying, it seems to be well documented in the FreeNAS / TrueNAS community e.g. https://www.truenas.com/community/threads/jbod-controller-for-dell-r720-and-freenas.46895/ https://techmikeny.com/blogs/techtalk/techmike-s-dell-poweredge-raid-card-perc-guide-with-nomenclature-decoder-ring.&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Watch logs.&lt;br /&gt;
&lt;br /&gt;
* Use forum search.&lt;br /&gt;
&lt;br /&gt;
* Use web search.&lt;br /&gt;
&lt;br /&gt;
* Enable component logs and navigate to /var/log/zm/.&lt;br /&gt;
&lt;br /&gt;
* Enable debug logs on a part of ZM, and set path to /var/log/zm/zm_element_debug+ (note you must set the path to /var/log/zm or it will put the debug files in the root home folder.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# tail -F /var/log/syslog&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;# multitail -du -s 5 /var/log/zm/*&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Beware of underlying hardware faults such as bad RAM.&lt;br /&gt;
&lt;br /&gt;
* Disable logs after you are done.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Some cams will have two video streams (e.g. Hikvision, Amcrest). The resolutions/video type may or may not be the same. For example, there may be a low resolution mjpeg stream, and a high resolution RTSP stream. Read the data sheet / user manual for cameras you intend to purchase. Multiple streams are desirable. On Axis cameras, you can specify the resolution at the end of the path, e.g. &amp;amp;resolution=320x240, (certain model) Foscams have videoMain, and videoSub. There are different variations. One Hikvision I used had 3 streams.&lt;br /&gt;
&lt;br /&gt;
* I found it helpful to include monitor ID in camera names, as you run into monitor ID in logs often.&lt;br /&gt;
&lt;br /&gt;
* Proprietary cameras are known to report to outside IPs. Don&amp;#039;t give them internet access. Only the server should be wan-accessible. Make a separate network. If you can&amp;#039;t make a truly air-gapped separate network, you can do a separate subnet for the cameras as discussed here: https://askubuntu.com/questions/474298/multiple-ips-on-different-subnets-on-one-interface  With this setup, you will have cameras that have no internet access, and additionally most malware on the network that might try to find cameras will likely fail. You can also of course use VLANs, but this requires the proper equipment which costs money (and requires more administration overhead).&lt;br /&gt;
&lt;br /&gt;
* Many cameras have default telnet passwords, in addition to the default web access passwords. Change these or keep cameras away from the wan. Cameras are common botnet targets.&lt;br /&gt;
&lt;br /&gt;
* With server motherboard hardware, you will be able to have more cameras (servers are more powerful, and better servers will have better performance). In practical terms, this means you want a Xeon processor not an i5,i7, or the equivalent AMD server vs. consumer AMD CPUs. You will also want to purchase one with more cores. How many cores will depend upon how many cameras you are monitoring.&lt;br /&gt;
&lt;br /&gt;
* I use ext4 filesystem for the HDDs. I had tried using the ext2 filesystem for possibly better performance, but the fsck time is prohibitively slow for ext2 (&amp;gt;24 hours for &amp;gt;2TB). Ext4 seems to work well. Older ext2, or ext3 fs can be upgraded to ext4. Other filesystems are generally, not recommended. Ext4 works fine. There is some discussion on filesystems on the forum, and the general consensus is to use ext4.&lt;br /&gt;
&lt;br /&gt;
* If you have more than 6 cameras you may want to edit about:config in FF or setup multi-port. See: https://medium.com/zmninja/multi-port-storage-areas-and-more-d5836a336c93    Note: article written by zm dev. [[Multi_Port]] has both multi port instructions and the about:config edits for FF.&lt;br /&gt;
&lt;br /&gt;
* Edit /etc/default/rcS (applies to Debian based distributions) and make sure auto FSCK is enabled. Failure to set this, will require manual intervention when the server is repairing the filesystem, requiring you to press a key.&lt;br /&gt;
&lt;br /&gt;
* Make sure the BIOS is set to power on after power fails. Or use a UPS. There is a list of UPS compatibility (hcl) here: https://networkupstools.org/stable-hcl.html Eaton has good support.&lt;br /&gt;
&lt;br /&gt;
* Don&amp;#039;t set a Max FPS limit on REMOTE or FFMPEG, or VLC cameras in Zoneminder. The FPS should only to be set at the IP camera itself. Max FPS limiting is for LOCAL cameras, or LibVNC, only.&lt;br /&gt;
&lt;br /&gt;
* Do NOT point cameras at contrasting and bright light, such as facing a window, a garage door, the sun, or anything that generates glare. It will blur the image / potentially damage the camera&amp;#039;s image sensor. Some cameras have technology that deals with this, it might be called Wide Dynamic Range. Older cameras will not handle looking out a sun facing window well. &lt;br /&gt;
&lt;br /&gt;
* Buy a set of adapters such as these: to use with your normal 5.5 2.1mm barrel plug. Search multi type 23 or 28 dc power adapter. EDIT: actually only use poe (but picture left as these are useful).&lt;br /&gt;
&lt;br /&gt;
[[File:Universal-28pcs-5-5x2-1mm-Multi-type-Male-Jack-for-DC-Plugs-for-AC-Power-Adapter.jpg 640x640.jpg|thumb|150px|Coaxial barrel plug adaptors||Universal 28pcx Multi type Male Jack for DC Plugs]]&lt;br /&gt;
&lt;br /&gt;
* I made a script to watch cameras that drop out, and disable/re-enable them for my 1.29 setup. See [https://forums.zoneminder.com/viewtopic.php?f=9&amp;amp;t=26909 here]. This also doubles as a notification in case the cameras somehow are powered off. You&amp;#039;ll get emails telling you cameras are down. EDIT: See note about poorly supported cameras above. With good cameras, this does not occur. Rabbit hole warning. Stick with quality name brands.&lt;br /&gt;
&lt;br /&gt;
* If you are setting up mobile phones with ZMNinja, and the wifi is the same WAN IP as the camera system, setup a VPS with a http/https proxy and point zmninja at the proxy. The proxy can be as simple as: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:80&lt;br /&gt;
sudo iptables-legacy -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j &lt;br /&gt;
DNAT --to-destination &amp;lt;officeip&amp;gt;:443&lt;br /&gt;
sudo iptables-legacy -t nat -A POSTROUTING -j MASQUERADE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note that you might want to set nonstandard ports. If you don&amp;#039;t do this, it may be impossible to access ZMNinja from within the LAN (without configuring two ip addresses / and two ZMNinja entries, one for outside of the office, and one for inside). This is a fundamental routing problem, of using the WAN ip to access the cameras, but being in the LAN of said WAN ip.&lt;br /&gt;
&lt;br /&gt;
* Run 2k cameras at least for business customers. People will expect reasonably high resolution.&lt;br /&gt;
&lt;br /&gt;
* The more you overbuild the server / CPU, the more overhead you will have. Performance will also depend upon how you configure ZM.&lt;br /&gt;
&lt;br /&gt;
* Use zmninja + the website. offer customers both apps. there are also some other apps available. (e.g. possibly zmsquarer).&lt;br /&gt;
&lt;br /&gt;
* For old coax cameras, buy a coax to ethernet adapter such as the ebridge series by Altronix. These allow use of an ip camera on a coax link. Though you have to be able to crimp coax well (you need the tools). Ideally, running ethernet is the best option.&lt;br /&gt;
&lt;br /&gt;
*https://forums.zoneminder.com/viewtopic.php?p=130577&amp;amp;hilit=1.37#p130577 See this note about slow playback in ZM &amp;lt; 1.37.&lt;br /&gt;
&lt;br /&gt;
* For numerous camera setups (10+), you will make your life easier if you deploy all the same model of camera or at least the same resolution. This way you can reuse camera settings. You can reuse settings for the low res motion detection, and then also reuse the same pixel area for zones as well (if the resolution is the same).&lt;br /&gt;
&lt;br /&gt;
* Fine tune zones with scripts on zm  https://forums.zoneminder.com/viewtopic.php?t=31355&amp;amp;p=124557#p124557 make 24 hour sequence, and fix ir false alarms&lt;br /&gt;
&lt;br /&gt;
* Always use a cellphone to test the alignment and focus of the camera. It&amp;#039;s easiest to adjust the camera while looking at the live feed.&lt;br /&gt;
&lt;br /&gt;
* Wireguard and remote cameras may need tuning for optimal performance. Or you can bypass VPNs altogether. https://forums.zoneminder.com/viewtopic.php?p=135840&lt;br /&gt;
&lt;br /&gt;
* If you use ZMNinja, and have the API wan accessible, you may want to consider the security hardening listed on [[ZMNinja]].&lt;br /&gt;
&lt;br /&gt;
* Video playback performance will always be better via VLC or mpv as opposed to the ZM web interface. Read: https://wiki.zoneminder.com/Filters#Create_Single_Video_of_Multiple_Events&lt;br /&gt;
&lt;br /&gt;
* Greasemonkey or other browser addons can cause problems on ZM or camera pages. https://forums.zoneminder.com/viewtopic.php?p=135447&lt;br /&gt;
&lt;br /&gt;
* When you setup the network, make administration easier by using DHCP reservations so that cameras are at sequential addresses. E.g. 10 cameras from 192.168.1.80-192.168.1.90.&lt;br /&gt;
&lt;br /&gt;
* Advice on tuning apache for more &amp;#039;workers&amp;#039;: https://forums.zoneminder.com/viewtopic.php?p=136440#p136440&lt;br /&gt;
&lt;br /&gt;
* For large ZM setups, you may want the DB to be on its own hdd/ssd, otherwise you could run into corruption as in the notes section of [[MySQL]].&lt;br /&gt;
&lt;br /&gt;
* For larger setups, consider using multicast on the cameras to avoid bandwidth limitations. Zoneminder also indicates the bandwidth in &amp;gt;=1.34 on the web console. https://learncctv.com/multicast-on-axis-cameras/ &lt;br /&gt;
&lt;br /&gt;
* The trick to having a hundred cameras or more, is that you have to divide up the networks (the ethernet cable can only carry so much traffic), and have multiple ZM servers. So you would run seperate ethernet networks, and have multiple ZM servers.&lt;br /&gt;
&lt;br /&gt;
* If there is a lot of Mocord footage to run through, I find it easier to use Filezilla to download a sequence of videos (i.e. one or two hours worth) to my local machine, then fast forward through them with mpv, VLC, or mplayer.&lt;br /&gt;
&lt;br /&gt;
* CLI usage of the zmu utility: https://forums.zoneminder.com/viewtopic.php?p=137491&lt;br /&gt;
&lt;br /&gt;
[[File:CMB-1B- Universal Camera Mount.jpg|thumb|150px|CMB-1B Universal Camera Mount||Standard Camera Mount. Comes with drop ceiling or wall attachment, anchors, and corrosion resistant screws. ]] &lt;br /&gt;
&lt;br /&gt;
* There is an unwritten standard type of CCTV mount. It is just a 1/4-20 bolt on a set of adjustable metal shafts (i.e. you can remove shafts to get to the desired length). One of the model names is CMB-1B. Search online/ebay. They are likely easy to DIY. Note that you want to install a camera somewhere it won&amp;#039;t need to be re-installed at some future time (i.e. installing on a concrete wall is better than on a wooden roof.)&lt;br /&gt;
&lt;br /&gt;
* Search the 3D Printing repositories for camera accessories, or make your own in FreeCAD. https://www.printables.com/search/models?q=ip+camera&lt;br /&gt;
&lt;br /&gt;
* See about infrared reflective tape https://forums.zoneminder.com/viewtopic.php?p=137768&lt;br /&gt;
&lt;br /&gt;
* See about bitrate affecting storage used by videos https://forums.zoneminder.com/viewtopic.php?p=137767&lt;br /&gt;
&lt;br /&gt;
* I have seen thieves cover themselves up from head to toe. The more light you have, the better you will see perpetrators. You may want to have cameras at eye level, and multiple in a protected room, so that it is difficult for a thief to look away. You will also have better footage of their clothing. What you can do, is setup motion lights, so that they only activate when the light switch is off. With the image matching (Yolo) technologies getting better, it should soon be possible to alert when someone is fully covered up. All cameras operate on light, and infrared loses colour information, so ideally you will have lights that either turn on, or are always on. &lt;br /&gt;
&lt;br /&gt;
* I looked into whether it is possible to track wifi probe request frames on a phone, or the mac address if their phone connects to a AP. This is not possible, as probe request frames do not work as some sources online say (e.g. https://github.com/brangerbriz/wifi-data-safari). It is possible that the cellphone OS developers have changed things. Also mac addresses are now randomized (they were not in the past). This is a setback for security, so it makes it more difficult to identify thieves. This means, you are left with monitoring if the phone connects to the wifi, and if there is a hostname that you recognize.&lt;br /&gt;
&lt;br /&gt;
* You will have to review zones periodically, as it&amp;#039;s possible for things to change. As an example, at an office a new credit card reader was installed which had a light that blinked on it 24/7. This caused unnecessary events at night with modect (due to glare from the LEDs), which also caused ZMES to run in the background, wasting CPU cycles to check the footage. While the incorrect events could be deleted with a filter, it was important to tune the zone, so that the events wouldn&amp;#039;t be created, and would not run ZMES. These false events can end up filling up the hdd, taking up space that otherwise could be used for actual events.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
* [[API]]&lt;br /&gt;
&lt;br /&gt;
* [[Cron]] example&lt;br /&gt;
&lt;br /&gt;
* [[Dedicated SBC Camera Monitor]] Guides for using a Beaglebone Black or Desktop as a client to watch the ZM Server.&lt;br /&gt;
&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
&lt;br /&gt;
* [[External Live Stream]] A quick html file you can deploy on clients to watch the server.&lt;br /&gt;
&lt;br /&gt;
* [[Exporting Videos Hack]] (not recommended)&lt;br /&gt;
&lt;br /&gt;
* [[Filters]] Examples&lt;br /&gt;
&lt;br /&gt;
* [[Finding Camera Stream Paths]]&lt;br /&gt;
&lt;br /&gt;
* [[ffmpeg]] Example usage, and notes.&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/How_to_view_recorded_history_from_show_timeline&lt;br /&gt;
&lt;br /&gt;
* [[LibVNC]] Screen recording in Zoneminder&lt;br /&gt;
&lt;br /&gt;
* [[Multi_Port]] For streaming more than 6 cameras at once to a browser.&lt;br /&gt;
&lt;br /&gt;
* [[MySQL]] can require some optimizing, and there are potential gotchas. Though newer releases of Zoneminder may have resolved some of the issues.&lt;br /&gt;
&lt;br /&gt;
* [[PurgeWhenFull]] requires configuration on larger systems, or systems where events are created at a pace faster than PurgeWhenFull can keep up. Failure to do so, will result in all events being blank, and you will have to fix it.&lt;br /&gt;
&lt;br /&gt;
* [[SMS Notifications]] or email.&lt;br /&gt;
&lt;br /&gt;
* [[Zmodopipe]] Is a tool that can tie an analog DVR system to Zoneminder, although it is far from perfect. I have documented it there, and recommend purchasing a (some #) channel video encoder instead.&lt;br /&gt;
&lt;br /&gt;
* [[ZMNinja]] - General usage, also Geoblocking w/apache.&lt;br /&gt;
&lt;br /&gt;
* [[ZMTrigger]] is a tool that can be used to take outside information and overlay it onto the camera display. For example, you might take the temperature, or wind speed, and overlay it on a camera. It can also be used as external motion detection. Experience with electronics and microcontrollers such as AVRs, Pics, and the Arduino IDE are applicable here.&lt;br /&gt;
&lt;br /&gt;
===Other Users===&lt;br /&gt;
&lt;br /&gt;
* [[How to share an USB camera from a remote ZM server to another ZM Server]]&lt;br /&gt;
&lt;br /&gt;
* [[General Notes]]&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=32&amp;amp;t=23815&amp;amp;hilit=i+run+this+script+every+night Backup DB script (Recommended)&lt;br /&gt;
&lt;br /&gt;
* https://wiki.zoneminder.com/Ubuntu_Install_ZoneMinder_on_Ubuntu_Server Apache Hardening&lt;br /&gt;
&lt;br /&gt;
* https://github.com/lbdc/zm_movie_bootstrap Create timelapse videos (adjust fps) or just export. Terminal or GUI. Good example of a basic ZM hack interfacing with db, and querying video files.&lt;br /&gt;
&lt;br /&gt;
* [[AxisMotionDetection]] - for offloading motion detection on Axis cameras and using ZMTrigger to receive the alerts (will save CPU).&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=131662#p131662 - URL for users to login to.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31005&amp;amp;start=15 - Run cameras at low res, yet using passthrough to get full res with modect on the low res stream and live.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=31355 - Rerun a video through the zones to tune them.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33445 - With large networks, you will need multiple networks and servers.&lt;br /&gt;
&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137894#p137894 - Some notes on a solar system deployment. &lt;br /&gt;
&lt;br /&gt;
[[Category:Dummies_Guide]]&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMES&amp;diff=17839</id>
		<title>ZMES</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMES&amp;diff=17839"/>
		<updated>2025-12-15T14:46:23Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From the github: The Event Notification Server sits along with ZoneMinder and offers real time notifications, support for push notifications as well as Machine Learning powered recognition. As of today, it supports:&lt;br /&gt;
&lt;br /&gt;
    - detection of 80 types of objects (persons, cars, etc.)&lt;br /&gt;
    - face recognition&lt;br /&gt;
    - deep license plate recognition&lt;br /&gt;
&lt;br /&gt;
I will add more algorithms over time.&lt;br /&gt;
Ref: https://github.com/ZoneMinder/zmeventnotification&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In plain terms, why would you want to use ZMES? Because it avoids false positives associated with weather, automobiles, nature, and a number of other factors. ZMES will get motion detection to detect correctly in the 90-99% range. To do this with Zoneminder&amp;#039;s built in motion detection is more difficult. Be warned that while ZMES is good, it is not perfect and there is room for improvement. However, &amp;#039;&amp;#039;&amp;#039;object detection&amp;#039;&amp;#039;&amp;#039; via tools like Yolo is still an emerging field, there is likely to be improvement in the future. &lt;br /&gt;
&lt;br /&gt;
You can also use external scripts (such as https://github.com/pjreddie/darknet or https://github.com/lbdc/zm-alarm) independently from ZM, as well as do custom object detection (search online) for other tasks such as automation, bird watching, insect monitoring, etc... All these scripts need is an image (which is easily obtained from ZM).&lt;br /&gt;
&lt;br /&gt;
== Setup == &lt;br /&gt;
Refer to https://zmeventnotification.readthedocs.io/en/latest/guides/install.html&lt;br /&gt;
and then after that page:&lt;br /&gt;
https://zmeventnotification.readthedocs.io/en/latest/guides/hooks.html&lt;br /&gt;
&lt;br /&gt;
Make sure you look through and configure the three files&lt;br /&gt;
* secrets.ini&lt;br /&gt;
* zmeventnotification.ini&lt;br /&gt;
* objectconfig.ini&lt;br /&gt;
&lt;br /&gt;
Test it is working with&lt;br /&gt;
 sudo -u www-data /var/lib/zmeventnotification/bin/zm_detect.py --config /etc/zm/objectconfig.ini  --eventid 2 --monitorid 1 --debug&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
==== Email Alert on events via filters ====&lt;br /&gt;
Please see [[Filters]]&lt;br /&gt;
&lt;br /&gt;
==== Face Recognition ====&lt;br /&gt;
* One approach: https://forums.zoneminder.com/viewtopic.php?t=32652&lt;br /&gt;
&lt;br /&gt;
==== Only activate ZMES on certain cameras ====&lt;br /&gt;
This is handled under the skip_monitors option in zmeventnotification.ini. &lt;br /&gt;
If you have a high number of cameras, but only need ZMES on certain ones, then you will want to use this.&lt;br /&gt;
&lt;br /&gt;
==== Adjusting the Threshold of what Percentage causes an Object to be detected ====&lt;br /&gt;
See objectconfig.ini: object_min_confidence. These can be set on a Monitor by Monitor basis, I think.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
==== Missed events in Mocord ====&lt;br /&gt;
If you run the above command: &lt;br /&gt;
 sudo -u www-data /var/lib/zmeventnotification/bin/zm_detect.py --config /etc/zm/objectconfig.ini  --eventid 2 --monitorid 1 --debug&lt;br /&gt;
You will see the debug information of what ZMES is trying to do. By default, it runs on either a frame:snapshot or an alarm frame. This means that it takes one picture of the video, and runs the neural net detection on that. If for some reason, e.g. a shadow instead of a person is on that alarm frame, then it may fail to detect a person. If you have a long mocord video (say 10 minutes) then there will be only one alarm frame analyzed. The solution appears to be to use modect, where there will be more alarm frames to test or adjust the zones.&lt;br /&gt;
&lt;br /&gt;
==== I installed opencv per the zmeventnotification docs, but import cv2 doesn&amp;#039;t work...? ====&lt;br /&gt;
This happens to me following the default guides. I&amp;#039;m probably missing a step, but the below solves it for me (debian 11):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
the install path is local to the build folder, but the module is further down a few directories. so the shared object / module needs to be copied to the path...&lt;br /&gt;
therefore:&lt;br /&gt;
&lt;br /&gt;
root@zmes:/home/user/build# python3 -m site&lt;br /&gt;
sys.path = [&lt;br /&gt;
    &amp;#039;/home/user/build&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python39.zip&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3.9&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3.9/lib-dynload&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/local/lib/python3.9/dist-packages&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3/dist-packages&amp;#039;,&lt;br /&gt;
]&lt;br /&gt;
USER_BASE: &amp;#039;/root/.local&amp;#039; (exists)&lt;br /&gt;
USER_SITE: &amp;#039;/root/.local/lib/python3.9/site-packages&amp;#039; (doesn&amp;#039;t exist)&lt;br /&gt;
ENABLE_USER_SITE: True&lt;br /&gt;
root@zmes:/home/user/build# cp lib/python3/cv2.cpython-39-x86_64-linux-gnu.so /usr/local/lib/python3.9/dist-packages/.&lt;br /&gt;
root@zmes:/home/user/build# python3&lt;br /&gt;
Python 3.9.2 (default, Feb 28 2021, 17:03:44) &lt;br /&gt;
[GCC 10.2.1 20210110] on linux&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import cv2&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; quit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== error: (-215:Assertion failed) preferableBackend != DNN_BACKEND_CUDA || IS_DNN_CUDA_TARGET(preferableTarget) in function &amp;#039;validateBackendAndTarget&amp;#039; ====&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135777&lt;br /&gt;
====This environment is externally managed... To install Python packages system-wide, ====&lt;br /&gt;
I recently got the following error with Debian 12 (Devuan 5).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ModuleNotFoundError: No module named &amp;#039;pyzm&amp;#039;&lt;br /&gt;
Failed to detect hooks version.&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
    &lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
    &lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
    &lt;br /&gt;
    See /usr/share/doc/python3.11/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
ERROR:python hooks setup failed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
My hack (fast) solution: &lt;br /&gt;
 edit install script and add&lt;br /&gt;
 --break-system-packages to the pip3 command line.&lt;br /&gt;
reference: https://stackoverflow.com/questions/75608323/how-do-i-solve-error-externally-managed-environment-every-time-i-use-pip-3&lt;br /&gt;
&lt;br /&gt;
Of course, you do this at your own risk. Given that my ZM machines are used only for ZM, it&amp;#039;s not so much of a danger to have pip&lt;br /&gt;
override packages.&lt;br /&gt;
&lt;br /&gt;
====Detecting Objects Out of a Zone====&lt;br /&gt;
Reportedly, this requires setting the bounding box pixels in objectconfig.ini. Read the ini file, which also says that you can import zones from ZM (note that there are two settings. Read the whole file. import_zm_zones and only_triggered_zm_zones). To get the bounding box, just use the Zone editor of ZM, putting them in order from 1,2,3 to 4, or more.&lt;br /&gt;
 [monitor-1]&lt;br /&gt;
 driveway=0,0 1919,0 1919,1079 0,1079&lt;br /&gt;
See https://forums.zoneminder.com/viewtopic.php?t=33879&lt;br /&gt;
====Problem with imutils on new install====&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=137777&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://storage.googleapis.com/openimages/web&lt;br /&gt;
* https://pypi.org/project/openimages&lt;br /&gt;
* https://pypi.org/project/yolo34py/ and https://github.com/madhawav/YOLO3-4-Py&lt;br /&gt;
* https://github.com/lbdc/zm-alarm&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137862 - Using Google&amp;#039;s AI service to identify objects with a python script instead of ZMES. Backup here: [[Python Scripts for Image Detection]]&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138013 - Another user with a script accessing external AI.&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138422 - Coral USB Adapter for Object Detection&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138664 - Possible error with recent updates of ZMES&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138714 - Another approach for Image Recognition w/out ZMES.&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=GPU_passthrough_to_virtual_machines&amp;diff=17838</id>
		<title>GPU passthrough to virtual machines</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=GPU_passthrough_to_virtual_machines&amp;diff=17838"/>
		<updated>2025-12-15T14:45:02Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Using a GPU should reduce the load on the CPUs and potentially enable a system to process more or larger camera feeds.  It can be tricky to get GPU passthrough working for GPUs to virtual machines.  This article is based on running systems. Note that you may also want to consider using a GPU just for object detection (ZMES), not necessarily for ZM.&lt;br /&gt;
&lt;br /&gt;
==Nvidia GPU on Proxmox==&lt;br /&gt;
I have recently [[User:Gerdesj|Gerdesj]] ([[User talk:Gerdesj|talk]]) 19:07, 6 September 2024 (EDT) migrated the hardware running VMware (Dell T320) in the next section to Proxmox 8.2.  I followed this guide: https://www.theregister.com/2024/06/19/proxmox_xcp_ng_gpu_passthrough/ The Proxmox instructions work  &lt;br /&gt;
&lt;br /&gt;
==Nvidia GPU in VMware==&lt;br /&gt;
I have not tested whether all mitigations are &amp;#039;&amp;#039;still&amp;#039;&amp;#039; needed, since I first wrote this article.  I suggest ignoring the VMware related changes (except for the actual passthrough step!) first and then add them in if they are still an issue.  Note that one of them is to avoid a PSOD so ensure you have access to the system if it needs rebooting from a crash.&lt;br /&gt;
&lt;br /&gt;
* Host: Dell T320, 1 socket Xeon E5-2407 2.2 GHz CPU, BIOS 2.9.0&lt;br /&gt;
* VMware: ESXI 6.5.0 patch level 16576891&lt;br /&gt;
* GPU: MSI Geforce GTX 1050 Ti (this card does not require any host BIOS settings changing, nor Memory Mapped I/O settings on the VM)&lt;br /&gt;
* Cameras: Four Reolink RLC-410.  Encoding at 2048 x 1536, 10 fps, High H.264 profile&lt;br /&gt;
* VM: Ubuntu 20.04 LTS server with no extras. Four vCPUs, 6 GB RAM, 30GB root and EFI, 300GB XFS for /var&lt;br /&gt;
* Zoneminder: 1.34 and 1.36&lt;br /&gt;
&lt;br /&gt;
===ESXi host===&lt;br /&gt;
ssh into the host and edit /etc/vmware/passthru.map.  Change the word bridge to link.  This avoids a PSOD on the host when restarting the VM with the GPU passed through to it. See: https://www.reddit.com/r/vmware/comments/f3xsgj/nvidia_gpu_esx_65_dell_t320_pci_passthrough_crash/&lt;br /&gt;
&lt;br /&gt;
 # NVIDIA&lt;br /&gt;
 10de  ffff  link   false&lt;br /&gt;
&lt;br /&gt;
Pass the GPU through to the host using the DirectPath I/O mechanism  and reboot, then connect both devices to the VM.  There will be an audio card and the video card itself.  see: https://blogs.vmware.com/apps/2018/09/using-gpus-with-virtual-machines-on-vsphere-part-2-vmdirectpath-i-o.html&lt;br /&gt;
&lt;br /&gt;
==Ubuntu 20.04 VM==&lt;br /&gt;
The VM must use EFI so the install must use the Ubuntu server installer and not the minimal installer which will not work with efiboot.  VM type set to Ubuntu 64 bit.&lt;br /&gt;
&lt;br /&gt;
In Advanced settings for the VM, set the following flag to false. This setting disables informing the VM it is a VM.  This avoids a problem where the GPU fails to initialise properly:&lt;br /&gt;
&lt;br /&gt;
 hypervisor.cpuid.v0 = FALSE&lt;br /&gt;
&lt;br /&gt;
===Nvidia drivers and CUDA===&lt;br /&gt;
These instructions stay within the drivers etc provided by Ubuntu 20.04 LTS. NVidia as upstream also provide drivers and these will be newer but may break something.  The OS provided ffmpeg has cuda support built in.&lt;br /&gt;
&lt;br /&gt;
Use this command to decide which driver to install:&lt;br /&gt;
&lt;br /&gt;
 # ubuntu-drivers devices&lt;br /&gt;
&lt;br /&gt;
Install the &amp;quot;headless&amp;quot; version of the driver and reboot, optionally install nvidia-utils to get nvidia-smi:&lt;br /&gt;
 # apt install nvidia-headless-440&lt;br /&gt;
 # apt install nvidia-utils-440&lt;br /&gt;
&lt;br /&gt;
Run this to confirm it is working after rebooting, if you have the utils installed:&lt;br /&gt;
 # nvidia-smi&lt;br /&gt;
&lt;br /&gt;
If you just need decoding eg for Zoneminder - this provides &amp;#039;&amp;#039;libnvcuvid.so&amp;#039;&amp;#039;: libnvidia-decode-440.&lt;br /&gt;
&lt;br /&gt;
If it does not work properly then reboot the ESXi host.  For example the two devices seem to pass through OK but only the audio devices seem to work.  You may have crashed the GPU in some way.  Messing around with drivers and too many restarts of the VM seems to cause this for me.&lt;br /&gt;
&lt;br /&gt;
===Testing===&lt;br /&gt;
Check ffmpeg has cuda support:&lt;br /&gt;
 # ffmpeg -hwaccels&lt;br /&gt;
 ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers&lt;br /&gt;
 ...&lt;br /&gt;
 Hardware acceleration methods:&lt;br /&gt;
 vdpau&lt;br /&gt;
 cuda&lt;br /&gt;
 vaapi&lt;br /&gt;
 drm&lt;br /&gt;
 opencl&lt;br /&gt;
 cuvid&lt;br /&gt;
&lt;br /&gt;
There should be no error messages relating to libraries when you run something like this, which streams from a camera to /dev/null and uses CUDA:&lt;br /&gt;
&lt;br /&gt;
 # ffmpeg -hwaccel cuda -i &amp;quot;rtmp://HOSTNAME_OR_IP/bcs/channel0_main.bcs?channel=0&amp;amp;stream=0&amp;amp;user=admin&amp;amp;password=PASSWORD&amp;quot;  -an -f rawvideo -y /dev/null&lt;br /&gt;
&lt;br /&gt;
In another console, you could run nvidia-smi and see a process using the GPU.&lt;br /&gt;
&lt;br /&gt;
If you get an error relating to libnvcuvid.so.1 then you have not installed libnvidia-decode&lt;br /&gt;
&lt;br /&gt;
== Camera Settings ==&lt;br /&gt;
&lt;br /&gt;
Camera parameters for reference. Reolinks have three streams - main, sub and ext.  main is the clear stream and sub is the lowest quality one.  These cameras also have a RTSP stream but that appears to be pretty flakey compared to RTMP.  I want to watch these cameras so I monitor at high resolution.  If you are building a security system then monitor sub and record main (bold in the URLs in the table.)  Monitoring at say 640 x 480 7 frames per second will allow you to monitor a huge number of cameras.&lt;br /&gt;
&lt;br /&gt;
All other settings on defaults.  Initial setup done on 1.34.  See below for notes on 1.36&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Parameter&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Model&lt;br /&gt;
|Reolink RLC-410-5MP&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |&amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|Source Type&lt;br /&gt;
|Ffmpeg&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |&amp;#039;&amp;#039;&amp;#039;Source&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|Method&lt;br /&gt;
|TCP&lt;br /&gt;
|-&lt;br /&gt;
|Options&lt;br /&gt;
|n/a&lt;br /&gt;
|-&lt;br /&gt;
|Source Path&lt;br /&gt;
|rtmp://HOSTNAME_OR_IP/bcs/channel0_&amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;.bcs?channel=0&amp;amp;stream=0&amp;amp;user=admin&amp;amp;password=PASSWORD &amp;lt;br /&amp;gt;&lt;br /&gt;
rtmp://HOSTNAME_OR_IP/bcs/channel0_&amp;#039;&amp;#039;&amp;#039;sub&amp;#039;&amp;#039;&amp;#039;.bcs?channel=0&amp;amp;stream=1&amp;amp;user=admin&amp;amp;password=PASSWORD&lt;br /&gt;
|-&lt;br /&gt;
|DecoderHWAccelName&lt;br /&gt;
|cuda&lt;br /&gt;
|-&lt;br /&gt;
|Target colorspace&lt;br /&gt;
|32 bit colour&lt;br /&gt;
|-&lt;br /&gt;
|Capture Width&lt;br /&gt;
|2048&lt;br /&gt;
|-&lt;br /&gt;
|Capture Height&lt;br /&gt;
|1536&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |&amp;#039;&amp;#039;&amp;#039;Storage&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|Save JPEGs&lt;br /&gt;
|Frames + Analysis images (if available)&lt;br /&gt;
|-&lt;br /&gt;
|Video Writer&lt;br /&gt;
|H264 Camera Passthrough&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Changes between 1.34 and 1.36 ==&lt;br /&gt;
I had to change the buffers settings to stop zmc crashing. &amp;#039;&amp;#039;Maximum Image Buffer Size (frames)&amp;#039;&amp;#039; from 25 to 0.  The default is 0 if you create a new monitor in 1.36 which autotunes the buffer.  &amp;#039;&amp;#039;Image Buffer Size (frames)&amp;#039;&amp;#039; to 5 which smoothes the live view.  /dev/shm is no longer a concern in 1.36 as it was before (see the release notes: https://forums.zoneminder.com/viewtopic.php?f=1&amp;amp;t=30781 )&lt;br /&gt;
&lt;br /&gt;
== Tips/Techniques ==&lt;br /&gt;
===Using CLI tools to determine GPU usage===&lt;br /&gt;
When troubleshooting, you may want to use:&lt;br /&gt;
 intel-smi &lt;br /&gt;
 or&lt;br /&gt;
 nvidia-smi&lt;br /&gt;
Per: https://forums.zoneminder.com/viewtopic.php?p=137930#p137930&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?f=40&amp;amp;t=30512&lt;br /&gt;
* https://developer.nvidia.com/blog/nvidia-ffmpeg-transcoding-guide/ - Nvidia Page on FFMPEG&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?t=33415 - the deb-multimedia repo reportedly has CUDA support compiled in for FFMPEG.&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138627 - Successful report of GPU usage.&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=ZMES&amp;diff=17837</id>
		<title>ZMES</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=ZMES&amp;diff=17837"/>
		<updated>2025-12-15T14:43:14Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From the github: The Event Notification Server sits along with ZoneMinder and offers real time notifications, support for push notifications as well as Machine Learning powered recognition. As of today, it supports:&lt;br /&gt;
&lt;br /&gt;
    - detection of 80 types of objects (persons, cars, etc.)&lt;br /&gt;
    - face recognition&lt;br /&gt;
    - deep license plate recognition&lt;br /&gt;
&lt;br /&gt;
I will add more algorithms over time.&lt;br /&gt;
Ref: https://github.com/ZoneMinder/zmeventnotification&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In plain terms, why would you want to use ZMES? Because it avoids false positives associated with weather, automobiles, nature, and a number of other factors. ZMES will get motion detection to detect correctly in the 90-99% range. To do this with Zoneminder&amp;#039;s built in motion detection is more difficult. Be warned that while ZMES is good, it is not perfect and there is room for improvement. However, &amp;#039;&amp;#039;&amp;#039;object detection&amp;#039;&amp;#039;&amp;#039; via tools like Yolo is still an emerging field, there is likely to be improvement in the future. &lt;br /&gt;
&lt;br /&gt;
You can also use external scripts (such as https://github.com/pjreddie/darknet or https://github.com/lbdc/zm-alarm) independently from ZM, as well as do custom object detection (search online) for other tasks such as automation, bird watching, insect monitoring, etc... All these scripts need is an image (which is easily obtained from ZM).&lt;br /&gt;
&lt;br /&gt;
== Setup == &lt;br /&gt;
Refer to https://zmeventnotification.readthedocs.io/en/latest/guides/install.html&lt;br /&gt;
and then after that page:&lt;br /&gt;
https://zmeventnotification.readthedocs.io/en/latest/guides/hooks.html&lt;br /&gt;
&lt;br /&gt;
Make sure you look through and configure the three files&lt;br /&gt;
* secrets.ini&lt;br /&gt;
* zmeventnotification.ini&lt;br /&gt;
* objectconfig.ini&lt;br /&gt;
&lt;br /&gt;
Test it is working with&lt;br /&gt;
 sudo -u www-data /var/lib/zmeventnotification/bin/zm_detect.py --config /etc/zm/objectconfig.ini  --eventid 2 --monitorid 1 --debug&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
==== Email Alert on events via filters ====&lt;br /&gt;
Please see [[Filters]]&lt;br /&gt;
&lt;br /&gt;
==== Face Recognition ====&lt;br /&gt;
* One approach: https://forums.zoneminder.com/viewtopic.php?t=32652&lt;br /&gt;
&lt;br /&gt;
==== Only activate ZMES on certain cameras ====&lt;br /&gt;
This is handled under the skip_monitors option in zmeventnotification.ini. &lt;br /&gt;
If you have a high number of cameras, but only need ZMES on certain ones, then you will want to use this.&lt;br /&gt;
&lt;br /&gt;
==== Adjusting the Threshold of what Percentage causes an Object to be detected ====&lt;br /&gt;
See objectconfig.ini: object_min_confidence. These can be set on a Monitor by Monitor basis, I think.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
==== Missed events in Mocord ====&lt;br /&gt;
If you run the above command: &lt;br /&gt;
 sudo -u www-data /var/lib/zmeventnotification/bin/zm_detect.py --config /etc/zm/objectconfig.ini  --eventid 2 --monitorid 1 --debug&lt;br /&gt;
You will see the debug information of what ZMES is trying to do. By default, it runs on either a frame:snapshot or an alarm frame. This means that it takes one picture of the video, and runs the neural net detection on that. If for some reason, e.g. a shadow instead of a person is on that alarm frame, then it may fail to detect a person. If you have a long mocord video (say 10 minutes) then there will be only one alarm frame analyzed. The solution appears to be to use modect, where there will be more alarm frames to test or adjust the zones.&lt;br /&gt;
&lt;br /&gt;
==== I installed opencv per the zmeventnotification docs, but import cv2 doesn&amp;#039;t work...? ====&lt;br /&gt;
This happens to me following the default guides. I&amp;#039;m probably missing a step, but the below solves it for me (debian 11):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
the install path is local to the build folder, but the module is further down a few directories. so the shared object / module needs to be copied to the path...&lt;br /&gt;
therefore:&lt;br /&gt;
&lt;br /&gt;
root@zmes:/home/user/build# python3 -m site&lt;br /&gt;
sys.path = [&lt;br /&gt;
    &amp;#039;/home/user/build&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python39.zip&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3.9&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3.9/lib-dynload&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/local/lib/python3.9/dist-packages&amp;#039;,&lt;br /&gt;
    &amp;#039;/usr/lib/python3/dist-packages&amp;#039;,&lt;br /&gt;
]&lt;br /&gt;
USER_BASE: &amp;#039;/root/.local&amp;#039; (exists)&lt;br /&gt;
USER_SITE: &amp;#039;/root/.local/lib/python3.9/site-packages&amp;#039; (doesn&amp;#039;t exist)&lt;br /&gt;
ENABLE_USER_SITE: True&lt;br /&gt;
root@zmes:/home/user/build# cp lib/python3/cv2.cpython-39-x86_64-linux-gnu.so /usr/local/lib/python3.9/dist-packages/.&lt;br /&gt;
root@zmes:/home/user/build# python3&lt;br /&gt;
Python 3.9.2 (default, Feb 28 2021, 17:03:44) &lt;br /&gt;
[GCC 10.2.1 20210110] on linux&lt;br /&gt;
Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; import cv2&lt;br /&gt;
&amp;gt;&amp;gt;&amp;gt; quit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== error: (-215:Assertion failed) preferableBackend != DNN_BACKEND_CUDA || IS_DNN_CUDA_TARGET(preferableTarget) in function &amp;#039;validateBackendAndTarget&amp;#039; ====&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=135777&lt;br /&gt;
====This environment is externally managed... To install Python packages system-wide, ====&lt;br /&gt;
I recently got the following error with Debian 12 (Devuan 5).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ModuleNotFoundError: No module named &amp;#039;pyzm&amp;#039;&lt;br /&gt;
Failed to detect hooks version.&lt;br /&gt;
error: externally-managed-environment&lt;br /&gt;
&lt;br /&gt;
× This environment is externally managed&lt;br /&gt;
╰─&amp;gt; To install Python packages system-wide, try apt install&lt;br /&gt;
    python3-xyz, where xyz is the package you are trying to&lt;br /&gt;
    install.&lt;br /&gt;
    &lt;br /&gt;
    If you wish to install a non-Debian-packaged Python package,&lt;br /&gt;
    create a virtual environment using python3 -m venv path/to/venv.&lt;br /&gt;
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make&lt;br /&gt;
    sure you have python3-full installed.&lt;br /&gt;
    &lt;br /&gt;
    If you wish to install a non-Debian packaged Python application,&lt;br /&gt;
    it may be easiest to use pipx install xyz, which will manage a&lt;br /&gt;
    virtual environment for you. Make sure you have pipx installed.&lt;br /&gt;
    &lt;br /&gt;
    See /usr/share/doc/python3.11/README.venv for more information.&lt;br /&gt;
&lt;br /&gt;
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.&lt;br /&gt;
hint: See PEP 668 for the detailed specification.&lt;br /&gt;
ERROR:python hooks setup failed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
My hack (fast) solution: &lt;br /&gt;
 edit install script and add&lt;br /&gt;
 --break-system-packages to the pip3 command line.&lt;br /&gt;
reference: https://stackoverflow.com/questions/75608323/how-do-i-solve-error-externally-managed-environment-every-time-i-use-pip-3&lt;br /&gt;
&lt;br /&gt;
Of course, you do this at your own risk. Given that my ZM machines are used only for ZM, it&amp;#039;s not so much of a danger to have pip&lt;br /&gt;
override packages.&lt;br /&gt;
&lt;br /&gt;
====Detecting Objects Out of a Zone====&lt;br /&gt;
Reportedly, this requires setting the bounding box pixels in objectconfig.ini. Read the ini file, which also says that you can import zones from ZM (note that there are two settings. Read the whole file. import_zm_zones and only_triggered_zm_zones). To get the bounding box, just use the Zone editor of ZM, putting them in order from 1,2,3 to 4, or more.&lt;br /&gt;
 [monitor-1]&lt;br /&gt;
 driveway=0,0 1919,0 1919,1079 0,1079&lt;br /&gt;
See https://forums.zoneminder.com/viewtopic.php?t=33879&lt;br /&gt;
====Problem with imutils on new install====&lt;br /&gt;
See: https://forums.zoneminder.com/viewtopic.php?p=137777&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://storage.googleapis.com/openimages/web&lt;br /&gt;
* https://pypi.org/project/openimages&lt;br /&gt;
* https://pypi.org/project/yolo34py/ and https://github.com/madhawav/YOLO3-4-Py&lt;br /&gt;
* https://github.com/lbdc/zm-alarm&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=137862 - Using Google&amp;#039;s AI service to identify objects with a python script instead of ZMES. Backup here: [[Python Scripts for Image Detection]]&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138013#p138013 - Another user with a script accessing external AI.&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138422#p138422 - Coral USB Adapter for Object Detection&lt;br /&gt;
* https://forums.zoneminder.com/viewtopic.php?p=138664#p138664 - Possible error with recent updates of ZMES&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17836</id>
		<title>Realtime event backup to cloud storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17836"/>
		<updated>2025-12-14T09:52:27Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s possible to use lsync daemon, which leverages the inotify https://en.wikipedia.org/wiki/Inotify kernel subsystem to run triggers based on events in a directory (create, modify, delete). Triggers can be varied (you can run any arbitrary command) but in the default use case, is as a filesystem backup / clone using the rsync command.&lt;br /&gt;
&lt;br /&gt;
You may also want to consider other options. Inotify has command line tools, and there is an incrond, which uses cron syntax to run commands based on inotify.&lt;br /&gt;
&lt;br /&gt;
==About==&lt;br /&gt;
After recently migrating from another popular NVR software on Windows to Zoneminder on Linux I started looking for a way to do near-real-time backups of my events to offsite storage, simply as a way to have a copy should the local ZM server be compromised by break-in, fire, etc.  Software such as Dropbox, Google Drive, etc. make it relatively easy to do this on Windows but the setup on Linux takes bit more effort.&lt;br /&gt;
&lt;br /&gt;
I wanted to keep it as simple as possible and don&amp;#039;t need my backup solution to interface with the ZM database at all.  After experimenting with several other options, I have settled on an application called lsyncd.  It runs as a service and leverages inotify and rsync to watch a directory or directories and mirror only new changes to another storage location.  Lsyncd should be available as a package for most Linux distributions.  I used the installation instructions here for my Rocky Linux system;&lt;br /&gt;
&lt;br /&gt;
	https://docs.rockylinux.org/10/guides/backup/mirroring_lsyncd/&lt;br /&gt;
	&lt;br /&gt;
At this point it is worthwhile to at least skim through the docs.&lt;br /&gt;
&lt;br /&gt;
	https://lsyncd.github.io/lsyncd/manual/config/file/&lt;br /&gt;
	&lt;br /&gt;
	https://linux.die.net/man/1/rsync&lt;br /&gt;
	&lt;br /&gt;
Both lsyncd and rsync are highly configurable and incredibly powerful.  For many people the use case will be very simple like my own which I will describe here - watch my Zoneminder storage location and copy new files to a remote location, but much more complex configurations are certainly possible. In my case I&amp;#039;ll be writing to an Amazon S3 bucket which I have already setup using S3FS-FUSE according to the documentation here;  &lt;br /&gt;
&lt;br /&gt;
	https://zoneminder.readthedocs.io/en/latest/userguide/options/options_storage.html&lt;br /&gt;
	&lt;br /&gt;
Note you do not need to add the S3FS as a storage location in ZM to use lsyncd to copy files there, that is only required for ZM to write events directly to S3.  Configuring rsync is beyond the scope of this document but this solution will work with any target that rsync is capable of writing to.  Make sure your remote location is accessible via rsync before proceeding.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
Once lsyncd is installed you will need to create a configuration file in /etc/lsyncd.conf.  I&amp;#039;ve included mine as an example below.  Note this script uses LUA syntax, not bash. Be &amp;#039;&amp;#039;&amp;#039;VERY CAREFUL&amp;#039;&amp;#039;&amp;#039; if you are testing remote write/sync/copy operations to a destination that already has important data on it (see links below).  I highly recommend initial testing with an empty bucket or target filesystem.  You have been warned.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;settings {&lt;br /&gt;
&lt;br /&gt;
   logfile = &amp;quot;/var/log/lsyncd.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusFile = &amp;quot;/var/log/lsyncd-status.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusInterval = 10,&lt;br /&gt;
&lt;br /&gt;
   maxProcesses = 1,&lt;br /&gt;
&lt;br /&gt;
   insist = true,&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sync {&lt;br /&gt;
&lt;br /&gt;
   default.rsync,&lt;br /&gt;
&lt;br /&gt;
   source = &amp;quot;/home/Cameras&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   target = &amp;quot;/media/aws&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   delete = false, &lt;br /&gt;
&lt;br /&gt;
   delay = 10,    &lt;br /&gt;
&lt;br /&gt;
   init = false,&lt;br /&gt;
&lt;br /&gt;
   rsync = {&lt;br /&gt;
&lt;br /&gt;
     archive = true,&lt;br /&gt;
&lt;br /&gt;
     compress = false&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;logfile = &amp;#039;&amp;#039; is pretty self-explanatory.  Be sure to set up log rotation after you are done setting lsyncd up, if required.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxProcesses = 1&amp;#039;&amp;#039; is the default.  If you are syncing multiple sources or targets you may want to increase this.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;insist = true&amp;#039;&amp;#039; allows the service to start even if the target is not ready.  I got errors without this which went away when I added it.  YMMV.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;source = &amp;#039;&amp;#039;The directory where ZM events are stored.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;target = &amp;#039;&amp;#039;The location to copy events to.  Must be accessible via rsync.  In my case it is the mount point for the S3FS configured previously.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;targetdir = &amp;quot;/somedirectory&amp;quot;&amp;#039;&amp;#039; (not shown, part of sync block) subdirectory to use on the target.  I&amp;#039;m just using the root directory in a dedicated bucket.  You may not want this and should specify something here.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delay = &amp;#039;&amp;#039;This is how often rsync will run if there are any filesystem changes.  Default is 15 seconds.  For many users this will be close enough to real-time for the purpose.  This can be combined with (or substituted) for another value in the settings field;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxDelay = # &amp;#039;&amp;#039; (not shown, part of settings block) will queue this # of file changes before calling rsync.  Between delay and/or maxDelay it is possible to tune the timing of your file copies to your exact preference.  inotify waits for write_close  to add files to the transfer list so there are no issues with rsync trying to upload uncompleted files.  I typically only record short 10 second clips.  If you use your cameras to continuously record be aware that files in the process of being written will not be copied until they are closed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;archive = true &amp;#039;&amp;#039;This preserves permissions on the copied files.&lt;br /&gt;
&lt;br /&gt;
Two other very important variables in this file are;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delete = false&amp;#039;&amp;#039; this is also pretty self explanatory, file deletes will not be synced from source to target.  In the case of my S3 bucket I have lifecycle rules that handle this.  If you prefer for your remote storage location to synchronize the deletions made by Zoneminder you can set this to true. This also means if you accidentally delete events from your local storage they will be deleted from the cloud as well.  Use with caution.   &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;init = false&amp;#039;&amp;#039; causes the lsyncd to not do a complete initial synchronization between source and target on service startup.  On S3 this is expensive in terms of API calls and may take a while.  I know I&amp;#039;m going to miss some events during system maintenance/OS updates etc anyway so I don&amp;#039;t consider this worth the cost, but you can set to true if you want it.  Be warned it will make your target an exact mirror of your source.&lt;br /&gt;
&lt;br /&gt;
Having delete and init set to false also should make this config fairly safe to use against an existing target if you just run it on your machine without heeding my previous warning. Don&amp;#039;t change these unless you are absolutely sure you know what you are doing. There are also options besides true and false so read the docs for more info.  You can also add options to be added directly to the rsync calls. You can sync multiple directories to multiple targets with multiple options.  There are exclude options which you may find useful.  It is far too much to cover here so read the docs, but the simple config above is all I need for my purposes.&lt;br /&gt;
&lt;br /&gt;
Once the service is configured you can control it with systemctl like any other systemd service.  By default it will be disabled so you will need to enable it to run automatically after suitable testing.  You can check the logs for startup or running errors with journalctl.  If syncs are working correctly you can watch them as uploads are logged very shortly after the events are saved to local disk;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[root@nvr system]# tail -50 /var/log/lsyncd.log&lt;br /&gt;
/1/2025-12-11/8707/8707-video.mp4&lt;br /&gt;
/1/2025-12-11/8707/snapshot.jpg&lt;br /&gt;
/1/2025-12-11/8707/alarm.jpg&lt;br /&gt;
/6/2025-12-11/8708/&lt;br /&gt;
/6/2025-12-11/&lt;br /&gt;
/6/&lt;br /&gt;
/6/2025-12-11/8708/8708-video.mp4&lt;br /&gt;
/6/2025-12-11/8708/snapshot.jpg&lt;br /&gt;
/6/2025-12-11/8708/alarm.jpg&lt;br /&gt;
/8/2025-12-11/8706/8706-video.mp4&lt;br /&gt;
/8/2025-12-11/8706/&lt;br /&gt;
/8/2025-12-11/&lt;br /&gt;
/8/&lt;br /&gt;
Thu Dec 11 14:30:25 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:31:50 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8709/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8709/8709-video.mp4&lt;br /&gt;
/2/2025-12-11/8709/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8709/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:00 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:04 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8710/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8710/8710-video.mp4&lt;br /&gt;
/2/2025-12-11/8710/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8710/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:11 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:45 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8711/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8711/8711-video.mp4&lt;br /&gt;
/2/2025-12-11/8711/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8711/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:51 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:37:36 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/3/2025-12-11/8712/&lt;br /&gt;
/3/2025-12-11/&lt;br /&gt;
/3/&lt;br /&gt;
/&lt;br /&gt;
/3/2025-12-11/8712/8712-video.mp4&lt;br /&gt;
/3/2025-12-11/8712/snapshot.jpg&lt;br /&gt;
/3/2025-12-11/8712/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:37:41 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
[root@nvr system]#&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Note:  If you receive errors similar to &amp;quot;maximum number of watches reached&amp;quot; in the logs you may need to increase the default limits on your system for /proc/sys/fs/inotify/max_user_instances and /proc/sys/fs/inotify/max_user_watches.  See here for more details;&lt;br /&gt;
&lt;br /&gt;
https://support.scc.suse.com/s/kb/360054835111?language=en_US&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m happy to have offsite copies of all my events now.  While they are not tracked in the Zoneminder database, they are still saved in folders by monitor id and date for easy retrieval should the ZM database become unavailable.  Props to the ZM devs for their great software, and I hope this writeup proves useful to some other users in the future.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://github.com/lsyncd/lsyncd/issues/668 - Beware that lsync will do rsync with deletes on by default. With some casual testing, you might inadvertedly delete your home directory or root filesystem. From the github: &amp;quot;&amp;#039;&amp;#039;I was told many times delete by default was a bad idea and was a result of the usual use case in the sense of replicating the target exactly like the source. I suppose the people telling so have a point.&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
* https://docs.rockylinux.org/10/books/learning_rsync/06_rsync_inotify/&lt;br /&gt;
* https://linuxvox.com/blog/what-is-the-proper-way-to-use-inotify/ - Using inotify-tools command line interface&lt;br /&gt;
* https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ - Probably easier than lsyncd. (Was not available in default Debian Bullseye (have to use backports https://qa.debian.org/madison.php?package=incron&amp;amp;table=archived&amp;amp;a=&amp;amp;c=&amp;amp;s=#) but is in most other Debian releases.).&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Inotifyd&lt;br /&gt;
* https://wiki.archlinux.org/title/Incron&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17835</id>
		<title>Realtime event backup to cloud storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17835"/>
		<updated>2025-12-14T09:34:13Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s possible to use lsync daemon, which leverages the inotify https://en.wikipedia.org/wiki/Inotify kernel subsystem to run triggers based on events in a directory (create, modify, delete). Triggers can be varied (you can run any arbitrary command) but in the default use case, is as a filesystem backup / clone using the rsync command.&lt;br /&gt;
&lt;br /&gt;
You may also want to consider other options. Inotify has command line tools, and there is an incrond, which uses cron syntax to run commands based on inotify.&lt;br /&gt;
&lt;br /&gt;
==About==&lt;br /&gt;
After recently migrating from another popular NVR software on Windows to Zoneminder on Linux I started looking for a way to do near-real-time backups of my events to offsite storage, simply as a way to have a copy should the local ZM server be compromised by break-in, fire, etc.  Software such as Dropbox, Google Drive, etc. make it relatively easy to do this on Windows but the setup on Linux takes bit more effort.&lt;br /&gt;
&lt;br /&gt;
I wanted to keep it as simple as possible and don&amp;#039;t need my backup solution to interface with the ZM database at all.  After experimenting with several other options, I have settled on an application called lsyncd.  It runs as a service and leverages inotify and rsync to watch a directory or directories and mirror only new changes to another storage location.  Lsyncd should be available as a package for most Linux distributions.  I used the installation instructions here for my Rocky Linux system;&lt;br /&gt;
&lt;br /&gt;
	https://docs.rockylinux.org/10/guides/backup/mirroring_lsyncd/&lt;br /&gt;
	&lt;br /&gt;
At this point it is worthwhile to at least skim through the docs.&lt;br /&gt;
&lt;br /&gt;
	https://lsyncd.github.io/lsyncd/manual/config/file/&lt;br /&gt;
	&lt;br /&gt;
	https://linux.die.net/man/1/rsync&lt;br /&gt;
	&lt;br /&gt;
Both lsyncd and rsync are highly configurable and incredibly powerful.  For many people the use case will be very simple like my own which I will describe here - watch my Zoneminder storage location and copy new files to a remote location, but much more complex configurations are certainly possible. In my case I&amp;#039;ll be writing to an Amazon S3 bucket which I have already setup using S3FS-FUSE according to the documentation here;  &lt;br /&gt;
&lt;br /&gt;
	https://zoneminder.readthedocs.io/en/latest/userguide/options/options_storage.html&lt;br /&gt;
	&lt;br /&gt;
Note you do not need to add the S3FS as a storage location in ZM to use lsyncd to copy files there, that is only required for ZM to write events directly to S3.  Configuring rsync is beyond the scope of this document but this solution will work with any target that rsync is capable of writing to.  Make sure your remote location is accessible via rsync before proceeding.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
Once lsyncd is installed you will need to create a configuration file in /etc/lsyncd.conf.  I&amp;#039;ve included mine as an example below.  Note this script uses LUA syntax, not bash. Be &amp;#039;&amp;#039;&amp;#039;VERY CAREFUL&amp;#039;&amp;#039;&amp;#039; if you are testing remote write/sync/copy operations to a destination that already has important data on it (see links below).  I highly recommend initial testing with an empty bucket or target filesystem.  You have been warned.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;settings {&lt;br /&gt;
&lt;br /&gt;
   logfile = &amp;quot;/var/log/lsyncd.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusFile = &amp;quot;/var/log/lsyncd-status.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusInterval = 10,&lt;br /&gt;
&lt;br /&gt;
   maxProcesses = 1,&lt;br /&gt;
&lt;br /&gt;
   insist = true,&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sync {&lt;br /&gt;
&lt;br /&gt;
   default.rsync,&lt;br /&gt;
&lt;br /&gt;
   source = &amp;quot;/home/Cameras&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   target = &amp;quot;/media/aws&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   delete = false, &lt;br /&gt;
&lt;br /&gt;
   delay = 10,    &lt;br /&gt;
&lt;br /&gt;
   init = false,&lt;br /&gt;
&lt;br /&gt;
   rsync = {&lt;br /&gt;
&lt;br /&gt;
     archive = true,&lt;br /&gt;
&lt;br /&gt;
     compress = false&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;logfile = &amp;#039;&amp;#039; is pretty self-explanatory.  Be sure to set up log rotation after you are done setting lsyncd up, if required.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxProcesses = 1&amp;#039;&amp;#039; is the default.  If you are syncing multiple sources or targets you may want to increase this.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;insist = true&amp;#039;&amp;#039; allows the service to start even if the target is not ready.  I got errors without this which went away when I added it.  YMMV.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;source = &amp;#039;&amp;#039;The directory where ZM events are stored.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;target = &amp;#039;&amp;#039;The location to copy events to.  Must be accessible via rsync.  In my case it is the mount point for the S3FS configured previously.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;targetdir = &amp;quot;/somedirectory&amp;quot;&amp;#039;&amp;#039; (not shown, part of sync block) subdirectory to use on the target.  I&amp;#039;m just using the root directory in a dedicated bucket.  You may not want this and should specify something here.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delay = &amp;#039;&amp;#039;This is how often rsync will run if there are any filesystem changes.  Default is 15 seconds.  For many users this will be close enough to real-time for the purpose.  This can be combined with (or substituted) for another value in the settings field;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxDelay = # &amp;#039;&amp;#039; (not shown, part of settings block) will queue this # of file changes before calling rsync.  Between delay and/or maxDelay it is possible to tune the timing of your file copies to your exact preference.  inotify waits for write_close  to add files to the transfer list so there are no issues with rsync trying to upload uncompleted files.  I typically only record short 10 second clips.  If you use your cameras to continuously record be aware that files in the process of being written will not be copied until they are closed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;archive = true &amp;#039;&amp;#039;This preserves permissions on the copied files.&lt;br /&gt;
&lt;br /&gt;
Two other very important variables in this file are;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delete = false&amp;#039;&amp;#039; this is also pretty self explanatory, file deletes will not be synced from source to target.  In the case of my S3 bucket I have lifecycle rules that handle this.  If you prefer for your remote storage location to synchronize the deletions made by Zoneminder you can set this to true. This also means if you accidentally delete events from your local storage they will be deleted from the cloud as well.  Use with caution.   &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;init = false&amp;#039;&amp;#039; causes the lsyncd to not do a complete initial synchronization between source and target on service startup.  On S3 this is expensive in terms of API calls and may take a while.  I know I&amp;#039;m going to miss some events during system maintenance/OS updates etc anyway so I don&amp;#039;t consider this worth the cost, but you can set to true if you want it.  Be warned it will make your target an exact mirror of your source.&lt;br /&gt;
&lt;br /&gt;
Having delete and init set to false also should make this config fairly safe to use against an existing target if you just run it on your machine without heeding my previous warning. Don&amp;#039;t change these unless you are absolutely sure you know what you are doing. There are also options besides true and false so read the docs for more info.  You can also add options to be added directly to the rsync calls. You can sync multiple directories to multiple targets with multiple options.  There are exclude options which you may find useful.  It is far too much to cover here so read the docs, but the simple config above is all I need for my purposes.&lt;br /&gt;
&lt;br /&gt;
Once the service is configured you can control it with systemctl like any other systemd service.  By default it will be disabled so you will need to enable it to run automatically after suitable testing.  You can check the logs for startup or running errors with journalctl.  If syncs are working correctly you can watch them as uploads are logged very shortly after the events are saved to local disk;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[root@nvr system]# tail -50 /var/log/lsyncd.log&lt;br /&gt;
/1/2025-12-11/8707/8707-video.mp4&lt;br /&gt;
/1/2025-12-11/8707/snapshot.jpg&lt;br /&gt;
/1/2025-12-11/8707/alarm.jpg&lt;br /&gt;
/6/2025-12-11/8708/&lt;br /&gt;
/6/2025-12-11/&lt;br /&gt;
/6/&lt;br /&gt;
/6/2025-12-11/8708/8708-video.mp4&lt;br /&gt;
/6/2025-12-11/8708/snapshot.jpg&lt;br /&gt;
/6/2025-12-11/8708/alarm.jpg&lt;br /&gt;
/8/2025-12-11/8706/8706-video.mp4&lt;br /&gt;
/8/2025-12-11/8706/&lt;br /&gt;
/8/2025-12-11/&lt;br /&gt;
/8/&lt;br /&gt;
Thu Dec 11 14:30:25 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:31:50 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8709/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8709/8709-video.mp4&lt;br /&gt;
/2/2025-12-11/8709/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8709/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:00 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:04 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8710/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8710/8710-video.mp4&lt;br /&gt;
/2/2025-12-11/8710/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8710/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:11 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:45 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8711/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8711/8711-video.mp4&lt;br /&gt;
/2/2025-12-11/8711/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8711/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:51 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:37:36 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/3/2025-12-11/8712/&lt;br /&gt;
/3/2025-12-11/&lt;br /&gt;
/3/&lt;br /&gt;
/&lt;br /&gt;
/3/2025-12-11/8712/8712-video.mp4&lt;br /&gt;
/3/2025-12-11/8712/snapshot.jpg&lt;br /&gt;
/3/2025-12-11/8712/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:37:41 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
[root@nvr system]#&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Note:  If you receive errors similar to &amp;quot;maximum number of watches reached&amp;quot; in the logs you may need to increase the default limits on your system for /proc/sys/fs/inotify/max_user_instances and /proc/sys/fs/inotify/max_user_watches.  See here for more details;&lt;br /&gt;
&lt;br /&gt;
https://support.scc.suse.com/s/kb/360054835111?language=en_US&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m happy to have offsite copies of all my events now.  While they are not tracked in the Zoneminder database, they are still saved in folders by monitor id and date for easy retrieval should the ZM database become unavailable.  Props to the ZM devs for their great software, and I hope this writeup proves useful to some other users in the future.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://github.com/lsyncd/lsyncd/issues/668 - Beware that lsync will do rsync with deletes on by default. With some casual testing, you might inadvertedly delete your home directory or root filesystem. From the github: &amp;quot;&amp;#039;&amp;#039;I was told many times delete by default was a bad idea and was a result of the usual use case in the sense of replicating the target exactly like the source. I suppose the people telling so have a point.&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
* https://docs.rockylinux.org/10/books/learning_rsync/06_rsync_inotify/&lt;br /&gt;
* https://linuxvox.com/blog/what-is-the-proper-way-to-use-inotify/ - Using inotify-tools command line interface&lt;br /&gt;
* https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ - Probably easier than lsyncd. Newer software (only available in Debian Bookworm and later).&lt;br /&gt;
* https://wiki.alpinelinux.org/wiki/Inotifyd&lt;br /&gt;
* https://wiki.archlinux.org/title/Incron&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17834</id>
		<title>Realtime event backup to cloud storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17834"/>
		<updated>2025-12-14T09:31:22Z</updated>

		<summary type="html">&lt;p&gt;Burger: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s possible to use lsync daemon, which leverages the inotify https://en.wikipedia.org/wiki/Inotify kernel subsystem to run triggers based on events in a directory (create, modify, delete). Triggers can be varied (you can run any arbitrary command) but in the default use case, is as a filesystem backup / clone using the rsync command.&lt;br /&gt;
&lt;br /&gt;
You may also want to consider other options. Inotify has command line tools, and there is an incrond, which uses cron syntax to run commands based on inotify.&lt;br /&gt;
&lt;br /&gt;
==About==&lt;br /&gt;
After recently migrating from another popular NVR software on Windows to Zoneminder on Linux I started looking for a way to do near-real-time backups of my events to offsite storage, simply as a way to have a copy should the local ZM server be compromised by break-in, fire, etc.  Software such as Dropbox, Google Drive, etc. make it relatively easy to do this on Windows but the setup on Linux takes bit more effort.&lt;br /&gt;
&lt;br /&gt;
I wanted to keep it as simple as possible and don&amp;#039;t need my backup solution to interface with the ZM database at all.  After experimenting with several other options, I have settled on an application called lsyncd.  It runs as a service and leverages inotify and rsync to watch a directory or directories and mirror only new changes to another storage location.  Lsyncd should be available as a package for most Linux distributions.  I used the installation instructions here for my Rocky Linux system;&lt;br /&gt;
&lt;br /&gt;
	https://docs.rockylinux.org/10/guides/backup/mirroring_lsyncd/&lt;br /&gt;
	&lt;br /&gt;
At this point it is worthwhile to at least skim through the docs.&lt;br /&gt;
&lt;br /&gt;
	https://lsyncd.github.io/lsyncd/manual/config/file/&lt;br /&gt;
	&lt;br /&gt;
	https://linux.die.net/man/1/rsync&lt;br /&gt;
	&lt;br /&gt;
Both lsyncd and rsync are highly configurable and incredibly powerful.  For many people the use case will be very simple like my own which I will describe here - watch my Zoneminder storage location and copy new files to a remote location, but much more complex configurations are certainly possible. In my case I&amp;#039;ll be writing to an Amazon S3 bucket which I have already setup using S3FS-FUSE according to the documentation here;  &lt;br /&gt;
&lt;br /&gt;
	https://zoneminder.readthedocs.io/en/latest/userguide/options/options_storage.html&lt;br /&gt;
	&lt;br /&gt;
Note you do not need to add the S3FS as a storage location in ZM to use lsyncd to copy files there, that is only required for ZM to write events directly to S3.  Configuring rsync is beyond the scope of this document but this solution will work with any target that rsync is capable of writing to.  Make sure your remote location is accessible via rsync before proceeding.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
Once lsyncd is installed you will need to create a configuration file in /etc/lsyncd.conf.  I&amp;#039;ve included mine as an example below.  Note this script uses LUA syntax, not bash. Be &amp;#039;&amp;#039;&amp;#039;VERY CAREFUL&amp;#039;&amp;#039;&amp;#039; if you are testing remote write/sync/copy operations to a destination that already has important data on it (see links below).  I highly recommend initial testing with an empty bucket or target filesystem.  You have been warned.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;settings {&lt;br /&gt;
&lt;br /&gt;
   logfile = &amp;quot;/var/log/lsyncd.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusFile = &amp;quot;/var/log/lsyncd-status.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusInterval = 10,&lt;br /&gt;
&lt;br /&gt;
   maxProcesses = 1,&lt;br /&gt;
&lt;br /&gt;
   insist = true,&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sync {&lt;br /&gt;
&lt;br /&gt;
   default.rsync,&lt;br /&gt;
&lt;br /&gt;
   source = &amp;quot;/home/Cameras&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   target = &amp;quot;/media/aws&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   delete = false, &lt;br /&gt;
&lt;br /&gt;
   delay = 10,    &lt;br /&gt;
&lt;br /&gt;
   init = false,&lt;br /&gt;
&lt;br /&gt;
   rsync = {&lt;br /&gt;
&lt;br /&gt;
     archive = true,&lt;br /&gt;
&lt;br /&gt;
     compress = false&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;logfile = &amp;#039;&amp;#039; is pretty self-explanatory.  Be sure to set up log rotation after you are done setting lsyncd up, if required.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxProcesses = 1&amp;#039;&amp;#039; is the default.  If you are syncing multiple sources or targets you may want to increase this.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;insist = true&amp;#039;&amp;#039; allows the service to start even if the target is not ready.  I got errors without this which went away when I added it.  YMMV.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;source = &amp;#039;&amp;#039;The directory where ZM events are stored.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;target = &amp;#039;&amp;#039;The location to copy events to.  Must be accessible via rsync.  In my case it is the mount point for the S3FS configured previously.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;targetdir = &amp;quot;/somedirectory&amp;quot;&amp;#039;&amp;#039; (not shown, part of sync block) subdirectory to use on the target.  I&amp;#039;m just using the root directory in a dedicated bucket.  You may not want this and should specify something here.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delay = &amp;#039;&amp;#039;This is how often rsync will run if there are any filesystem changes.  Default is 15 seconds.  For many users this will be close enough to real-time for the purpose.  This can be combined with (or substituted) for another value in the settings field;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxDelay = # &amp;#039;&amp;#039; (not shown, part of settings block) will queue this # of file changes before calling rsync.  Between delay and/or maxDelay it is possible to tune the timing of your file copies to your exact preference.  inotify waits for write_close  to add files to the transfer list so there are no issues with rsync trying to upload uncompleted files.  I typically only record short 10 second clips.  If you use your cameras to continuously record be aware that files in the process of being written will not be copied until they are closed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;archive = true &amp;#039;&amp;#039;This preserves permissions on the copied files.&lt;br /&gt;
&lt;br /&gt;
Two other very important variables in this file are;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delete = false&amp;#039;&amp;#039; this is also pretty self explanatory, file deletes will not be synced from source to target.  In the case of my S3 bucket I have lifecycle rules that handle this.  If you prefer for your remote storage location to synchronize the deletions made by Zoneminder you can set this to true. This also means if you accidentally delete events from your local storage they will be deleted from the cloud as well.  Use with caution.   &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;init = false&amp;#039;&amp;#039; causes the lsyncd to not do a complete initial synchronization between source and target on service startup.  On S3 this is expensive in terms of API calls and may take a while.  I know I&amp;#039;m going to miss some events during system maintenance/OS updates etc anyway so I don&amp;#039;t consider this worth the cost, but you can set to true if you want it.  Be warned it will make your target an exact mirror of your source.&lt;br /&gt;
&lt;br /&gt;
Having delete and init set to false also should make this config fairly safe to use against an existing target if you just run it on your machine without heeding my previous warning. Don&amp;#039;t change these unless you are absolutely sure you know what you are doing. There are also options besides true and false so read the docs for more info.  You can also add options to be added directly to the rsync calls. You can sync multiple directories to multiple targets with multiple options.  There are exclude options which you may find useful.  It is far too much to cover here so read the docs, but the simple config above is all I need for my purposes.&lt;br /&gt;
&lt;br /&gt;
Once the service is configured you can control it with systemctl like any other systemd service.  By default it will be disabled so you will need to enable it to run automatically after suitable testing.  You can check the logs for startup or running errors with journalctl.  If syncs are working correctly you can watch them as uploads are logged very shortly after the events are saved to local disk;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[root@nvr system]# tail -50 /var/log/lsyncd.log&lt;br /&gt;
/1/2025-12-11/8707/8707-video.mp4&lt;br /&gt;
/1/2025-12-11/8707/snapshot.jpg&lt;br /&gt;
/1/2025-12-11/8707/alarm.jpg&lt;br /&gt;
/6/2025-12-11/8708/&lt;br /&gt;
/6/2025-12-11/&lt;br /&gt;
/6/&lt;br /&gt;
/6/2025-12-11/8708/8708-video.mp4&lt;br /&gt;
/6/2025-12-11/8708/snapshot.jpg&lt;br /&gt;
/6/2025-12-11/8708/alarm.jpg&lt;br /&gt;
/8/2025-12-11/8706/8706-video.mp4&lt;br /&gt;
/8/2025-12-11/8706/&lt;br /&gt;
/8/2025-12-11/&lt;br /&gt;
/8/&lt;br /&gt;
Thu Dec 11 14:30:25 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:31:50 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8709/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8709/8709-video.mp4&lt;br /&gt;
/2/2025-12-11/8709/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8709/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:00 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:04 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8710/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8710/8710-video.mp4&lt;br /&gt;
/2/2025-12-11/8710/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8710/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:11 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:45 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8711/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8711/8711-video.mp4&lt;br /&gt;
/2/2025-12-11/8711/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8711/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:51 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:37:36 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/3/2025-12-11/8712/&lt;br /&gt;
/3/2025-12-11/&lt;br /&gt;
/3/&lt;br /&gt;
/&lt;br /&gt;
/3/2025-12-11/8712/8712-video.mp4&lt;br /&gt;
/3/2025-12-11/8712/snapshot.jpg&lt;br /&gt;
/3/2025-12-11/8712/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:37:41 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
[root@nvr system]#&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Note:  If you receive errors similar to &amp;quot;maximum number of watches reached&amp;quot; in the logs you may need to increase the default limits on your system for /proc/sys/fs/inotify/max_user_instances and /proc/sys/fs/inotify/max_user_watches.  See here for more details;&lt;br /&gt;
&lt;br /&gt;
https://support.scc.suse.com/s/kb/360054835111?language=en_US&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m happy to have offsite copies of all my events now.  While they are not tracked in the Zoneminder database, they are still saved in folders by monitor id and date for easy retrieval should the ZM database become unavailable.  Props to the ZM devs for their great software, and I hope this writeup proves useful to some other users in the future.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://github.com/lsyncd/lsyncd/issues/668 - Beware that lsync will do rsync with deletes on by default. With some casual testing, you might inadvertedly delete your home directory or root filesystem. From the github: &amp;quot;&amp;#039;&amp;#039;I was told many times delete by default was a bad idea and was a result of the usual use case in the sense of replicating the target exactly like the source. I suppose the people telling so have a point.&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
* https://docs.rockylinux.org/10/books/learning_rsync/06_rsync_inotify/&lt;br /&gt;
* https://linuxvox.com/blog/what-is-the-proper-way-to-use-inotify/ - Using inotify-tools command line interface&lt;br /&gt;
* https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ - Probably easier than lsyncd. Newer software (only available in Debian Bookworm and later).&lt;br /&gt;
* https://wiki.archlinux.org/title/Incron&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
	<entry>
		<id>http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17833</id>
		<title>Realtime event backup to cloud storage</title>
		<link rel="alternate" type="text/html" href="http://wiki.staging.zoneminder.com/index.php?title=Realtime_event_backup_to_cloud_storage&amp;diff=17833"/>
		<updated>2025-12-14T09:30:07Z</updated>

		<summary type="html">&lt;p&gt;Burger: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&amp;#039;s possible to use lsync daemon, which leverages the inotify https://en.wikipedia.org/wiki/Inotify kernel subsystem to run triggers based on events in a directory (create, modify, delete). Triggers can be varied (you can run any arbitrary command) but in the default use case, is as a filesystem backup / clone using the rsync command.&lt;br /&gt;
&lt;br /&gt;
==About==&lt;br /&gt;
After recently migrating from another popular NVR software on Windows to Zoneminder on Linux I started looking for a way to do near-real-time backups of my events to offsite storage, simply as a way to have a copy should the local ZM server be compromised by break-in, fire, etc.  Software such as Dropbox, Google Drive, etc. make it relatively easy to do this on Windows but the setup on Linux takes bit more effort.&lt;br /&gt;
&lt;br /&gt;
I wanted to keep it as simple as possible and don&amp;#039;t need my backup solution to interface with the ZM database at all.  After experimenting with several other options, I have settled on an application called lsyncd.  It runs as a service and leverages inotify and rsync to watch a directory or directories and mirror only new changes to another storage location.  Lsyncd should be available as a package for most Linux distributions.  I used the installation instructions here for my Rocky Linux system;&lt;br /&gt;
&lt;br /&gt;
	https://docs.rockylinux.org/10/guides/backup/mirroring_lsyncd/&lt;br /&gt;
	&lt;br /&gt;
At this point it is worthwhile to at least skim through the docs.&lt;br /&gt;
&lt;br /&gt;
	https://lsyncd.github.io/lsyncd/manual/config/file/&lt;br /&gt;
	&lt;br /&gt;
	https://linux.die.net/man/1/rsync&lt;br /&gt;
	&lt;br /&gt;
Both lsyncd and rsync are highly configurable and incredibly powerful.  For many people the use case will be very simple like my own which I will describe here - watch my Zoneminder storage location and copy new files to a remote location, but much more complex configurations are certainly possible. In my case I&amp;#039;ll be writing to an Amazon S3 bucket which I have already setup using S3FS-FUSE according to the documentation here;  &lt;br /&gt;
&lt;br /&gt;
	https://zoneminder.readthedocs.io/en/latest/userguide/options/options_storage.html&lt;br /&gt;
	&lt;br /&gt;
Note you do not need to add the S3FS as a storage location in ZM to use lsyncd to copy files there, that is only required for ZM to write events directly to S3.  Configuring rsync is beyond the scope of this document but this solution will work with any target that rsync is capable of writing to.  Make sure your remote location is accessible via rsync before proceeding.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
Once lsyncd is installed you will need to create a configuration file in /etc/lsyncd.conf.  I&amp;#039;ve included mine as an example below.  Note this script uses LUA syntax, not bash. Be &amp;#039;&amp;#039;&amp;#039;VERY CAREFUL&amp;#039;&amp;#039;&amp;#039; if you are testing remote write/sync/copy operations to a destination that already has important data on it (see links below).  I highly recommend initial testing with an empty bucket or target filesystem.  You have been warned.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;settings {&lt;br /&gt;
&lt;br /&gt;
   logfile = &amp;quot;/var/log/lsyncd.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusFile = &amp;quot;/var/log/lsyncd-status.log&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   statusInterval = 10,&lt;br /&gt;
&lt;br /&gt;
   maxProcesses = 1,&lt;br /&gt;
&lt;br /&gt;
   insist = true,&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sync {&lt;br /&gt;
&lt;br /&gt;
   default.rsync,&lt;br /&gt;
&lt;br /&gt;
   source = &amp;quot;/home/Cameras&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   target = &amp;quot;/media/aws&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
   delete = false, &lt;br /&gt;
&lt;br /&gt;
   delay = 10,    &lt;br /&gt;
&lt;br /&gt;
   init = false,&lt;br /&gt;
&lt;br /&gt;
   rsync = {&lt;br /&gt;
&lt;br /&gt;
     archive = true,&lt;br /&gt;
&lt;br /&gt;
     compress = false&lt;br /&gt;
&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;logfile = &amp;#039;&amp;#039; is pretty self-explanatory.  Be sure to set up log rotation after you are done setting lsyncd up, if required.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxProcesses = 1&amp;#039;&amp;#039; is the default.  If you are syncing multiple sources or targets you may want to increase this.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;insist = true&amp;#039;&amp;#039; allows the service to start even if the target is not ready.  I got errors without this which went away when I added it.  YMMV.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;source = &amp;#039;&amp;#039;The directory where ZM events are stored.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;target = &amp;#039;&amp;#039;The location to copy events to.  Must be accessible via rsync.  In my case it is the mount point for the S3FS configured previously.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;targetdir = &amp;quot;/somedirectory&amp;quot;&amp;#039;&amp;#039; (not shown, part of sync block) subdirectory to use on the target.  I&amp;#039;m just using the root directory in a dedicated bucket.  You may not want this and should specify something here.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delay = &amp;#039;&amp;#039;This is how often rsync will run if there are any filesystem changes.  Default is 15 seconds.  For many users this will be close enough to real-time for the purpose.  This can be combined with (or substituted) for another value in the settings field;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;maxDelay = # &amp;#039;&amp;#039; (not shown, part of settings block) will queue this # of file changes before calling rsync.  Between delay and/or maxDelay it is possible to tune the timing of your file copies to your exact preference.  inotify waits for write_close  to add files to the transfer list so there are no issues with rsync trying to upload uncompleted files.  I typically only record short 10 second clips.  If you use your cameras to continuously record be aware that files in the process of being written will not be copied until they are closed.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;archive = true &amp;#039;&amp;#039;This preserves permissions on the copied files.&lt;br /&gt;
&lt;br /&gt;
Two other very important variables in this file are;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;delete = false&amp;#039;&amp;#039; this is also pretty self explanatory, file deletes will not be synced from source to target.  In the case of my S3 bucket I have lifecycle rules that handle this.  If you prefer for your remote storage location to synchronize the deletions made by Zoneminder you can set this to true. This also means if you accidentally delete events from your local storage they will be deleted from the cloud as well.  Use with caution.   &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;init = false&amp;#039;&amp;#039; causes the lsyncd to not do a complete initial synchronization between source and target on service startup.  On S3 this is expensive in terms of API calls and may take a while.  I know I&amp;#039;m going to miss some events during system maintenance/OS updates etc anyway so I don&amp;#039;t consider this worth the cost, but you can set to true if you want it.  Be warned it will make your target an exact mirror of your source.&lt;br /&gt;
&lt;br /&gt;
Having delete and init set to false also should make this config fairly safe to use against an existing target if you just run it on your machine without heeding my previous warning. Don&amp;#039;t change these unless you are absolutely sure you know what you are doing. There are also options besides true and false so read the docs for more info.  You can also add options to be added directly to the rsync calls. You can sync multiple directories to multiple targets with multiple options.  There are exclude options which you may find useful.  It is far too much to cover here so read the docs, but the simple config above is all I need for my purposes.&lt;br /&gt;
&lt;br /&gt;
Once the service is configured you can control it with systemctl like any other systemd service.  By default it will be disabled so you will need to enable it to run automatically after suitable testing.  You can check the logs for startup or running errors with journalctl.  If syncs are working correctly you can watch them as uploads are logged very shortly after the events are saved to local disk;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[root@nvr system]# tail -50 /var/log/lsyncd.log&lt;br /&gt;
/1/2025-12-11/8707/8707-video.mp4&lt;br /&gt;
/1/2025-12-11/8707/snapshot.jpg&lt;br /&gt;
/1/2025-12-11/8707/alarm.jpg&lt;br /&gt;
/6/2025-12-11/8708/&lt;br /&gt;
/6/2025-12-11/&lt;br /&gt;
/6/&lt;br /&gt;
/6/2025-12-11/8708/8708-video.mp4&lt;br /&gt;
/6/2025-12-11/8708/snapshot.jpg&lt;br /&gt;
/6/2025-12-11/8708/alarm.jpg&lt;br /&gt;
/8/2025-12-11/8706/8706-video.mp4&lt;br /&gt;
/8/2025-12-11/8706/&lt;br /&gt;
/8/2025-12-11/&lt;br /&gt;
/8/&lt;br /&gt;
Thu Dec 11 14:30:25 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:31:50 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8709/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8709/8709-video.mp4&lt;br /&gt;
/2/2025-12-11/8709/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8709/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:00 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:04 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8710/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8710/8710-video.mp4&lt;br /&gt;
/2/2025-12-11/8710/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8710/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:11 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:32:45 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/2/2025-12-11/8711/&lt;br /&gt;
/2/2025-12-11/&lt;br /&gt;
/2/&lt;br /&gt;
/&lt;br /&gt;
/2/2025-12-11/8711/8711-video.mp4&lt;br /&gt;
/2/2025-12-11/8711/snapshot.jpg&lt;br /&gt;
/2/2025-12-11/8711/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:32:51 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
Thu Dec 11 14:37:36 2025 Normal: Calling rsync with filter-list of new/modified files/dirs&lt;br /&gt;
/3/2025-12-11/8712/&lt;br /&gt;
/3/2025-12-11/&lt;br /&gt;
/3/&lt;br /&gt;
/&lt;br /&gt;
/3/2025-12-11/8712/8712-video.mp4&lt;br /&gt;
/3/2025-12-11/8712/snapshot.jpg&lt;br /&gt;
/3/2025-12-11/8712/alarm.jpg&lt;br /&gt;
Thu Dec 11 14:37:41 2025 Normal: Finished a list after exitcode: 0&lt;br /&gt;
[root@nvr system]#&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Note:  If you receive errors similar to &amp;quot;maximum number of watches reached&amp;quot; in the logs you may need to increase the default limits on your system for /proc/sys/fs/inotify/max_user_instances and /proc/sys/fs/inotify/max_user_watches.  See here for more details;&lt;br /&gt;
&lt;br /&gt;
https://support.scc.suse.com/s/kb/360054835111?language=en_US&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m happy to have offsite copies of all my events now.  While they are not tracked in the Zoneminder database, they are still saved in folders by monitor id and date for easy retrieval should the ZM database become unavailable.  Props to the ZM devs for their great software, and I hope this writeup proves useful to some other users in the future.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
* https://github.com/lsyncd/lsyncd/issues/668 - Beware that lsync will do rsync with deletes on by default. With some casual testing, you might inadvertedly delete your home directory or root filesystem. From the github: &amp;quot;&amp;#039;&amp;#039;I was told many times delete by default was a bad idea and was a result of the usual use case in the sense of replicating the target exactly like the source. I suppose the people telling so have a point.&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
* https://docs.rockylinux.org/10/books/learning_rsync/06_rsync_inotify/&lt;br /&gt;
* https://linuxvox.com/blog/what-is-the-proper-way-to-use-inotify/ - Using inotify-tools command line interface&lt;br /&gt;
* https://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ - Probably easier than lsyncd. Newer software (only available in Debian Bookworm and later).&lt;br /&gt;
* https://wiki.archlinux.org/title/Incron&lt;/div&gt;</summary>
		<author><name>Burger</name></author>
	</entry>
</feed>