// This file is part of JustMotion. // JustMotion is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // JustMotion is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. #include "event_loop.h" EventLoop::EventLoop(shared_t *sharedRes, QThread *thr, QObject *parent) : QObject(parent) { shared = sharedRes; heartBeat = 1; loopTimer = 0; connect(thr, &QThread::started, this, &EventLoop::init); connect(thr, &QThread::finished, this, &EventLoop::deleteLater); moveToThread(thr); } void EventLoop::init() { loopTimer = new QTimer(this); connect(loopTimer, &QTimer::timeout, this, &EventLoop::exec); loopTimer->setSingleShot(false); loopTimer->start(heartBeat * 1000); } QString EventLoop::statusLine() { if (loopTimer->isActive()) { return "OK "; } else { return "FAIL"; } } void EventLoop::updatePls() { QString text; auto txt = QTextStream(&text); txt << "#EXTM3U" << Qt::endl; txt << "#EXT-X-VERSION:3" << Qt::endl; txt << "#EXT-X-TARGETDURATION:4" << Qt::endl; txt << "#EXT-X-MEDIA-SEQUENCE:0" << Qt::endl; auto vids = lsFilesInDir(shared->recPath + "/vid", shared->recExt); for (auto vid : vids) { txt << "#EXTINF:4.000000," << Qt::endl; txt << "vid/" << vid << Qt::endl; } QFile file(shared->recPath + "/pls.m3u8"); if (file.open(QFile::WriteOnly)) { file.write(text.toUtf8()); } file.close(); } void EventLoop::exec() { bool dirUpdated = false; if (!shared->recList.vidList.isEmpty()) { auto vidPath = shared->recList.vidList.takeFirst(); auto imgPath = shared->recList.imgList.takeFirst(); auto vidDst = shared->recPath + "/vid/" + QFileInfo(vidPath).fileName(); auto imgDst = shared->recPath + "/img/" + QFileInfo(imgPath).baseName() + shared->thumbExt; qInfo() << "---EVENT WRITEOUT START---"; qInfo() << "source files: "; qInfo() << vidPath; qInfo() << imgPath; qInfo() << "destination files: "; qInfo() << vidDst; qInfo() << imgDst; mkPath(shared->recPath + "/vid"); mkPath(shared->recPath + "/img"); if (!QFile::copy(vidPath, vidDst)) { qCritical() << "err: file copy operation failed." << Qt::endl; qInfo() << "exists?: " << vidPath << ": " << QFileInfo::exists(vidPath); } if (imgPath.endsWith(shared->thumbExt)) { QFile::copy(imgPath, imgDst); } else { QStringList args; args << imgPath; args << imgDst; QProcess::execute("convert", args); } dirUpdated = true; qInfo() << "---EVENT WRITEOUT END---"; } else { // maintain max live secs worth of image files in the img buffer folder. auto names = lsFilesInDir(shared->buffPath + "/img", ".bmp"); if (names.size() > (shared->liveSecs / 3)) { QFile::remove(shared->buffPath + "/img/" + names[0]); names.removeFirst(); } // maintain max live secs worth of video files in the vid buffer folder. names = lsFilesInDir(shared->buffPath + "/vid", shared->streamExt); if (names.size() > (shared->liveSecs / 3)) { QFile::remove(shared->buffPath + "/vid/" + names[0]); names.removeFirst(); } } // maintain max byte size of the vid/img folder in the recording path. auto names = lsFilesInDir(shared->recPath + "/vid", shared->recExt); if (byteSize(shared->recPath) > shared->evtMaxBytes) { auto nameOnly = QFileInfo(shared->recPath + "/vid/" + names[0]).baseName(); auto vidFile = shared->recPath + "/vid/" + nameOnly + shared->recExt; auto imgFile = shared->recPath + "/img/" + nameOnly + shared->thumbExt; QFile::remove(vidFile); QFile::remove(imgFile); names.removeFirst(); dirUpdated = true; } if (dirUpdated) { updatePls(); } }