2022-04-14 09:45:54 -04:00
|
|
|
#include <iostream>
|
2022-07-08 15:24:45 -04:00
|
|
|
#include <fstream>
|
2022-04-14 09:45:54 -04:00
|
|
|
#include <string>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/stat.h>
|
2022-07-08 15:24:45 -04:00
|
|
|
#include <errno.h>
|
2022-08-12 21:46:36 -04:00
|
|
|
#include <vector>
|
|
|
|
#include <thread>
|
|
|
|
#include <mutex>
|
2022-04-14 09:45:54 -04:00
|
|
|
|
|
|
|
#include <opencv4/opencv2/opencv.hpp>
|
|
|
|
#include <opencv4/opencv2/videoio.hpp>
|
|
|
|
|
|
|
|
using namespace cv;
|
|
|
|
using namespace std;
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
#define BUF_SZ 3
|
|
|
|
|
2022-04-14 09:45:54 -04:00
|
|
|
struct shared_t
|
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
string recordUrl;
|
|
|
|
string outDir;
|
|
|
|
string postCmd;
|
|
|
|
string conf;
|
|
|
|
string buffDir;
|
|
|
|
string concatTxtTmp;
|
|
|
|
string concatShTmp;
|
|
|
|
string createShTmp;
|
|
|
|
mutex thrMutex;
|
|
|
|
bool init;
|
|
|
|
int tmpId;
|
|
|
|
int colorThresh;
|
|
|
|
int secs;
|
|
|
|
int blockThresh;
|
|
|
|
int blockX;
|
|
|
|
int blockY;
|
|
|
|
int retCode;
|
2022-04-14 09:45:54 -04:00
|
|
|
|
|
|
|
} sharedRes;
|
|
|
|
|
|
|
|
string cleanDir(const string &path)
|
|
|
|
{
|
|
|
|
if (path[path.size() - 1] == '/')
|
|
|
|
{
|
|
|
|
return path.substr(0, path.size() - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool createDir(const string &dir)
|
|
|
|
{
|
|
|
|
auto ret = mkdir(dir.c_str(), 0777);
|
|
|
|
|
|
|
|
if (ret == -1)
|
|
|
|
{
|
|
|
|
return errno == EEXIST;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool createDirTree(const string &full_path)
|
|
|
|
{
|
|
|
|
size_t pos = 0;
|
|
|
|
auto ret = true;
|
|
|
|
|
|
|
|
while (ret == true && pos != string::npos)
|
|
|
|
{
|
|
|
|
pos = full_path.find('/', pos + 1);
|
|
|
|
ret = createDir(full_path.substr(0, pos));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
bool fileExists(const string& name)
|
|
|
|
{
|
|
|
|
return access(name.c_str(), F_OK) != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void replaceAll(string &str, const string &from, const string &to)
|
|
|
|
{
|
|
|
|
if(from.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
size_t startPos = 0;
|
|
|
|
|
|
|
|
while((startPos = str.find(from, startPos)) != string::npos)
|
|
|
|
{
|
|
|
|
str.replace(startPos, from.length(), to);
|
|
|
|
|
|
|
|
startPos += to.length();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
string genDstFile(const string &dirOut, const string &ext)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-28 10:30:07 -04:00
|
|
|
time_t rawtime;
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
time(&rawtime);
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
auto timeinfo = localtime(&rawtime);
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
char dateC[20];
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
strftime(dateC, 20, "%Y-%m-%d", timeinfo);
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
createDirTree(cleanDir(dirOut));
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
return cleanDir(dirOut) + string("/") + string(dateC) + ext;
|
2022-07-28 10:30:07 -04:00
|
|
|
}
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
string genTmpFile(const string &dirOut, const string &ext, shared_t *share)
|
2022-07-28 10:30:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
createDirTree(cleanDir(dirOut));
|
2022-04-22 09:43:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
share->tmpId += 1;
|
2022-04-22 09:43:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
return cleanDir(dirOut) + string("/") + to_string(share->tmpId) + ext;
|
2022-07-28 10:30:07 -04:00
|
|
|
}
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
Mat toGray(const Mat &src)
|
|
|
|
{
|
|
|
|
Mat ret;
|
|
|
|
|
|
|
|
cvtColor(src, ret, COLOR_BGR2GRAY);
|
|
|
|
|
|
|
|
return ret;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
bool pixDiff(const uchar &pixA, const uchar &pixB, shared_t *share)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
auto diff = 0;
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
if (pixA > pixB) diff = pixA - pixB;
|
|
|
|
if (pixB > pixA) diff = pixB - pixA;
|
|
|
|
|
|
|
|
if (diff < share->colorThresh)
|
|
|
|
{
|
|
|
|
diff = 0;
|
|
|
|
}
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
return diff != 0;
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
void secDiff(Mat imgA, Mat imgB, int rows, int cols, int rowOffs, int colOffs, bool *mod, shared_t *share)
|
2022-07-08 15:24:45 -04:00
|
|
|
{
|
2022-07-28 10:30:07 -04:00
|
|
|
auto pnts = 0;
|
2022-07-08 15:24:45 -04:00
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
for (auto y = rowOffs; y < rows; y++)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-28 10:30:07 -04:00
|
|
|
for (auto x = colOffs; x < cols; x++)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
auto pixA = imgA.at<uchar>(Point(x, y));
|
|
|
|
auto pixB = imgB.at<uchar>(Point(x, y));
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
//cout << "pnts: " << pnts << endl;
|
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
if (pixDiff(pixA, pixB, share))
|
2022-07-08 15:24:45 -04:00
|
|
|
{
|
2022-07-28 10:30:07 -04:00
|
|
|
pnts += 1;
|
2022-08-12 21:46:36 -04:00
|
|
|
|
|
|
|
if (pnts >= share->blockThresh)
|
|
|
|
{
|
|
|
|
lock_guard<mutex> guard(share->thrMutex);
|
|
|
|
|
|
|
|
*mod = true; return;
|
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
2022-06-11 08:43:19 -04:00
|
|
|
}
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
bool imgDiff(Mat prev, Mat next, shared_t *share)
|
2022-04-22 09:43:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
auto numOfXBlocks = prev.cols / share->blockX;
|
|
|
|
auto numOfYBlocks = prev.rows / share->blockY;
|
|
|
|
auto moInBlock = false;
|
2022-04-22 09:43:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
vector<thread> threads;
|
2022-07-08 15:24:45 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
for (auto x = 0; (x < numOfXBlocks) && !moInBlock; x += share->blockX)
|
|
|
|
{
|
|
|
|
for (auto y = 0; (y < numOfYBlocks) && !moInBlock; y += share->blockY)
|
2022-07-28 10:30:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
threads.push_back(thread(secDiff, prev, next, share->blockY, share->blockX, y, x, &moInBlock, share));
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
2022-08-12 21:46:36 -04:00
|
|
|
}
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
for (auto &&thr : threads)
|
|
|
|
{
|
|
|
|
thr.join();
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
2022-08-12 21:46:36 -04:00
|
|
|
|
|
|
|
return moInBlock;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
|
|
|
|
2022-07-08 15:24:45 -04:00
|
|
|
string parseForParam(const string &arg, int argc, char** argv, bool argOnly)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
|
|
|
for (int i = 0; i < argc; ++i)
|
|
|
|
{
|
|
|
|
auto argInParams = string(argv[i]);
|
|
|
|
|
|
|
|
if (arg.compare(argInParams) == 0)
|
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
if (!argOnly)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
// check ahead, make sure i + 1 won't cause out-of-range exception
|
|
|
|
if ((i + 1) <= (argc - 1))
|
|
|
|
{
|
|
|
|
return string(argv[i + 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-07-14 10:19:37 -04:00
|
|
|
return string("true");
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
2022-07-14 10:19:37 -04:00
|
|
|
void rdLine(const string ¶m, const string &line, string *value)
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-14 10:19:37 -04:00
|
|
|
if (line.rfind(param.c_str(), 0) == 0)
|
|
|
|
{
|
|
|
|
*value = line.substr(param.size());
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
//cout << param << *value << endl;
|
2022-07-14 10:19:37 -04:00
|
|
|
}
|
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
|
2022-07-14 10:19:37 -04:00
|
|
|
void rdLine(const string ¶m, const string &line, int *value)
|
|
|
|
{
|
|
|
|
if (line.rfind(param.c_str(), 0) == 0)
|
|
|
|
{
|
|
|
|
*value = strtol(line.substr(param.size()).c_str(), NULL, 10);
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
//cout << param << *value << endl;
|
2022-07-14 10:19:37 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool rdConf(shared_t *share)
|
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
ifstream varFile(share->conf.c_str());
|
|
|
|
|
|
|
|
if (!varFile.is_open())
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
share->retCode = ENOENT;
|
|
|
|
|
|
|
|
cerr << "err: Failed to open the config file: " << share->conf << " for reading. please check file permissions or if it exists." << endl;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
else
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
string line;
|
|
|
|
|
2022-07-28 10:30:07 -04:00
|
|
|
share->recordUrl.clear();
|
|
|
|
share->outDir.clear();
|
|
|
|
share->postCmd.clear();
|
2022-08-12 21:46:36 -04:00
|
|
|
share->buffDir.clear();
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
share->colorThresh = 5;
|
2022-07-28 10:30:07 -04:00
|
|
|
share->secs = 60;
|
2022-08-12 21:46:36 -04:00
|
|
|
share->blockX = 32;
|
|
|
|
share->blockY = 32;
|
|
|
|
share->blockThresh = 900;
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-07-08 15:24:45 -04:00
|
|
|
do
|
|
|
|
{
|
|
|
|
getline(varFile, line);
|
|
|
|
|
|
|
|
if (line.rfind("#", 0) != 0)
|
|
|
|
{
|
2022-07-14 10:19:37 -04:00
|
|
|
rdLine("recording_stream = ", line, &share->recordUrl);
|
|
|
|
rdLine("output_dir = ", line, &share->outDir);
|
|
|
|
rdLine("post_cmd = ", line, &share->postCmd);
|
2022-07-28 10:30:07 -04:00
|
|
|
rdLine("color_threshold = ", line, &share->colorThresh);
|
2022-07-14 10:19:37 -04:00
|
|
|
rdLine("duration = ", line, &share->secs);
|
2022-08-12 21:46:36 -04:00
|
|
|
rdLine("buff_dir = ", line, &share->buffDir);
|
|
|
|
rdLine("block_x = ", line, &share->blockX);
|
|
|
|
rdLine("block_y = ", line, &share->blockY);
|
|
|
|
rdLine("block_threshold = ", line, &share->blockThresh);
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
} while(!line.empty());
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
if (share->init)
|
|
|
|
{
|
|
|
|
system(string("rm -r " + share->buffDir).c_str());
|
|
|
|
|
|
|
|
share->init = false;
|
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
|
|
|
|
share->retCode = 0;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
|
|
|
|
varFile.close();
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
return share->retCode == 0;
|
2022-07-08 15:24:45 -04:00
|
|
|
}
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
bool capPair(Mat &prev, Mat &next, VideoCapture &capture, shared_t *share)
|
2022-07-28 10:30:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
capture >> prev;
|
|
|
|
capture >> next;
|
|
|
|
|
|
|
|
return !prev.empty() && !next.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
void wrOut(const string &buffFile, const string &dstPath, shared_t *share)
|
|
|
|
{
|
|
|
|
ofstream file;
|
|
|
|
|
|
|
|
auto scriptFile = genTmpFile(share->buffDir, ".sh", share);
|
|
|
|
auto scriptData = string();
|
|
|
|
|
|
|
|
if (fileExists(dstPath))
|
2022-07-28 10:30:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
auto concatFile = genTmpFile(share->buffDir, ".txt", share);
|
|
|
|
auto existsFile = genTmpFile(share->outDir, ".ts", share);
|
|
|
|
auto concatData = share->concatTxtTmp;
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
scriptData = share->concatShTmp;
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
replaceAll(concatData, "%existsFile%", existsFile);
|
|
|
|
replaceAll(concatData, "%buffFile%", buffFile);
|
2022-07-28 10:30:07 -04:00
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
replaceAll(scriptData, "%existsFile%", existsFile);
|
|
|
|
replaceAll(scriptData, "%concatFile%", concatFile);
|
|
|
|
|
|
|
|
file.open(concatFile.c_str());
|
|
|
|
file << concatData;
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scriptData = share->createShTmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
replaceAll(scriptData, "%buffFile%", buffFile);
|
|
|
|
replaceAll(scriptData, "%dstPath%", dstPath);
|
|
|
|
replaceAll(scriptData, "%scriptFile%", scriptFile);
|
|
|
|
|
|
|
|
file.open(scriptFile.c_str());
|
|
|
|
file << scriptData;
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
system(string("sh " + scriptFile + " &").c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool moDetect(const string &buffFile, shared_t *share)
|
|
|
|
{
|
|
|
|
auto mod = false;
|
|
|
|
|
|
|
|
VideoCapture capture(buffFile.c_str(), CAP_FFMPEG);
|
|
|
|
|
|
|
|
if (capture.isOpened())
|
|
|
|
{
|
|
|
|
Mat prev;
|
|
|
|
Mat next;
|
|
|
|
|
|
|
|
while (capPair(prev, next, capture, share))
|
|
|
|
{
|
|
|
|
if (imgDiff(toGray(prev), toGray(next), share))
|
2022-07-28 10:30:07 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
mod = true; break;
|
2022-07-28 10:30:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-12 21:46:36 -04:00
|
|
|
if (mod)
|
|
|
|
{
|
|
|
|
auto dstPath = genDstFile(share->outDir, ".ts");
|
|
|
|
|
|
|
|
wrOut(buffFile, dstPath, share);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cerr << "err: Could not open buff file: " << buffFile << " for reading. check formatting/permissions." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mod)
|
|
|
|
{
|
|
|
|
system(string("rm " + buffFile + " &").c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
return mod;
|
|
|
|
}
|
|
|
|
|
|
|
|
void recLoop(shared_t *share)
|
|
|
|
{
|
|
|
|
while (rdConf(share))
|
|
|
|
{
|
|
|
|
auto mod = false;
|
|
|
|
|
|
|
|
for (auto i = 0; i < share->secs; i += BUF_SZ)
|
|
|
|
{
|
|
|
|
auto dstPath = genTmpFile(share->buffDir, ".ts", share);
|
|
|
|
auto cmd = "ffmpeg -hide_banner -loglevel error -i " + share->recordUrl + " -y -vcodec copy -t " + to_string(BUF_SZ) + " " + dstPath;
|
|
|
|
|
|
|
|
system(cmd.c_str());
|
|
|
|
|
|
|
|
mod = moDetect(dstPath, share);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mod)
|
|
|
|
{
|
|
|
|
system(share->postCmd.c_str());
|
|
|
|
}
|
2022-07-28 10:30:07 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-08 15:24:45 -04:00
|
|
|
void showHelp()
|
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
cout << "Motion Watch v1.1" << endl << endl;
|
2022-07-08 15:24:45 -04:00
|
|
|
cout << "Usage: mow <argument>" << endl << endl;
|
|
|
|
cout << "-h : display usage information about this application." << endl;
|
|
|
|
cout << "-c : path to the config file." << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
sharedRes.conf = parseForParam("-c", argc, argv, false);
|
|
|
|
|
|
|
|
if (parseForParam("-h", argc, argv, true) == "true")
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-07-08 15:24:45 -04:00
|
|
|
showHelp();
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
2022-07-08 15:24:45 -04:00
|
|
|
else if (sharedRes.conf.empty())
|
2022-04-14 09:45:54 -04:00
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
cerr << "err: A config file was not given in -c" << endl;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-08-12 21:46:36 -04:00
|
|
|
sharedRes.retCode = 0;
|
|
|
|
sharedRes.tmpId = 0;
|
|
|
|
sharedRes.init = true;
|
|
|
|
|
|
|
|
sharedRes.concatTxtTmp += "file '%existsFile%'\n";
|
|
|
|
sharedRes.concatTxtTmp += "file '%buffFile%'\n";
|
|
|
|
|
|
|
|
sharedRes.concatShTmp += "#!/bin/sh\n";
|
|
|
|
sharedRes.concatShTmp += "cp '%dstPath%' '%existsFile%'\n";
|
|
|
|
sharedRes.concatShTmp += "ffmpeg -hide_banner -loglevel error -y -f concat -safe 0 -i '%concatFile%' -c copy '%dstPath%'\n";
|
|
|
|
sharedRes.concatShTmp += "rm '%concatFile%'\n";
|
|
|
|
sharedRes.concatShTmp += "rm '%existsFile%'\n";
|
|
|
|
sharedRes.concatShTmp += "rm '%buffFile%'\n";
|
|
|
|
sharedRes.concatShTmp += "rm '%scriptFile%'\n";
|
|
|
|
|
|
|
|
sharedRes.createShTmp += "#!/bin/sh\n";
|
|
|
|
sharedRes.createShTmp += "cp '%buffFile%' '%dstPath%'\n";
|
|
|
|
sharedRes.createShTmp += "rm '%buffFile%'\n";
|
|
|
|
sharedRes.createShTmp += "rm '%scriptFile%'\n";
|
|
|
|
|
|
|
|
thread th1(recLoop, &sharedRes);
|
|
|
|
|
|
|
|
th1.join();
|
2022-04-14 09:45:54 -04:00
|
|
|
|
2022-07-08 15:24:45 -04:00
|
|
|
return sharedRes.retCode;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|
|
|
|
|
2022-07-08 15:24:45 -04:00
|
|
|
return EINVAL;
|
2022-04-14 09:45:54 -04:00
|
|
|
}
|