v1.5.t16
The app is still failing with intermittent moov atom failures on trying to open the video clips with opencv VideoCapture. I suspect it is trying to open the files while ffmpeg is not done finalizing them. Reformed the detection loop to spawn dedicated motion detection threads for each video clip and only when ffmpeg confirmed finished.
This commit is contained in:
parent
ad4a6357b4
commit
b470915276
|
@ -202,7 +202,6 @@ bool rdConf(shared_t *share)
|
|||
share->buffDir = "/tmp";
|
||||
share->vidExt = "mp4";
|
||||
share->vidCodec = "copy";
|
||||
share->recLoopWait = false;
|
||||
share->skipCmd = false;
|
||||
share->webBg = "#485564";
|
||||
share->webTxt = "#dee5ee";
|
||||
|
@ -284,3 +283,13 @@ string parseForParam(const string &arg, int argc, char** argv, bool argOnly)
|
|||
|
||||
return string();
|
||||
}
|
||||
|
||||
void waitForDetThreads(shared_t *share)
|
||||
{
|
||||
for (auto &&thr : share->detThreads)
|
||||
{
|
||||
thr.join();
|
||||
}
|
||||
|
||||
share->detThreads.clear();
|
||||
}
|
||||
|
|
59
src/common.h
59
src/common.h
|
@ -35,40 +35,38 @@ using namespace cv;
|
|||
using namespace std;
|
||||
using namespace std::filesystem;
|
||||
|
||||
#define APP_VER "1.5.t15"
|
||||
#define APP_VER "1.5.t16"
|
||||
#define APP_NAME "Motion Watch"
|
||||
|
||||
struct shared_t
|
||||
{
|
||||
|
||||
ofstream recLogFile;
|
||||
ofstream detLogFile;
|
||||
string recLogPath;
|
||||
string detLogPath;
|
||||
string recordUrl;
|
||||
string outDir;
|
||||
string postCmd;
|
||||
string conf;
|
||||
string buffDir;
|
||||
string vidExt;
|
||||
string vidCodec;
|
||||
string camName;
|
||||
string webBg;
|
||||
string webTxt;
|
||||
string webFont;
|
||||
string webRoot;
|
||||
bool init;
|
||||
bool recLoopWait;
|
||||
bool logRun;
|
||||
bool skipCmd;
|
||||
int frameGap;
|
||||
int pixThresh;
|
||||
int imgThresh;
|
||||
int secs;
|
||||
int maxDays;
|
||||
int maxClips;
|
||||
int maxLogSize;
|
||||
int retCode;
|
||||
vector<thread> detThreads;
|
||||
ofstream recLogFile;
|
||||
ofstream detLogFile;
|
||||
string recLogPath;
|
||||
string detLogPath;
|
||||
string recordUrl;
|
||||
string outDir;
|
||||
string postCmd;
|
||||
string conf;
|
||||
string buffDir;
|
||||
string vidExt;
|
||||
string vidCodec;
|
||||
string camName;
|
||||
string webBg;
|
||||
string webTxt;
|
||||
string webFont;
|
||||
string webRoot;
|
||||
bool init;
|
||||
bool skipCmd;
|
||||
int frameGap;
|
||||
int pixThresh;
|
||||
int imgThresh;
|
||||
int secs;
|
||||
int maxDays;
|
||||
int maxClips;
|
||||
int maxLogSize;
|
||||
int retCode;
|
||||
};
|
||||
|
||||
string genDstFile(const string &dirOut, const char *fmt, const string &ext);
|
||||
|
@ -82,6 +80,7 @@ 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, int *value);
|
||||
void statOut(shared_t *share);
|
||||
void waitForDetThreads(shared_t *share);
|
||||
bool rdConf(shared_t *share);
|
||||
vector<string> lsFilesInDir(const string &path, const string &ext = string());
|
||||
vector<string> lsDirsInDir(const string &path);
|
||||
|
|
101
src/main.cpp
101
src/main.cpp
|
@ -13,57 +13,24 @@
|
|||
#include "mo_detect.h"
|
||||
#include "logger.h"
|
||||
|
||||
void detectLoop(shared_t *share)
|
||||
void detectMoInFile(const string &bufPath, shared_t *share)
|
||||
{
|
||||
detLog("detect_loop() -- start", share);
|
||||
detLog("detect_mo_in_file() -- start", share);
|
||||
|
||||
vector<string> bufFiles;
|
||||
auto waitingForFiles = 0;
|
||||
Mat thumbNail;
|
||||
|
||||
do
|
||||
if (moDetect(bufPath, thumbNail, share))
|
||||
{
|
||||
bufFiles = lsFilesInDir(share->buffDir, "." + share->vidExt);
|
||||
share->skipCmd = true;
|
||||
|
||||
// this loop will not process the last buffile while recLoop is still actively
|
||||
// pulling footage from ffmpeg. it is assumed the last file is not finished.
|
||||
// share->recLoopWait is used to detect if the recloop is still pulling. if not
|
||||
// then the last file is finally processed.
|
||||
|
||||
if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty()))
|
||||
{
|
||||
auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0];
|
||||
Mat thumbNail;
|
||||
|
||||
if (moDetect(fullPath, thumbNail, share))
|
||||
{
|
||||
share->skipCmd = true;
|
||||
|
||||
wrOut(fullPath, thumbNail, share);
|
||||
}
|
||||
else if (exists(fullPath))
|
||||
{
|
||||
remove(fullPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waitingForFiles >= share->secs)
|
||||
{
|
||||
detLog("timed out waiting for buff files from ffmpeg, did it fail?", share);
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
detLog(to_string(bufFiles.size()) + " buff file(s) found, waiting for more.", share);
|
||||
}
|
||||
|
||||
sleep(5); waitingForFiles += 5;
|
||||
}
|
||||
wrOut(bufPath, thumbNail, share);
|
||||
}
|
||||
else if (exists(bufPath))
|
||||
{
|
||||
remove(bufPath);
|
||||
}
|
||||
while (!share->recLoopWait || !bufFiles.empty());
|
||||
|
||||
detLog("detect_loop() -- finished", share);
|
||||
detLog("detect_mo_in_file() -- finished", share);
|
||||
}
|
||||
|
||||
void recLoop(shared_t *share)
|
||||
|
@ -99,29 +66,39 @@ void recLoop(shared_t *share)
|
|||
|
||||
recLog("camera specific webroot page updated: " + share->outDir + "/index.html", share);
|
||||
|
||||
auto bufPath = cleanDir(share->buffDir) + "/%03d." + share->vidExt;
|
||||
auto secs = to_string(share->secs);
|
||||
auto limSecs = to_string(share->secs + 3);
|
||||
auto cmd = "timeout -k 1 " + limSecs + " ffmpeg -hide_banner -i " + share->recordUrl + " -y -vcodec " + share->vidCodec + " -movflags faststart -map 0 -segment_time 00:00:10 -f segment -t " + secs + " " + bufPath;
|
||||
for (auto i = 0; i < share->secs; i += 10)
|
||||
{
|
||||
auto bufPath = cleanDir(share->buffDir) + "/" + to_string(i) + "." + share->vidExt;
|
||||
auto cmd = "ffmpeg -hide_banner -i " + share->recordUrl + " -y vcodec " + share->vidCodec + " -movflags faststart -t 10 " + bufPath;
|
||||
|
||||
thread th2(detectLoop, share);
|
||||
recLog("ffmpeg_run: " + cmd, share);
|
||||
|
||||
recLog("detect_loop() -- started in a seperate thread.", share);
|
||||
recLog("ffmpeg_run: " + cmd, share);
|
||||
auto retCode = system(cmd.c_str());
|
||||
|
||||
auto retCode = system(cmd.c_str());
|
||||
recLog("ffmpeg_retcode: " + to_string(retCode), share);
|
||||
|
||||
recLog("ffmpeg_retcode: " + to_string(retCode), share);
|
||||
if (retCode == 0)
|
||||
{
|
||||
recLog("detect_mo_in_file() -- started in a seperate thread.", share);
|
||||
|
||||
share->recLoopWait = true;
|
||||
share->detThreads.push_back(thread(detectMoInFile, bufPath, share));
|
||||
}
|
||||
else
|
||||
{
|
||||
recLog("ffmpeg returned non zero, indicating failure. please check stderr output.", share);
|
||||
|
||||
th2.join();
|
||||
if (exists(bufPath))
|
||||
{
|
||||
remove(bufPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recLog("detect_loop() -- thread finished.", share);
|
||||
waitForDetThreads(share);
|
||||
|
||||
if (!share->skipCmd)
|
||||
{
|
||||
recLog("motion not detected by the detection loop.", share);
|
||||
recLog("no motion detected", share);
|
||||
|
||||
if (share->postCmd.empty())
|
||||
{
|
||||
|
@ -135,7 +112,7 @@ void recLoop(shared_t *share)
|
|||
}
|
||||
else
|
||||
{
|
||||
recLog("motion detected by the detection loop, skipping the post command.", share);
|
||||
recLog("motion detected, skipping the post command.", share);
|
||||
}
|
||||
|
||||
recLog("rec_loop() -- finished", share);
|
||||
|
@ -171,11 +148,9 @@ int main(int argc, char** argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
sharedRes.retCode = 0;
|
||||
sharedRes.recLoopWait = false;
|
||||
sharedRes.skipCmd = false;
|
||||
sharedRes.init = true;
|
||||
sharedRes.logRun = true;
|
||||
sharedRes.retCode = 0;
|
||||
sharedRes.skipCmd = false;
|
||||
sharedRes.init = true;
|
||||
|
||||
recLoop(&sharedRes);
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share)
|
|||
|
||||
if (imgDiff(prev, next, share))
|
||||
{
|
||||
resize(next, vidThumb, Size(1280, 720), INTER_LINEAR);
|
||||
resize(next, vidThumb, Size(720, 480), INTER_LINEAR);
|
||||
|
||||
mod = true; break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user