diff --git a/src/common.h b/src/common.h index 663c135..39a26c1 100644 --- a/src/common.h +++ b/src/common.h @@ -32,10 +32,11 @@ using namespace std; -#define APP_VERSION "3.6.t6" +#define APP_VERSION "3.6.t7" #define APP_NAME "JustMotion" #define APP_TARGET "jmotion" #define DATETIME_FMT "yyyyMMddhhmmss" +#define STRFTIME_FMT "%Y%m%d%H%M%S" #define PREV_IMG "&prev&" #define NEXT_IMG "&next&" @@ -73,7 +74,6 @@ struct shared_t QString thumbExt; QString recScale; QString imgScale; - quint64 seed; bool singleTenant; bool skipCmd; int liveSecs; diff --git a/src/detect_loop.cpp b/src/detect_loop.cpp index b709137..b92db0d 100644 --- a/src/detect_loop.cpp +++ b/src/detect_loop.cpp @@ -12,10 +12,9 @@ #include "detect_loop.h" -DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QObject(parent) +DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QFileSystemWatcher(parent) { pcTimer = 0; - deTimer = 0; shared = sharedRes; connect(thr, &QThread::started, this, &DetectLoop::init); @@ -27,17 +26,14 @@ DetectLoop::DetectLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QOb void DetectLoop::init() { pcTimer = new QTimer(this); - deTimer = new QTimer(this); connect(pcTimer, &QTimer::timeout, this, &DetectLoop::pcBreak); - connect(deTimer, &QTimer::timeout, this, &DetectLoop::preExec); - - thread()->sleep(2); // delay detection kickoff by 2 seconds to allow RecLoop to buffer + connect(this, &QFileSystemWatcher::directoryChanged, this, &DetectLoop::updated); pcTimer->start(shared->postSecs * 1000); - deTimer->start(2000); setupBuffDir(shared->buffPath); + addPath(shared->buffPath + "/live"); } void DetectLoop::reset() @@ -51,21 +47,26 @@ void DetectLoop::reset() eventQue.timeStamp.clear(); } -void DetectLoop::preExec() +void DetectLoop::updated(const QString &path) { - vidAPath = shared->buffPath + "/live/" + QString::number(shared->seed - 1).rightJustified(14, '0') + shared->streamExt; - vidBPath = shared->buffPath + "/live/" + QString::number(shared->seed - 2).rightJustified(14, '0') + shared->streamExt; - eTimer.start(); - auto vidAInfo = QFileInfo(vidAPath); - auto vidBInfo = QFileInfo(vidBPath); + auto clips = lsFilesInDir(path, shared->streamExt); + auto index = clips.indexOf(vidBName); - if (vidAInfo.exists() && vidAInfo.size() > 0 && vidBInfo.exists() && vidBInfo.size() > 0) + if (clips.size() - (index + 1) < 3) { - shared->seed += 1; + thread()->sleep(1); + } + else + { + vidAName = clips[clips.size() - 3]; + vidBName = clips[clips.size() - 2]; - exec(); + vidAPath = shared->buffPath + "/live/" + vidAName; + vidBPath = shared->buffPath + "/live/" + vidBName; + + exec(); thread()->sleep(1); } } @@ -246,4 +247,7 @@ void DetectLoop::exec() } } } + + vidAPath.clear(); + vidBPath.clear(); } diff --git a/src/detect_loop.h b/src/detect_loop.h index 305a427..ebd2c5c 100644 --- a/src/detect_loop.h +++ b/src/detect_loop.h @@ -15,7 +15,7 @@ #include "common.h" -class DetectLoop : public QObject +class DetectLoop : public QFileSystemWatcher { Q_OBJECT @@ -23,9 +23,10 @@ private: QString vidAPath; QString vidBPath; + QString vidAName; + QString vidBName; QStringList prevClips; QTimer *pcTimer; - QTimer *deTimer; QElapsedTimer eTimer; evt_t eventQue; shared_t *shared; @@ -39,7 +40,7 @@ private slots: void init(); void reset(); void pcBreak(); - void preExec(); + void updated(const QString &path); public: diff --git a/src/record_loop.cpp b/src/record_loop.cpp index 351cb05..eb949b5 100644 --- a/src/record_loop.cpp +++ b/src/record_loop.cpp @@ -15,11 +15,8 @@ RecordLoop::RecordLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QProcess(parent) { checkTimer = 0; - seedtimer = 0; shared = sharedRes; - sharedRes->seed = 2; - connect(thr, &QThread::started, this, &RecordLoop::init); connect(thr, &QThread::finished, this, &RecordLoop::deleteLater); @@ -39,68 +36,38 @@ RecordLoop::~RecordLoop() void RecordLoop::init() { checkTimer = new QTimer(this); - seedtimer = new QTimer(this); connect(checkTimer, &QTimer::timeout, this, &RecordLoop::restart); - connect(seedtimer, &QTimer::timeout, this, &RecordLoop::checkSeed); checkTimer->setSingleShot(true); checkTimer->setInterval(3000); - seedtimer->setInterval(1000); setupBuffDir(shared->buffPath); restart(); } -QStringList RecordLoop::camCmdFromConf() +QString RecordLoop::camCmdFromConf() { - QStringList ret; - - ret.append("ffmpeg"); ret.append("-hide_banner"); ret.append("-y"); ret.append("-i"); - ret.append(shared->recordUri); + auto ret = "ffmpeg -hide_banner -y -i '" + shared->recordUri + "' -strftime 1 -strftime_mkdir 1 "; if (shared->recordUri.contains("rtsp")) { - ret.append("-rtsp_transport"); - ret.append("udp"); + ret += "-rtsp_transport udp "; } if (shared->vidCodec != "copy") { - ret.append("-vf"); - ret.append("fps=" + QString::number(shared->recFps) + ",scale=" + shared->recScale); + ret += "-vf fps=" + QString::number(shared->recFps) + ",scale=" + shared->recScale + " "; } - ret.append("-vcodec"); ret.append(shared->vidCodec); - ret.append("-acodec"); ret.append(shared->audCodec); - - ret.append("-reset_timestamps"); ret.append("1"); - ret.append("-sc_threshold"); ret.append("0"); - ret.append("-g"); ret.append("2"); - ret.append("-force_key_frames"); ret.append("expr:gte(t, n_forced * 2)"); - ret.append("-segment_time"); ret.append("2"); - ret.append("-f"); ret.append("segment"); - - ret.append(shared->buffPath + "/live/%014d" + shared->streamExt); + ret += "-vcodec " + shared->vidCodec + " "; + ret += "-acodec " + shared->audCodec + " "; + ret += "-reset_timestamps 1 -sc_threshold 0 -g 2 -force_key_frames 'expr:gte(t, n_forced * 2)' -segment_time 2 -f segment "; + ret += shared->buffPath + "/live/" + QString(STRFTIME_FMT) + shared->streamExt; return ret; } -void RecordLoop::checkSeed() -{ - if (shared->seed >= 99999999999999ULL) - { - terminate(); - waitForFinished(); - - setupBuffDir(shared->buffPath, true); - - shared->seed = 2; - - restart(); - } -} - QString RecordLoop::statusLine() { if (state() == QProcess::Running) @@ -120,17 +87,16 @@ void RecordLoop::resetTime() void RecordLoop::restart() { - checkTimer->start(); - if (state() == QProcess::Running) { terminate(); waitForFinished(); } - auto args = camCmdFromConf(); + auto cmdLine = camCmdFromConf(); + auto args = parseArgs(cmdLine.toUtf8(), -1); - qInfo() << "start recording command: " << args.join(' '); + qInfo() << "start recording command: " << cmdLine; if (args.isEmpty()) { diff --git a/src/record_loop.h b/src/record_loop.h index c721fb4..494a779 100644 --- a/src/record_loop.h +++ b/src/record_loop.h @@ -22,17 +22,14 @@ class RecordLoop : public QProcess private slots: void init(); - void checkSeed(); void resetTime(); private: shared_t *shared; - QTimer *seedtimer; QTimer *checkTimer; - quint64 getLatestSeed(); - QStringList camCmdFromConf(); + QString camCmdFromConf(); public slots: