v1.6.t9
The fork() architecture from the previous commit is also deemed a failure. Reverted back to v1.5.t19 code. I'll start from scratch, using this commit as the new base.
This commit is contained in:
parent
13eaf75c8a
commit
81da33ba81
15
README.md
15
README.md
|
@ -13,8 +13,13 @@ of this app can be used to operate multiple cameras.
|
||||||
Usage: mow <argument>
|
Usage: mow <argument>
|
||||||
|
|
||||||
-h : display usage information about this application.
|
-h : display usage information about this application.
|
||||||
-c : path to the config file.
|
-c : path to the config file(s).
|
||||||
-v : display the current version.
|
-v : display the current version.
|
||||||
|
|
||||||
|
note: multiple -c config files can be passed, reading from left
|
||||||
|
to right. any conflicting values between the files will
|
||||||
|
have the latest value from the latest file overwrite the
|
||||||
|
the earliest.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Config File ###
|
### Config File ###
|
||||||
|
@ -33,14 +38,6 @@ recording_stream = rtsp://1.2.3.4:554/h264
|
||||||
# this is the url to the main stream of the IP camera that will be used
|
# this is the url to the main stream of the IP camera that will be used
|
||||||
# to record footage.
|
# to record footage.
|
||||||
#
|
#
|
||||||
detect_stream = rtsp://1.2.3.4:554/h264cif
|
|
||||||
# this is an optional detection stream that will be used to detect motion.
|
|
||||||
# most cameras have the option to broadcast multiple streams of the same
|
|
||||||
# footage. it's recommend to use this parameter with a smaller, lower bit
|
|
||||||
# rate stream to reduce CPU usage. recording_stream will still be used to
|
|
||||||
# record higher quality footage. if not defined, recording_stream will be
|
|
||||||
# used for both motion detection and recording.
|
|
||||||
#
|
|
||||||
web_root = /var/www/html
|
web_root = /var/www/html
|
||||||
# this is the output directory that will be used to store recorded footage
|
# this is the output directory that will be used to store recorded footage
|
||||||
# from the cameras as well as the web interface for the application.
|
# from the cameras as well as the web interface for the application.
|
||||||
|
|
|
@ -6,7 +6,7 @@ cp ./.build-mow/mow /opt/mow/bin
|
||||||
printf "#!/bin/sh\n" > /opt/mow/run
|
printf "#!/bin/sh\n" > /opt/mow/run
|
||||||
printf "export OPENCV_LOG_LEVEL=DEBUG\n" >> /opt/mow/run
|
printf "export OPENCV_LOG_LEVEL=DEBUG\n" >> /opt/mow/run
|
||||||
printf "export OPENCV_VIDEOIO_DEBUG=1\n" >> /opt/mow/run
|
printf "export OPENCV_VIDEOIO_DEBUG=1\n" >> /opt/mow/run
|
||||||
printf "/opt/mow/bin \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8\n" >> /opt/mow/run
|
printf "/opt/mow/bin \$1 \$2 \$3\n" >> /opt/mow/run
|
||||||
chmod +x /opt/mow/run
|
chmod +x /opt/mow/run
|
||||||
chmod +x /opt/mow/bin
|
chmod +x /opt/mow/bin
|
||||||
rm /usr/bin/mow
|
rm /usr/bin/mow
|
||||||
|
|
102
src/common.cpp
102
src/common.cpp
|
@ -12,44 +12,6 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
string leftTrim(const string &str, const string &toRemove)
|
|
||||||
{
|
|
||||||
auto start = str.find_first_not_of(toRemove);
|
|
||||||
|
|
||||||
if (start != string::npos)
|
|
||||||
{
|
|
||||||
return str.substr(start);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string rightTrim(const string &str, const string &toRemove)
|
|
||||||
{
|
|
||||||
auto end = str.find_last_not_of(toRemove);
|
|
||||||
|
|
||||||
if (end != string::npos)
|
|
||||||
{
|
|
||||||
return str.substr(0, end + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string trim(const string &str, const string &toRemove)
|
|
||||||
{
|
|
||||||
return rightTrim(leftTrim(str, toRemove), toRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
string trim(const string &str)
|
|
||||||
{
|
|
||||||
return trim(str, TRIM_REMOVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
string cleanDir(const string &path)
|
string cleanDir(const string &path)
|
||||||
{
|
{
|
||||||
if (path[path.size() - 1] == '/')
|
if (path[path.size() - 1] == '/')
|
||||||
|
@ -193,7 +155,7 @@ void rdLine(const string ¶m, const string &line, string *value)
|
||||||
{
|
{
|
||||||
if (line.rfind(param.c_str(), 0) == 0)
|
if (line.rfind(param.c_str(), 0) == 0)
|
||||||
{
|
{
|
||||||
*value = trim(line).substr(param.size());
|
*value = line.substr(param.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +163,7 @@ void rdLine(const string ¶m, const string &line, int *value)
|
||||||
{
|
{
|
||||||
if (line.rfind(param.c_str(), 0) == 0)
|
if (line.rfind(param.c_str(), 0) == 0)
|
||||||
{
|
{
|
||||||
*value = strtol(trim(line).substr(param.size()).c_str(), NULL, 10);
|
*value = strtol(line.substr(param.size()).c_str(), NULL, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +175,7 @@ bool rdConf(const string &filePath, shared_t *share)
|
||||||
{
|
{
|
||||||
share->retCode = ENOENT;
|
share->retCode = ENOENT;
|
||||||
|
|
||||||
cerr << "err: config file: " << filePath << " does not exists or lack read permissions." << endl;
|
cout << "wrn: config file: " << filePath << " does not exists or lack read permissions." << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -227,7 +189,6 @@ bool rdConf(const string &filePath, shared_t *share)
|
||||||
{
|
{
|
||||||
rdLine("cam_name = ", line, &share->camName);
|
rdLine("cam_name = ", line, &share->camName);
|
||||||
rdLine("recording_stream = ", line, &share->recordUrl);
|
rdLine("recording_stream = ", line, &share->recordUrl);
|
||||||
rdLine("detect_stream = ", line, &share->detectUrl);
|
|
||||||
rdLine("web_root = ", line, &share->webRoot);
|
rdLine("web_root = ", line, &share->webRoot);
|
||||||
rdLine("web_text = ", line, &share->webTxt);
|
rdLine("web_text = ", line, &share->webTxt);
|
||||||
rdLine("web_bg = ", line, &share->webBg);
|
rdLine("web_bg = ", line, &share->webBg);
|
||||||
|
@ -255,7 +216,6 @@ bool rdConf(const string &filePath, shared_t *share)
|
||||||
bool rdConf(shared_t *share)
|
bool rdConf(shared_t *share)
|
||||||
{
|
{
|
||||||
share->recordUrl.clear();
|
share->recordUrl.clear();
|
||||||
share->detectUrl.clear();
|
|
||||||
share->postCmd.clear();
|
share->postCmd.clear();
|
||||||
share->buffDir.clear();
|
share->buffDir.clear();
|
||||||
share->camName.clear();
|
share->camName.clear();
|
||||||
|
@ -281,27 +241,25 @@ bool rdConf(shared_t *share)
|
||||||
share->webBg = "#485564";
|
share->webBg = "#485564";
|
||||||
share->webTxt = "#dee5ee";
|
share->webTxt = "#dee5ee";
|
||||||
share->webFont = "courier";
|
share->webFont = "courier";
|
||||||
share->detSuffix = ".det.";
|
|
||||||
share->recSuffix = ".rec.";
|
|
||||||
|
|
||||||
if (rdConf(share->conf, share))
|
auto ret = false;
|
||||||
|
|
||||||
|
for (auto &&confPath: share->conf)
|
||||||
|
{
|
||||||
|
if (rdConf(confPath, share)) ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
{
|
{
|
||||||
if (share->camName.empty())
|
if (share->camName.empty())
|
||||||
{
|
{
|
||||||
share->camName = path(share->conf).filename();
|
share->camName = path(share->conf.back()).filename();
|
||||||
}
|
|
||||||
|
|
||||||
if (share->detectUrl.empty())
|
|
||||||
{
|
|
||||||
share->detectUrl = share->recordUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
share->outDir = cleanDir(share->webRoot) + "/" + share->camName;
|
share->outDir = cleanDir(share->webRoot) + "/" + share->camName;
|
||||||
share->buffDir = cleanDir(share->buffDir) + "/" + share->camName;
|
share->buffDir = cleanDir(share->buffDir) + "/" + share->camName;
|
||||||
share->recLogPath = share->outDir + "/rec_log_lines.html";
|
share->recLogPath = share->outDir + "/rec_log_lines.html";
|
||||||
share->detLogPath = share->outDir + "/det_log_lines.html";
|
share->detLogPath = share->outDir + "/det_log_lines.html";
|
||||||
share->detSuffix += share->vidExt;
|
|
||||||
share->recSuffix += share->vidExt;
|
|
||||||
|
|
||||||
if (share->init)
|
if (share->init)
|
||||||
{
|
{
|
||||||
|
@ -316,8 +274,12 @@ bool rdConf(shared_t *share)
|
||||||
createDirTree(cleanDir(share->buffDir));
|
createDirTree(cleanDir(share->buffDir));
|
||||||
createDirTree(share->outDir);
|
createDirTree(share->outDir);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "err: none of the expected config files could be read." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return share->retCode == 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
string parseForParam(const string &arg, int argc, char** argv, bool argOnly, int &offs)
|
string parseForParam(const string &arg, int argc, char** argv, bool argOnly, int &offs)
|
||||||
|
@ -355,3 +317,33 @@ string parseForParam(const string &arg, int argc, char** argv, bool argOnly)
|
||||||
|
|
||||||
return parseForParam(arg, argc, argv, argOnly, notUsed);
|
return parseForParam(arg, argc, argv, argOnly, notUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<string> parseForList(const string &arg, int argc, char** argv)
|
||||||
|
{
|
||||||
|
auto offs = 0;
|
||||||
|
auto ret = vector<string>();
|
||||||
|
string param;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
param = parseForParam(arg, argc, argv, false, offs);
|
||||||
|
|
||||||
|
if (!param.empty())
|
||||||
|
{
|
||||||
|
ret.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!param.empty());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void waitForDetThreads(shared_t *share)
|
||||||
|
{
|
||||||
|
for (auto &&thr : share->detThreads)
|
||||||
|
{
|
||||||
|
thr.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
share->detThreads.clear();
|
||||||
|
}
|
||||||
|
|
77
src/common.h
77
src/common.h
|
@ -21,12 +21,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <opencv4/opencv2/opencv.hpp>
|
#include <opencv4/opencv2/opencv.hpp>
|
||||||
#include <opencv4/opencv2/videoio.hpp>
|
#include <opencv4/opencv2/videoio.hpp>
|
||||||
|
@ -35,53 +35,41 @@ using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
|
|
||||||
#define APP_VER "1.6.t8"
|
#define APP_VER "1.6.t9"
|
||||||
#define APP_NAME "Motion Watch"
|
#define APP_NAME "Motion Watch"
|
||||||
#define TRIM_REMOVE " \n\r\t\f\v."
|
|
||||||
#define PATH_ADDR 9
|
|
||||||
#define MAX_CAP_RETRY 3
|
|
||||||
|
|
||||||
struct shared_t
|
struct shared_t
|
||||||
{
|
{
|
||||||
ofstream recLogFile;
|
vector<thread> detThreads;
|
||||||
ofstream detLogFile;
|
vector<string> conf;
|
||||||
string conf;
|
ofstream recLogFile;
|
||||||
string recLogPath;
|
ofstream detLogFile;
|
||||||
string detLogPath;
|
string recLogPath;
|
||||||
string recordUrl;
|
string detLogPath;
|
||||||
string detectUrl;
|
string recordUrl;
|
||||||
string outDir;
|
string outDir;
|
||||||
string postCmd;
|
string postCmd;
|
||||||
string buffDir;
|
string buffDir;
|
||||||
string recSuffix;
|
string vidExt;
|
||||||
string detSuffix;
|
string vidCodec;
|
||||||
string vidExt;
|
string camName;
|
||||||
string vidCodec;
|
string webBg;
|
||||||
string camName;
|
string webTxt;
|
||||||
string webBg;
|
string webFont;
|
||||||
string webTxt;
|
string webRoot;
|
||||||
string webFont;
|
bool init;
|
||||||
string webRoot;
|
bool skipCmd;
|
||||||
bool init;
|
int clipLen;
|
||||||
bool skipCmd;
|
int frameGap;
|
||||||
bool updateRoot;
|
int pixThresh;
|
||||||
int detProcs;
|
int imgThresh;
|
||||||
int clipLen;
|
int numOfClips;
|
||||||
int frameGap;
|
int maxDays;
|
||||||
int pixThresh;
|
int maxClips;
|
||||||
int imgThresh;
|
int maxLogSize;
|
||||||
int numOfClips;
|
int retCode;
|
||||||
int maxDays;
|
|
||||||
int maxClips;
|
|
||||||
int maxLogSize;
|
|
||||||
int index;
|
|
||||||
int retCode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
string leftTrim(const string &str, const string &toRemove);
|
|
||||||
string rightTrim(const string &str, const string &toRemove);
|
|
||||||
string trim(const string &str, const string &toRemove);
|
|
||||||
string trim(const string &str);
|
|
||||||
string genDstFile(const string &dirOut, const char *fmt, const string &ext);
|
string genDstFile(const string &dirOut, const char *fmt, const string &ext);
|
||||||
string genTimeStr(const char *fmt);
|
string genTimeStr(const char *fmt);
|
||||||
string cleanDir(const string &path);
|
string cleanDir(const string &path);
|
||||||
|
@ -93,7 +81,10 @@ void enforceMaxDays(const string &dirPath, shared_t *share);
|
||||||
void enforceMaxClips(const string &dirPath, shared_t *share);
|
void enforceMaxClips(const string &dirPath, shared_t *share);
|
||||||
void rdLine(const string ¶m, const string &line, string *value);
|
void rdLine(const string ¶m, const string &line, string *value);
|
||||||
void rdLine(const string ¶m, const string &line, int *value);
|
void rdLine(const string ¶m, const string &line, int *value);
|
||||||
|
void statOut(shared_t *share);
|
||||||
|
void waitForDetThreads(shared_t *share);
|
||||||
bool rdConf(shared_t *share);
|
bool rdConf(shared_t *share);
|
||||||
|
vector<string> parseForList(const string &arg, int argc, char** argv);
|
||||||
vector<string> lsFilesInDir(const string &path, const string &ext = string());
|
vector<string> lsFilesInDir(const string &path, const string &ext = string());
|
||||||
vector<string> lsDirsInDir(const string &path);
|
vector<string> lsDirsInDir(const string &path);
|
||||||
|
|
||||||
|
|
176
src/main.cpp
176
src/main.cpp
|
@ -13,48 +13,32 @@
|
||||||
#include "mo_detect.h"
|
#include "mo_detect.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
void detectMoInFile(const string &detPath, const string &recPath, shared_t *share)
|
void detectMoInFile(const string &bufPath, shared_t *share)
|
||||||
{
|
{
|
||||||
if (fork() == 0)
|
detLog("detect_mo_in_file() -- start", share);
|
||||||
|
|
||||||
|
Mat thumbNail;
|
||||||
|
|
||||||
|
if (moDetect(bufPath, thumbNail, share))
|
||||||
{
|
{
|
||||||
detLog("detect_mo_in_file() -- start", share);
|
share->skipCmd = true;
|
||||||
|
|
||||||
share->detProcs++;
|
wrOut(bufPath, thumbNail, share);
|
||||||
|
|
||||||
if (exists(detPath))
|
|
||||||
{
|
|
||||||
Mat thumbNail;
|
|
||||||
|
|
||||||
if (moDetect(detPath, thumbNail, share))
|
|
||||||
{
|
|
||||||
share->skipCmd = true;
|
|
||||||
|
|
||||||
wrOut(recPath, thumbNail, share);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exists(detPath)) remove(detPath);
|
|
||||||
if (exists(recPath)) remove(recPath);
|
|
||||||
|
|
||||||
share->detProcs--;
|
|
||||||
|
|
||||||
detLog("detect_mo_in_file() -- finished", share);
|
|
||||||
}
|
}
|
||||||
}
|
else if (exists(bufPath))
|
||||||
|
|
||||||
void exeCmd(char *const argv[])
|
|
||||||
{
|
|
||||||
if (fork() == 0)
|
|
||||||
{
|
{
|
||||||
execvp("ffmpeg", argv);
|
remove(bufPath);
|
||||||
_Exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detLog("detect_mo_in_file() -- finished", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recLoop(shared_t *share)
|
void recLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
while (rdConf(share))
|
while (rdConf(share))
|
||||||
{
|
{
|
||||||
|
recLog("rec_loop() -- start", share);
|
||||||
|
|
||||||
enforceMaxLogSize(share->recLogPath, share);
|
enforceMaxLogSize(share->recLogPath, share);
|
||||||
enforceMaxLogSize(share->detLogPath, share);
|
enforceMaxLogSize(share->detLogPath, share);
|
||||||
|
|
||||||
|
@ -63,9 +47,7 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
initLogFrontPages(share);
|
initLogFrontPages(share);
|
||||||
|
|
||||||
recLog("rec_loop() -- start", share);
|
if (!exists("/tmp/mow-lock"))
|
||||||
|
|
||||||
if (!exists("/tmp/mow-lock") && share->updateRoot)
|
|
||||||
{
|
{
|
||||||
system("touch /tmp/mow-lock");
|
system("touch /tmp/mow-lock");
|
||||||
|
|
||||||
|
@ -74,71 +56,49 @@ void recLoop(shared_t *share)
|
||||||
|
|
||||||
remove("/tmp/mow-lock");
|
remove("/tmp/mow-lock");
|
||||||
recLog("webroot page updated: " + cleanDir(share->webRoot) + "/index.html", share);
|
recLog("webroot page updated: " + cleanDir(share->webRoot) + "/index.html", share);
|
||||||
|
}
|
||||||
share->updateRoot = false;
|
else
|
||||||
|
{
|
||||||
|
recLog("skipping update of the webroot page, it is busy.", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
genHTMLul(share->outDir, share->camName, share);
|
genHTMLul(share->outDir, share->camName, share);
|
||||||
|
|
||||||
recLog("camera specific webroot page updated: " + share->outDir + "/index.html", share);
|
recLog("camera specific webroot page updated: " + share->outDir + "/index.html", share);
|
||||||
|
|
||||||
auto strClipLen = to_string(share->clipLen);
|
for (auto i = 0; i < share->numOfClips; ++i)
|
||||||
|
|
||||||
char* argvRec[] = {(char*) "ffmpeg",
|
|
||||||
(char*) "-hide_banner",
|
|
||||||
(char*) "-i",
|
|
||||||
(char*) share->recordUrl.c_str(),
|
|
||||||
(char*) "-y",
|
|
||||||
(char*) "-vcodec",
|
|
||||||
(char*) share->vidCodec.c_str(),
|
|
||||||
(char*) "-t",
|
|
||||||
(char*) strClipLen.c_str(),
|
|
||||||
(char*) "--replace_me--",
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
char* argvDet[] = {(char*) "ffmpeg",
|
|
||||||
(char*) "-hide_banner",
|
|
||||||
(char*) "-i",
|
|
||||||
(char*) share->detectUrl.c_str(),
|
|
||||||
(char*) "-y",
|
|
||||||
(char*) "-vcodec",
|
|
||||||
(char*) share->vidCodec.c_str(),
|
|
||||||
(char*) "-t",
|
|
||||||
(char*) strClipLen.c_str(),
|
|
||||||
(char*) "--replace_me--",
|
|
||||||
NULL};
|
|
||||||
|
|
||||||
for (auto i = 0; i < share->numOfClips; ++i, ++share->index)
|
|
||||||
{
|
{
|
||||||
auto detPath = cleanDir(share->buffDir) + "/" + to_string(share->index) + share->detSuffix;
|
auto bufPath = cleanDir(share->buffDir) + "/" + to_string(i) + "." + share->vidExt;
|
||||||
auto recPath = cleanDir(share->buffDir) + "/" + to_string(share->index) + share->recSuffix;
|
auto cmd = "timeout -k 1 " + to_string(share->clipLen + 2) + " ";
|
||||||
|
|
||||||
if (share->recordUrl == share->detectUrl)
|
cmd += "ffmpeg -hide_banner -i " + share->recordUrl + " -y -vcodec " + share->vidCodec + " -movflags faststart -t " + to_string(share->clipLen) + " " + bufPath;
|
||||||
|
|
||||||
|
recLog("ffmpeg_run: " + cmd, share);
|
||||||
|
|
||||||
|
auto retCode = system(cmd.c_str());
|
||||||
|
|
||||||
|
recLog("ffmpeg_retcode: " + to_string(retCode), share);
|
||||||
|
|
||||||
|
if (retCode == 0)
|
||||||
{
|
{
|
||||||
recPath = detPath;
|
recLog("detect_mo_in_file() -- started in a seperate thread.", share);
|
||||||
}
|
|
||||||
|
|
||||||
argvRec[PATH_ADDR] = (char*) recPath.c_str();
|
share->detThreads.push_back(thread(detectMoInFile, bufPath, share));
|
||||||
argvDet[PATH_ADDR] = (char*) detPath.c_str();
|
|
||||||
|
|
||||||
recLog("fetching camera footage -- ", share);
|
|
||||||
|
|
||||||
if (share->recordUrl == share->detectUrl)
|
|
||||||
{
|
|
||||||
exeCmd(argvDet);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exeCmd(argvDet);
|
recLog("ffmpeg returned non zero, indicating failure. please check stderr output.", share);
|
||||||
exeCmd(argvRec);
|
|
||||||
|
if (exists(bufPath))
|
||||||
|
{
|
||||||
|
remove(bufPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(share->clipLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(share->clipLen * 2);
|
|
||||||
|
|
||||||
detectMoInFile(detPath, recPath, share);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (share->detProcs > 0) sleep(1);
|
waitForDetThreads(share);
|
||||||
|
|
||||||
if (!share->skipCmd)
|
if (!share->skipCmd)
|
||||||
{
|
{
|
||||||
|
@ -151,8 +111,7 @@ void recLoop(shared_t *share)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
recLog("running post command: " + share->postCmd, share);
|
recLog("running post command: " + share->postCmd, share);
|
||||||
|
system(share->postCmd.c_str());
|
||||||
system(string("timeout -k 1 14 " + share->postCmd).c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -166,52 +125,26 @@ void recLoop(shared_t *share)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_at(argvDet);
|
|
||||||
destroy_at(argvRec);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigHandler(int signal, siginfo_t *info, void *context)
|
|
||||||
{
|
|
||||||
cerr << "received signal details: " << endl;
|
|
||||||
cerr << "-- si_pid: " << info->si_pid << endl;
|
|
||||||
cerr << "-- si_signo: " << info->si_signo << endl;
|
|
||||||
cerr << "-- si_code: " << info->si_code << endl;
|
|
||||||
cerr << "-- si_errno: " << info->si_errno << endl;
|
|
||||||
cerr << "-- si_uid: " << info->si_uid << endl;
|
|
||||||
cerr << "-- si_addr: " << info->si_addr << endl;
|
|
||||||
cerr << "-- si_status: " << info->si_status << endl;
|
|
||||||
cerr << "-- si_band: " << info->si_band << endl;
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
struct shared_t sharedRes;
|
struct shared_t sharedRes;
|
||||||
|
|
||||||
struct sigaction act = { 0 };
|
sharedRes.conf = parseForList("-c", argc, argv);
|
||||||
|
|
||||||
act.sa_flags = SA_SIGINFO;
|
|
||||||
act.sa_sigaction = &sigHandler;
|
|
||||||
|
|
||||||
sigaction(SIGTERM, &act, NULL);
|
|
||||||
sigaction(SIGABRT, &act, NULL);
|
|
||||||
sigaction(SIGSEGV, &act, NULL);
|
|
||||||
sigaction(SIGILL, &act, NULL);
|
|
||||||
sigaction(SIGFPE, &act, NULL);
|
|
||||||
sigaction(SIGBUS, &act, NULL);
|
|
||||||
|
|
||||||
sharedRes.conf = parseForParam("-c", argc, argv, false);
|
|
||||||
|
|
||||||
if (parseForParam("-h", argc, argv, true) == "true")
|
if (parseForParam("-h", argc, argv, true) == "true")
|
||||||
{
|
{
|
||||||
cout << "Motion Watch " << APP_VER << endl << endl;
|
cout << "Motion Watch " << APP_VER << endl << endl;
|
||||||
cout << "Usage: mow <argument>" << endl << endl;
|
cout << "Usage: mow <argument>" << endl << endl;
|
||||||
cout << "-h : display usage information about this application." << endl;
|
cout << "-h : display usage information about this application." << endl;
|
||||||
cout << "-c : path to the config file." << endl;
|
cout << "-c : path to a config file." << endl;
|
||||||
cout << "-v : display the current version." << endl << endl;
|
cout << "-v : display the current version." << endl << endl;
|
||||||
|
cout << "note: multiple -c config files can be passed, reading from left" << endl;
|
||||||
|
cout << " to right. any conflicting values between the files will" << endl;
|
||||||
|
cout << " have the latest value from the latest file overwrite the" << endl;
|
||||||
|
cout << " the earliest." << endl;
|
||||||
}
|
}
|
||||||
else if (parseForParam("-v", argc, argv, true) == "true")
|
else if (parseForParam("-v", argc, argv, true) == "true")
|
||||||
{
|
{
|
||||||
|
@ -219,16 +152,13 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else if (sharedRes.conf.empty())
|
else if (sharedRes.conf.empty())
|
||||||
{
|
{
|
||||||
cerr << "err: config file not given in -c" << endl;
|
cerr << "err: no config file(s) were given in -c" << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sharedRes.retCode = 0;
|
sharedRes.retCode = 0;
|
||||||
sharedRes.detProcs = 0;
|
sharedRes.skipCmd = false;
|
||||||
sharedRes.index = 0;
|
sharedRes.init = true;
|
||||||
sharedRes.updateRoot = true;
|
|
||||||
sharedRes.skipCmd = false;
|
|
||||||
sharedRes.init = true;
|
|
||||||
|
|
||||||
recLoop(&sharedRes);
|
recLoop(&sharedRes);
|
||||||
|
|
||||||
|
|
|
@ -95,31 +95,16 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share)
|
||||||
detLog("wr_out() -- finished()", share);
|
detLog("wr_out() -- finished()", share);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool openVid(const string &buffFile, VideoCapture &cap)
|
|
||||||
{
|
|
||||||
auto ret = cap.open(buffFile.c_str(), CAP_FFMPEG);
|
|
||||||
|
|
||||||
for (auto i = 0; (i < 3) && !ret; ++i)
|
|
||||||
{
|
|
||||||
sleep(1);
|
|
||||||
|
|
||||||
ret = cap.open(buffFile.c_str(), CAP_FFMPEG);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
||||||
{
|
{
|
||||||
detLog("mo_detect() -- start()", share);
|
detLog("mo_detect() -- start()", share);
|
||||||
detLog("buff_file: " + buffFile, share);
|
detLog("buff_file: " + buffFile, share);
|
||||||
|
|
||||||
auto mod = false;
|
auto mod = false;
|
||||||
auto trys = 0;
|
|
||||||
|
|
||||||
VideoCapture capture;
|
VideoCapture capture(buffFile.c_str(), CAP_FFMPEG);
|
||||||
|
|
||||||
if (openVid(buffFile, capture))
|
if (capture.isOpened())
|
||||||
{
|
{
|
||||||
Mat prev;
|
Mat prev;
|
||||||
Mat next;
|
Mat next;
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "web.h"
|
#include "web.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
bool openVid(const string &buffFile, VideoCapture &cap);
|
|
||||||
bool imgDiff(const Mat &prev, const Mat &next, shared_t *share);
|
bool imgDiff(const Mat &prev, const Mat &next, shared_t *share);
|
||||||
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share);
|
bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share);
|
||||||
void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share);
|
void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user