diff --git a/src/common.cpp b/src/common.cpp index 71d5f70..c93259f 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -111,20 +111,20 @@ void enforceMaxDays(const string &dirPath, shared_t *share) void enforceMaxClips(const string &dirPath, shared_t *share) { - auto names = lsDirsInDir(dirPath); + auto names = lsDirsInDir(dirPath, "." + share->vidExt); - // note: this function assumes all video clips are accompanied by - // .html and .jpg files of the same name, hence why it *3 - // the max names in the directory and *3 the file deletion. - - while (names.size() > ((share->maxClips - 1) * 3)) + while (names.size() > share->maxClips) { - remove(string(cleanDir(dirPath) + "/" + names[0]).c_str()); - remove(string(cleanDir(dirPath) + "/" + names[1]).c_str()); - remove(string(cleanDir(dirPath) + "/" + names[2]).c_str()); + // removes the video file extension. + auto nameOnly = names[0].substr(0, names[0].size() - (share->vidExt.size() + 1)); + auto imgFile = cleanDir(dirPath) + "/" + nameOnly + ".jpg"; + auto webFile = cleanDir(dirPath) + "/" + nameOnly + ".html" + + remove(cleanDir(dirPath) + "/" + names[0]); + + if (exists(imgFile)) remove(imgFile); + if (exists(webFile)) remove(webFile); - names.erase(names.begin()); - names.erase(names.begin()); names.erase(names.begin()); } } @@ -191,12 +191,12 @@ bool rdConf(shared_t *share) share->retCode = 0; share->frameGap = 10; - share->pixThresh = 30; - share->imgThresh = 512; + share->pixThresh = 150; + share->imgThresh = 1024; share->secs = 60; share->maxDays = 15; share->maxClips = 30; - share->maxLogSize = 10000; + share->maxLogSize = 50000; share->camName = path(share->conf.c_str()).filename(); share->webRoot = "/var/www/html"; share->vidExt = "mp4"; @@ -242,7 +242,7 @@ bool rdConf(shared_t *share) { remove_all(share->buffDir); } - + share->init = false; } diff --git a/src/common.h b/src/common.h index d673bfc..dec0cb8 100644 --- a/src/common.h +++ b/src/common.h @@ -35,7 +35,7 @@ using namespace cv; using namespace std; using namespace std::filesystem; -#define APP_VER "1.5.t9" +#define APP_VER "1.5.t10" #define APP_NAME "Motion Watch" struct shared_t diff --git a/src/main.cpp b/src/main.cpp index 4113479..abb1a3e 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ void detectLoop(shared_t *share) { - detLog("detectLoop() -- start", share); + detLog("detect_loop() -- start", share); vector bufFiles; auto waitingForFiles = 0; @@ -32,24 +32,17 @@ void detectLoop(shared_t *share) if ((bufFiles.size() >= 2) || (share->recLoopWait && !bufFiles.empty())) { auto fullPath = cleanDir(share->buffDir) + "/" + bufFiles[0]; - - Mat thumbNail; + Mat thumbNail; if (moDetect(fullPath, thumbNail, share)) { share->skipCmd = true; - detLog("motion detected in file: " + fullPath, share); wrOut(fullPath, thumbNail, share); } - else + else if (exists(fullPath)) { - detLog("no motion detected in file: " + fullPath + " removing it.", share); - - if (exists(fullPath)) - { - remove(fullPath); - } + remove(fullPath); } } else @@ -60,19 +53,25 @@ void detectLoop(shared_t *share) break; } + else + { + detLog(to_string(bufFiles.size()) + " buff file(s) found, waiting for more.", share); + } - sleep(1); waitingForFiles++; + sleep(5); waitingForFiles += 5; } } - while (!bufFiles.empty() && !share->recLoopWait); + while (!share->recLoopWait || !bufFiles.empty()); - detLog("detectLoop() -- finished", share); + detLog("detect_loop() -- finished", share); } void recLoop(shared_t *share) { while (rdConf(share)) { + recLog("rec_loop() -- start", share); + enforceMaxLogSize(share->recLogPath, share); enforceMaxLogSize(share->detLogPath, share); @@ -81,28 +80,24 @@ void recLoop(shared_t *share) initLogFrontPages(share); - recLog("recLoop() -- start", share); - if (!exists("/tmp/mow-lock")) { - recLog("/tmp/mow-lock not found, assuming it is safe to update the webroot page.", share); - recLog("webroot page = " + cleanDir(share->webRoot) + "/index.html", share); - system("touch /tmp/mow-lock"); genCSS(share); genHTMLul(share->webRoot, string(APP_NAME) + " " + string(APP_VER), share); remove("/tmp/mow-lock"); + recLog("webroot page updated: " + cleanDir(share->webRoot) + "/index.html", share); } else { - recLog("/tmp/mow-lock pesent, skipping update of the webroot page.", share); + recLog("skipping update of the webroot page, it is busy.", share); } genHTMLul(share->outDir, share->camName, share); - recLog("camera specific webroot page updated. page = " + share->outDir + "/index.html", 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); @@ -111,7 +106,7 @@ void recLoop(shared_t *share) thread th2(detectLoop, share); - recLog("detectLoop() -- started in a seperate thread.", share); + recLog("detect_loop() -- started in a seperate thread.", share); recLog("ffmpeg_run: " + cmd, share); auto retCode = system(cmd.c_str()); @@ -122,6 +117,8 @@ void recLoop(shared_t *share) th2.join(); + recLog("detect_loop() -- thread finished.", share); + if (!share->skipCmd) { recLog("motion not detected by the detection loop.", share); @@ -132,7 +129,7 @@ void recLoop(shared_t *share) } else { - recLog("running post command = " + share->postCmd, share); + recLog("running post command: " + share->postCmd, share); system(share->postCmd.c_str()); } } @@ -141,7 +138,7 @@ void recLoop(shared_t *share) recLog("motion detected by the detection loop, skipping the post command.", share); } - recLog("recLoop() -- finished", share); + recLog("rec_loop() -- finished", share); if (share->retCode != 0) { diff --git a/src/mo_detect.cpp b/src/mo_detect.cpp index 37df853..9b70338 100644 --- a/src/mo_detect.cpp +++ b/src/mo_detect.cpp @@ -14,14 +14,30 @@ bool imgDiff(const Mat &prev, const Mat &next, int &diffScore, shared_t *share) { - Mat diff; + auto ret = false; - absdiff(prev, next, diff); - threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); + detLog("img_diff() -- start()", share); - diffScore = countNonZero(diff); + if (prev.empty()) detLog("prev_frame is empty -- this should never happen (opencv to blame).", share); + if (next.empty()) detLog("next_frame is empty -- EOF assumed.", share); - return diffScore >= share->imgThresh; + if (!prev.empty() && !next.empty()) + { + Mat diff; + + absdiff(prev, next, diff); + threshold(diff, diff, share->pixThresh, 255, THRESH_BINARY); + + diffScore = countNonZero(diff); + + detLog("diff_score: " + to_string(diffScore), share); + + ret = diffScore >= share->imgThresh; + } + + detLog("img_diff() -- finished()", share); + + return ret; } Mat frameFF(VideoCapture *cap, int gap) @@ -47,6 +63,9 @@ Mat frameFF(VideoCapture *cap, int gap) void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share) { + detLog("wr_out() -- start()", share); + detLog("buff_file: " + buffFile, share); + auto dayStr = genTimeStr("%Y-%m-%d"); auto timStr = genTimeStr("%H%M%S"); auto outDir = cleanDir(share->outDir) + "/" + dayStr; @@ -61,7 +80,6 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share) detLog("write_out_vid: " + vidOut, share); detLog("write_out_img: " + imgOut, share); - detLog("remove_file: " + buffFile, share); enforceMaxClips(outDir, share); @@ -73,10 +91,15 @@ void wrOut(const string &buffFile, const Mat &vidThumb, shared_t *share) genHTMLvid(vidOut, share); genHTMLul(outDir, share->camName + ": " + dayStr, share); genHTMLul(share->outDir, share->camName, share); + + detLog("wr_out() -- finished()", share); } bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share) { + detLog("mo_detect() -- start()", share); + detLog("buff_file: " + buffFile, share); + auto mod = false; VideoCapture capture(buffFile.c_str()); @@ -100,24 +123,21 @@ bool moDetect(const string &buffFile, Mat &vidThumb, shared_t *share) { resize(next, vidThumb, Size(1280, 720), INTER_LINEAR); - if (diff > maxDiff) - { - maxDiff = diff; - } - - mod = true; break; + mod = true; } - frameGaps++; - } - while (!prev.empty() && !next.empty()); + frameGaps += share->frameGap; - detLog("scanned_buff_file = " + buffFile + " max_score = " + to_string(maxDiff) + " frame_gaps = " + to_string(frameGaps), share); + detLog("frame_gap: " + to_string(frameGaps), share); + } + while (!prev.empty() && !next.empty() && !mod); } else { - detLog("failed to open buff file: " + buffFile + " for reading. check permissions and/or opencv's video-io support (gstreamer/ffmpeg).", share); + detLog("failed to open the buff file for reading. check permissions and/or opencv's video-io support (gstreamer/ffmpeg).", share); } + detLog("mo_detect() -- finished()", share); + return mod; }