-added 'null' key word to img_comp_cmd parameter so motion
 detection can be turned off if desired
-fixed footage directory max_events_bytes by having it loop
 through the directory at least 100 times
This commit is contained in:
zii 2025-07-22 21:06:44 -04:00
parent 7c72d26e46
commit c0f167e5b1
4 changed files with 48 additions and 24 deletions

View File

@ -2,7 +2,7 @@
JustMotion is a simple, lightweight video surveillance application utilizing
the server-client model that doesn't try to re-invent the wheel. The source
code for both server and client are available this repository and can be
code for both server and client are available in this repository and can be
compliled and/or installed separately.
# JustMotion-Server #
@ -13,10 +13,10 @@ motion to permanent storage. The main advantage of this is reduced storage
requirements as opposed to continuous recording because only video footage
of interest is kept in storage.
The server implements the principle of doing the least as needed, as a result
it extremely lightweight with the fact it doesn't attempt to re-implement much
of it's functions internally but will instead rely on external applications
that already implement the functions very well.
The server implements the principle of doing the least as needed. As a result
it is extremely lightweight with the fact it doesn't attempt to re-implement
much of it's functions internally but will instead rely on external
applications that already implement the functions very well.
It doesn't have a builtin user interface so instead external applications are
more than welcome to interface with the buffer/footage directories to
@ -26,14 +26,14 @@ implement a user interface of any flavor.
JustMotion-Client is the client portion of this application that actually
implement a user interface. Utilizing the same principle of doing the least as
needed, it uses an external video player to play m3u8 playlist files mounted
as an ssh filesystem to play live or recorded footage from the server.
needed, it uses an external video player to play m3u8 playlist files located
at the server's buffer/footage directories. It mounts the server as an ssh
filesystem to access such directories so no need to open any addtional ports
if your server already has working ssh access.
### Usage (server) ###
```
JustMotion 1.0
Usage: jmotion <argument>
-h : display usage information about this application.
@ -53,9 +53,6 @@ Usage: jmotion <argument>
The config file is a simple text file that contain parameters that dictate the
behavior of the server for each camera located in the /etc/jmotion directory.
The config for each camera can have any unique name within that directory.
Below is an example of a config file with all parameters supported and
descriptions.
```
# Motion Watch config file
#
@ -106,9 +103,8 @@ img_comp_cmd = compare -metric FUZZ &prev& &next& /dev/null
# formatted so the app will be required to support this format. also avoid
# outputting any special chars, only numeric chars with a single '.' if
# outputting a decimal value. magick is the default if not defined in the
# config file. the special string &prev& will be substituted with the path
# to the "previous" bitmap image, behind in time stamp to the image path
# subtituted in &next&.
# config file. this parameter can also be set to 'null' as a means to turn
# off motion detection.
#
img_comp_out = stderr
# this is the standard output stream the app defined in img_comp_cmd will

View File

@ -32,7 +32,7 @@
using namespace std;
#define APP_VERSION "1.0"
#define APP_VERSION "1.1"
#define APP_NAME "JustMotion"
#define APP_TARGET "jmotion"
#define DATETIME_FMT "yyyyMMddhhmmss"

View File

@ -29,21 +29,36 @@ void DetectLoop::init()
pcTimer = new QTimer(this);
evtTimer = new QTimer(this);
setupBuffDir(shared->buffPath);
connect(pcTimer, &QTimer::timeout, this, &DetectLoop::pcBreak);
connect(evtTimer, &QTimer::timeout, this, &DetectLoop::reset);
connect(this, &QFileSystemWatcher::directoryChanged, this, &DetectLoop::updated);
pcTimer->start(shared->postSecs * 1000);
if (shared->compCmd.toLower() != "null")
{
connect(evtTimer, &QTimer::timeout, this, &DetectLoop::reset);
evtTimer->setSingleShot(true);
setupBuffDir(shared->buffPath);
eTimer.start();
}
else
{
eTimer.invalidate();
}
addPath(shared->buffPath + "/vid");
}
void DetectLoop::updated(const QString &path)
{
if (shared->compCmd.toLower() != "null")
{
eTimer.start();
}
auto clips = lsFilesInDir(path, shared->streamExt);
auto index = clips.indexOf(vidBName);
@ -153,7 +168,11 @@ QStringList DetectLoop::buildSnapArgs(const QString &vidSrc, const QString &imgP
QString DetectLoop::statusLine()
{
if (eTimer.elapsed() >= 5000)
if (!eTimer.isValid())
{
return "OFF ";
}
else if (eTimer.elapsed() >= 5000)
{
emit starving();
@ -187,7 +206,7 @@ void DetectLoop::exec()
QProcess::execute("ffmpeg", snapArgsA);
QProcess::execute("ffmpeg", snapArgsB);
if (QFile::exists(imgAPath) && QFile::exists(imgBPath))
if (QFile::exists(imgAPath) && QFile::exists(imgBPath) && (shared->compCmd.toLower() != "null"))
{
QProcess extComp;

View File

@ -150,7 +150,7 @@ void EventLoop::exec()
auto names = lsFilesInDir(shared->recPath + "/vid", shared->recExt);
if (byteSize(shared->recPath) > shared->evtMaxBytes)
for (auto i = 0; (byteSize(shared->recPath) >= shared->evtMaxBytes); ++i)
{
auto nameOnly = QFileInfo(shared->recPath + "/vid/" + names[0]).baseName();
@ -163,6 +163,15 @@ void EventLoop::exec()
names.removeFirst();
dirUpdated = true;
if (i > 100)
{
// loop through 100 times before breaking the for loop, prevents infinte looping
// if bytes size of the dir is not being read correctly or there is a lot to
// delete (don't want to keep EventLoop busy doing this for too long).
break;
}
}
if (dirUpdated)