Compare commits
No commits in common. "25528617d5c1e346d04e7c4c297472ddb2602bae" and "ff5f95f44562b2530c32c9049851f6dac9a6bda5" have entirely different histories.
25528617d5
...
ff5f95f445
|
@ -40,11 +40,6 @@ web_root = /var/www/html
|
||||||
# warning: this will overwrite any existing index.html files so be sure
|
# warning: this will overwrite any existing index.html files so be sure
|
||||||
# to choose a directory that doesn't have an existing website.
|
# to choose a directory that doesn't have an existing website.
|
||||||
#
|
#
|
||||||
buffer_path = /tmp
|
|
||||||
# this is the work directory the app will use to store live footage and
|
|
||||||
# image frames. it's recommended to use a ram disk for this since there
|
|
||||||
# will be large amounts of io occuring here.
|
|
||||||
#
|
|
||||||
cam_name = cam-1
|
cam_name = cam-1
|
||||||
# this is the optional camera name parameter to identify the camera. this
|
# this is the optional camera name parameter to identify the camera. this
|
||||||
# name will also be used to as the base directory in web_root. if not
|
# name will also be used to as the base directory in web_root. if not
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
apt install apache2
|
||||||
if [ ! -d "/opt/mow" ]; then
|
if [ ! -d "/opt/mow" ]; then
|
||||||
mkdir /opt/mow
|
mkdir /opt/mow
|
||||||
fi
|
fi
|
||||||
cp ./.build-mow/mow /opt/mow/bin
|
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_VIDEOIO_DEBUG=1\n" >> /opt/mow/run
|
||||||
printf "/opt/mow/bin \$1 \$2 \$3\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
|
||||||
|
|
|
@ -25,7 +25,6 @@ Camera::Camera(QObject *parent) : QObject(parent)
|
||||||
shared.skipCmd = false;
|
shared.skipCmd = false;
|
||||||
shared.postSecs = 60;
|
shared.postSecs = 60;
|
||||||
shared.evMaxSecs = 30;
|
shared.evMaxSecs = 30;
|
||||||
shared.buffPath = QDir::tempPath();
|
|
||||||
shared.webRoot = "/var/www/html";
|
shared.webRoot = "/var/www/html";
|
||||||
shared.webBg = "#485564";
|
shared.webBg = "#485564";
|
||||||
shared.webTxt = "#dee5ee";
|
shared.webTxt = "#dee5ee";
|
||||||
|
@ -38,6 +37,14 @@ int Camera::start(const QStringList &args)
|
||||||
|
|
||||||
if (rdConf(&shared))
|
if (rdConf(&shared))
|
||||||
{
|
{
|
||||||
|
QDir("live").removeRecursively();
|
||||||
|
QDir("img").removeRecursively();
|
||||||
|
|
||||||
|
QDir().mkdir("live");
|
||||||
|
QDir().mkdir("events");
|
||||||
|
QDir().mkdir("logs");
|
||||||
|
QDir().mkdir("img");
|
||||||
|
|
||||||
auto thr1 = new QThread(nullptr);
|
auto thr1 = new QThread(nullptr);
|
||||||
auto thr2 = new QThread(nullptr);
|
auto thr2 = new QThread(nullptr);
|
||||||
auto thr3 = new QThread(nullptr);
|
auto thr3 = new QThread(nullptr);
|
||||||
|
@ -208,6 +215,11 @@ Upkeep::Upkeep(shared_t *sharedRes, QThread *thr, QObject *parent) : Loop(shared
|
||||||
|
|
||||||
bool Upkeep::exec()
|
bool Upkeep::exec()
|
||||||
{
|
{
|
||||||
|
QDir().mkdir("live");
|
||||||
|
QDir().mkdir("events");
|
||||||
|
QDir().mkdir("logs");
|
||||||
|
QDir().mkdir("img");
|
||||||
|
|
||||||
enforceMaxLogSize(QString("logs/") + REC_LOG_NAME, shared);
|
enforceMaxLogSize(QString("logs/") + REC_LOG_NAME, shared);
|
||||||
enforceMaxLogSize(QString("logs/") + DET_LOG_NAME, shared);
|
enforceMaxLogSize(QString("logs/") + DET_LOG_NAME, shared);
|
||||||
|
|
||||||
|
@ -241,7 +253,7 @@ EventLoop::EventLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : Loop(
|
||||||
|
|
||||||
bool EventLoop::exec()
|
bool EventLoop::exec()
|
||||||
{
|
{
|
||||||
if (!vidList.isEmpty())
|
if (cycles * 2 >= shared->evMaxSecs)
|
||||||
{
|
{
|
||||||
vidList.removeDuplicates();
|
vidList.removeDuplicates();
|
||||||
|
|
||||||
|
@ -270,45 +282,31 @@ bool EventLoop::exec()
|
||||||
|
|
||||||
vidList.clear();
|
vidList.clear();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cycles += 1;
|
||||||
|
|
||||||
shared->recMutex.lock();
|
shared->recMutex.lock();
|
||||||
|
|
||||||
QList<int> rmIndx;
|
for (auto &&event : shared->recList)
|
||||||
|
|
||||||
for (auto i = 0; i < shared->recList.size(); ++i)
|
|
||||||
{
|
{
|
||||||
auto event = &shared->recList[i];
|
auto maxFiles = shared->evMaxSecs / 2;
|
||||||
|
// there's 2 secs in each hls segment
|
||||||
|
|
||||||
if (highScore < event->score)
|
if (highScore < event.score)
|
||||||
{
|
{
|
||||||
name = event->timeStamp.toString(DATETIME_FMT);
|
name = event.timeStamp.toString(DATETIME_FMT);
|
||||||
imgPath = event->imgPath;
|
imgPath = event.imgPath;
|
||||||
highScore = event->score;
|
highScore = event.score;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->queAge >= (shared->evMaxSecs / heartBeat))
|
vidList.append(backwardFacingFiles("live", ".ts", event.timeStamp, maxFiles / 2));
|
||||||
{
|
vidList.append(forwardFacingFiles("live", ".ts", event.timeStamp, maxFiles / 2));
|
||||||
auto maxSecs = shared->evMaxSecs / 2;
|
|
||||||
// half the maxsecs value to get front-back half secs
|
|
||||||
|
|
||||||
auto backFiles = backwardFacingFiles("live", ".ts", event->timeStamp, maxSecs);
|
|
||||||
auto frontFiles = forwardFacingFiles("live", ".ts", event->timeStamp, maxSecs);
|
|
||||||
|
|
||||||
vidList.append(backFiles + frontFiles);
|
|
||||||
rmIndx.append(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
event->queAge += heartBeat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i : rmIndx)
|
|
||||||
{
|
|
||||||
shared->recList.removeAt(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared->recList.clear();
|
||||||
shared->recMutex.unlock();
|
shared->recMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
return Loop::exec();
|
return Loop::exec();
|
||||||
}
|
}
|
||||||
|
@ -379,9 +377,9 @@ DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : Loo
|
||||||
{
|
{
|
||||||
pcTimer = 0;
|
pcTimer = 0;
|
||||||
heartBeat = 2;
|
heartBeat = 2;
|
||||||
delayCycles = 12; // this will be used to delay the
|
delayCycles = 8; // this will be used to delay the
|
||||||
// actual start of DetectLoop by
|
// actual start of DetectLoop by
|
||||||
// 24secs.
|
// 16secs.
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetectLoop::init()
|
void DetectLoop::init()
|
||||||
|
@ -475,7 +473,6 @@ bool DetectLoop::exec()
|
||||||
event.timeStamp = curDT;
|
event.timeStamp = curDT;
|
||||||
event.score = score;
|
event.score = score;
|
||||||
event.imgPath = images[pos];
|
event.imgPath = images[pos];
|
||||||
event.queAge = 0;
|
|
||||||
|
|
||||||
shared->recMutex.lock();
|
shared->recMutex.lock();
|
||||||
shared->recList.append(event); mod = true;
|
shared->recList.append(event); mod = true;
|
||||||
|
|
|
@ -167,21 +167,6 @@ void rdLine(const QString ¶m, const QString &line, int *value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void touch(const QString &path)
|
|
||||||
{
|
|
||||||
if (!QFile::exists(path))
|
|
||||||
{
|
|
||||||
QFile file(path);
|
|
||||||
|
|
||||||
if (file.open(QFile::WriteOnly))
|
|
||||||
{
|
|
||||||
file.write("");
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rdConf(const QString &filePath, shared_t *share)
|
bool rdConf(const QString &filePath, shared_t *share)
|
||||||
{
|
{
|
||||||
QFile varFile(filePath);
|
QFile varFile(filePath);
|
||||||
|
@ -204,7 +189,6 @@ bool rdConf(const QString &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("buffer_path = ", line, &share->buffPath);
|
|
||||||
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);
|
||||||
|
@ -233,29 +217,10 @@ bool rdConf(shared_t *share)
|
||||||
}
|
}
|
||||||
|
|
||||||
share->outDir = QDir().cleanPath(share->webRoot) + "/" + share->camName;
|
share->outDir = QDir().cleanPath(share->webRoot) + "/" + share->camName;
|
||||||
share->tmpDir = share->buffPath + "/" + APP_BIN + "/" + share->camName;
|
|
||||||
|
|
||||||
QDir().mkpath(share->outDir);
|
QDir().mkpath(share->outDir);
|
||||||
QDir().mkpath(share->tmpDir);
|
|
||||||
|
|
||||||
QDir().mkpath(share->outDir + "/events");
|
if (!QDir::setCurrent(share->outDir))
|
||||||
QDir().mkpath(share->tmpDir + "/live");
|
|
||||||
QDir().mkpath(share->tmpDir + "/logs");
|
|
||||||
QDir().mkpath(share->tmpDir + "/img");
|
|
||||||
|
|
||||||
touch(share->tmpDir + "/index.html");
|
|
||||||
touch(share->tmpDir + "/stream.html");
|
|
||||||
touch(share->tmpDir + "/stream.m3u8");
|
|
||||||
|
|
||||||
QFile::link(share->tmpDir + "/live", share->outDir + "/live");
|
|
||||||
QFile::link(share->tmpDir + "/logs", share->outDir + "/logs");
|
|
||||||
QFile::link(share->tmpDir + "/img", share->outDir + "/img");
|
|
||||||
QFile::link(share->tmpDir + "/index.html", share->outDir + "/index.html");
|
|
||||||
QFile::link(share->tmpDir + "/stream.html", share->outDir + "/stream.html");
|
|
||||||
QFile::link(share->tmpDir + "/stream.m3u8", share->outDir + "/stream.m3u8");
|
|
||||||
QFile::link(share->outDir + "/events", share->tmpDir + "/events");
|
|
||||||
|
|
||||||
if (!QDir::setCurrent(share->tmpDir))
|
|
||||||
{
|
{
|
||||||
QTextStream(stderr) << "err: failed to change/create the current working directory to camera folder: '" << share->outDir << "' does it exists?" << Qt::endl;
|
QTextStream(stderr) << "err: failed to change/create the current working directory to camera folder: '" << share->outDir << "' does it exists?" << Qt::endl;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define APP_VER "3.1"
|
#define APP_VER "3.0.0"
|
||||||
#define APP_NAME "Motion Watch"
|
#define APP_NAME "Motion Watch"
|
||||||
#define APP_BIN "mow"
|
#define APP_BIN "mow"
|
||||||
#define REC_LOG_NAME "rec_log_lines.html"
|
#define REC_LOG_NAME "rec_log_lines.html"
|
||||||
|
@ -45,7 +45,6 @@ struct evt_t
|
||||||
QDateTime timeStamp;
|
QDateTime timeStamp;
|
||||||
QString imgPath;
|
QString imgPath;
|
||||||
float score;
|
float score;
|
||||||
uint queAge;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct shared_t
|
struct shared_t
|
||||||
|
@ -58,8 +57,6 @@ struct shared_t
|
||||||
QString detLog;
|
QString detLog;
|
||||||
QString recordUrl;
|
QString recordUrl;
|
||||||
QString outDir;
|
QString outDir;
|
||||||
QString tmpDir;
|
|
||||||
QString buffPath;
|
|
||||||
QString postCmd;
|
QString postCmd;
|
||||||
QString camName;
|
QString camName;
|
||||||
QString webBg;
|
QString webBg;
|
||||||
|
@ -83,7 +80,6 @@ QStringList backwardFacingFiles(const QString &path, const QString &ext, const Q
|
||||||
QStringList forwardFacingFiles(const QString &path, const QString &ext, const QDateTime &stamp, int secs);
|
QStringList forwardFacingFiles(const QString &path, const QString &ext, const QDateTime &stamp, int secs);
|
||||||
bool rdConf(const QString &filePath, shared_t *share);
|
bool rdConf(const QString &filePath, shared_t *share);
|
||||||
bool rdConf(shared_t *share);
|
bool rdConf(shared_t *share);
|
||||||
void touch(const QString &path);
|
|
||||||
void rdLine(const QString ¶m, const QString &line, QString *value);
|
void rdLine(const QString ¶m, const QString &line, QString *value);
|
||||||
void rdLine(const QString ¶m, const QString &line, int *value);
|
void rdLine(const QString ¶m, const QString &line, int *value);
|
||||||
void enforceMaxEvents(shared_t *share);
|
void enforceMaxEvents(shared_t *share);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user