From c899c11e98a2d5ffc5fa3535f13666af9012899d Mon Sep 17 00:00:00 2001
From: am0ebe <am0ebe@gmx.de>
Date: Mon, 5 Aug 2024 17:18:52 +0200
Subject: [PATCH] fix errors. create rec dir on startRecord with time for
 multiple recs on same day with same cam. also writeout stats along with rec.

---
 obj/recorder-cmd.pro   |  2 +-
 src/cam.cpp            | 69 +++++++++++++--------------------
 src/cam.h              |  6 +--
 src/camobserver.cpp    |  2 +-
 src/cmd/console.cpp    |  4 +-
 src/core.cpp           | 26 ++++++-------
 src/frameobserver.cpp  | 17 +--------
 src/frameobserver.h    |  7 +---
 src/frameprocessor.cpp | 17 +++++----
 src/frameprocessor.h   |  9 ++---
 src/iprinter.cpp       |  7 ++++
 src/iprinter.h         |  1 +
 src/pingScan.sh        | 22 +----------
 src/record.cpp         | 86 +++++++++++++++++++++++++++++-------------
 src/record.h           |  8 ++--
 15 files changed, 135 insertions(+), 148 deletions(-)

diff --git a/obj/recorder-cmd.pro b/obj/recorder-cmd.pro
index 0373760..6459685 100644
--- a/obj/recorder-cmd.pro
+++ b/obj/recorder-cmd.pro
@@ -12,7 +12,7 @@ HEADERS += 	$$SRC_DIR/cmd/*.h \
 DEFINES *= QT_USE_QSTRINGBUILDER		#converts + to % when building strings 	#append macro
 DEFINES += CONSOLE 	#add macro
 
-DEFINES += DEBUG
+#DEFINES += DEBUG
 
 # opencv
 CONFIG += link_pkgconfig
diff --git a/src/cam.cpp b/src/cam.cpp
index 3b20bce..9bffe45 100644
--- a/src/cam.cpp
+++ b/src/cam.cpp
@@ -28,33 +28,6 @@ _rec()
 	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 }
 
-// Cam::Cam(const Cam& other) : IPrinter(), std::enable_shared_from_this<Cam>(other)
-// _vcam(other._vcam),
-// _name(other._name),
-// _ip(other._ip),
-// _id(other._id),
-// _state(other._state)Cam::Cam(const Cam& other) : IPrinter(), std::enable_shared_from_this<Cam>(other)
-// _vcam(other._vcam),
-// _name(other._name),
-// _ip(other._ip),
-// _id(other._id),
-// _state(other._state)
-// {
-// 	//careful of changing member vars of a copy only!
-// 	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "copy constructor";
-// }
-
-// // Copy assignment operator
-// Cam& operator=(const Cam& other) {
-// 	if (this != &other) {
-// 		// Copy other member variables here if necessary
-
-// 		// Explicitly initialize base class
-// 		std::enable_shared_from_this<Cam>::operator=(other);
-// 	}
-// 	return *this;
-// }
-
 Cam::~Cam()
 {
 	qDebug() << __FUNCTION__ << "():" << __LINE__ << "id:" << _id << ", usecount:" << _vcam.use_count();
@@ -108,7 +81,7 @@ void Cam::open()
 	if(_state != closed)
 		return error("cant open " + stateToString(_state) + " cam");
 
-	f(_vcam->Open( VmbAccessModeFull ),"open cam #"+_id);
+	f(_vcam->Open( VmbAccessModeFull ),"open "+_name);
 	//state change will be handled by CamObserver::CameraStateChanged > Core::onCameraChanged > Cam::onChanged
 }
 
@@ -121,30 +94,38 @@ void Cam::close()
 	//state change will be handled by CamObserver::CameraStateChanged > Core::onCameraChanged > Cam::onChanged
 }
 
-void Cam::printStreamFeatures( QStringList features )
+QStringList Cam::getStreamFeatures( QStringList features )
 {
 	if(_state != opened && _state != recording )
-		return error("cant access features on " + stateToString(_state) + " cam");
+	{
+		error("cant access features on " + stateToString(_state) + " cam");
+		return {""};
+	}
 
 	StreamPtrVector streams;
 	_vcam->GetStreams(streams);
-	printFeatures(streams.at(0), features);
+	return getFeatures(streams.at(0), features);
 }
 
-void Cam::printCamFeatures( QStringList features )
+QStringList Cam::getCamFeatures( QStringList features )
 {
 	if(_state != opened )
-		return error("cant access features on " + stateToString(_state) + " cam");
+	{
+		error("cant access features on " + stateToString(_state) + " cam");
+		return {""};
+	}
 
-	printFeatures(_vcam, features);
+	return getFeatures(_vcam, features);
 }
 
-void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features)
+QStringList Cam::getFeatures( FeatureContainerPtr camOrStream, QStringList features)
 {
+	QStringList allFeaturesWithValue;
 	for( auto feature : features )
 	{
 		try
 		{
+			QString featureWithValue = feature + ": ";
 			FeaturePtr pFeature;
 			g( camOrStream->GetFeatureByName(feature.toStdString().c_str(), pFeature) ); //, QString("GetFeatureByName: %1").arg(feature)
 
@@ -157,41 +138,43 @@ void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features)
 				{
 					VmbInt64_t value;
 					g( pFeature->GetValue(value) );
-					print(feature, value);
+					featureWithValue += QString::number(value);
 					break;
 				}
 				case VmbFeatureDataFloat:
 				{
 					double value;
 					g( pFeature->GetValue(value) );
-					print(feature, value);
+					featureWithValue += QString::number(value);
 					break;
 				}
 				case VmbFeatureDataEnum:
 				{
 					std::string value;
 					g( pFeature->GetValue(value) );
-					print(feature, value);
+					featureWithValue += QString::fromStdString(value);
 					break;
 				}
 				case VmbFeatureDataString:
 				{
 					std::string value;
 					g( pFeature->GetValue(value) );
-					print(feature, value);
+					featureWithValue += QString::fromStdString(value);
 					break;
 				}
 				case VmbFeatureDataBool:
 				{
 					bool value;
 					g( pFeature->GetValue(value) );
-					print(feature, value);
+					featureWithValue += QString::number(value);
 					break;
 				}
 				default:
 					qDebug() << "Unsupported feature type for " << feature;
 					continue;
+
 			}
+			allFeaturesWithValue << featureWithValue;
 		}
 		catch (const std::runtime_error& xx)
 		{
@@ -199,6 +182,8 @@ void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features)
 			// break;
 		}
 	}
+	print(allFeaturesWithValue);
+	return allFeaturesWithValue;
 }
 
 // id,name,model,serial,interfaceID,state
@@ -225,7 +210,7 @@ QString Cam::camInfo()
 
 		camInfo += stateToString(_state) + DELIM;
 		if( _state == recording)
-			camInfo += _rec->getProgressBar() + DELIM;
+			camInfo += _rec->progressBar() + DELIM;
 		else
 			camInfo += "recdur: " + formatTime( _rec->dur().count() * 1000 ) + DELIM;
 
@@ -271,7 +256,7 @@ void Cam::onChanged(UpdateTriggerType type)
 			break;
 		case UpdateTriggerType::UpdateTriggerOpenStateChanged:
 
-			qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "state changed" << stateToString(_state);
+			// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "state changed" << stateToString(_state);
 			if( _state == opened )
 				_state = closed;
 			else if ( _state == closed )
diff --git a/src/cam.h b/src/cam.h
index 837bd55..d305b81 100644
--- a/src/cam.h
+++ b/src/cam.h
@@ -38,8 +38,8 @@ public:
 	void close();
 
 	QString camInfo();
-	void printCamFeatures( QStringList );
-	void printStreamFeatures( QStringList );
+	QStringList getCamFeatures( QStringList );
+	QStringList getStreamFeatures( QStringList );
 
 
 	void saveSettings();
@@ -52,7 +52,7 @@ public:
 	friend class Core;
 
 private:
-	void printFeatures(VmbCPP::FeatureContainerPtr, QStringList);
+	QStringList getFeatures(VmbCPP::FeatureContainerPtr, QStringList);
 
 	CameraPtr _vcam;
 	QString _name;
diff --git a/src/camobserver.cpp b/src/camobserver.cpp
index 8ac9056..7d461e1 100644
--- a/src/camobserver.cpp
+++ b/src/camobserver.cpp
@@ -9,6 +9,6 @@ using namespace VmbCPP;
 
 void CamObserver::CameraListChanged(CameraPtr pCam, UpdateTriggerType type)
 {
-	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__;
+	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__;
 	emit cameraChanged(pCam,type);
 }
diff --git a/src/cmd/console.cpp b/src/cmd/console.cpp
index 5fdfb4c..121f6e4 100644
--- a/src/cmd/console.cpp
+++ b/src/cmd/console.cpp
@@ -62,9 +62,9 @@ void Console::error(const int& errCode )
 void Console::error(const QString& str, const int& errCode=0 )
 {
 	if( str != "" )
-		qDebug().noquote() << "💩 " << str;
+		// qDebug().noquote() << "💩 " << str;
 		// qDebug().noquote() << "💣 " << str;
-		// qDebug().noquote() << "💥 " << str;
+		qDebug().noquote() << "💥 " << str;
 		// qDebug().noquote() << "🔥 " << str;
 	error(errCode);
 }
diff --git a/src/core.cpp b/src/core.cpp
index 12fe47b..3c23c36 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -71,7 +71,7 @@ Core::~Core()
 // update & sync camera vectors
 void Core::detectCams()
 {
-	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
+	info("Looking for cams...");
 	for ( auto cam : _cameras )
 	{
 		if( cam->state() == Cam::disconnected )
@@ -183,7 +183,7 @@ void Core::showRecordingStats()
 	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 	if( cam() && cam()->rec() && cam()->getCameraPtr() )
 	{
-		cam()->rec()->showStats();
+		info(cam()->rec()->stats());
 	}
 }
 
@@ -191,22 +191,20 @@ void Core::showInfo()
 {
 	print("---------(( INFO ))------------");
 	print("configFile",utils::configFile());
+	print("	outDir",utils::outDir());
+	print("	frameSize",utils::frameSize());
+	print("	fps",utils::fps());
+	print("	recDuration",utils::recDuration());
 	print("settingsFile",utils::settingsFile());
-	print("outDir",utils::outDir());
-	print("frameSize",utils::frameSize());
-	print("fps",utils::fps());
-	print("threadsPerCam",utils::threadsPerCam());
 	print("ncam",utils::ncam());
-	print("recDuration",utils::recDuration());
+	print("threadsPerCam",utils::threadsPerCam());
 	print("-------------------------------");
 
-	if( cam() && cam()->rec() )
-	{
-		print(QString("checkDirExists: %1").arg(cam()->rec()->checkDirExists()));
-		showRecordingStats();
-	}
-	//checkDiskSpace (show progressbar)
-	//calcDirSize
+ 	// if( cam() && cam()->rec() )
+	// {
+		// print(QString("check outdir: %1").arg(cam()->rec()->checkDir())); //dir exists, space available
+	// 	// info(cam()->rec()->stats()); //only after cam discovered
+	// }
 
 }
 
diff --git a/src/frameobserver.cpp b/src/frameobserver.cpp
index c74b346..23a3427 100644
--- a/src/frameobserver.cpp
+++ b/src/frameobserver.cpp
@@ -4,19 +4,15 @@
 #include "record.h"
 
 #include <VmbCPP/SharedPointerDefines.h>
-#include <VmbCPP/Camera.h>
 
-// #include "qnamespace.h"
 #include <QThreadPool>
-#include <QDebug>
 #include <QThread>
-#include <QObject>
 
 using namespace VmbCPP;
 
 FrameObserver::FrameObserver( CamPtr cam ) : IFrameObserver( cam->getCameraPtr() ),
 	_cam(cam),
-	_processor(new FrameProcessor(cam->rec()->dir())),
+	_processor(new FrameProcessor(_cam)),
 	_pool(QThreadPool::globalInstance())
 {
 	// _pool->setMaxThreadCount(QThread::idealThreadCount()); //dflt
@@ -26,7 +22,7 @@ FrameObserver::FrameObserver( CamPtr cam ) : IFrameObserver( cam->getCameraPtr()
 
 FrameObserver::~FrameObserver()
 {
-	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
+	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 	delete _processor;
 }
 
@@ -59,12 +55,3 @@ void FrameObserver::queueFrame(FramePtr pframe)
 	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 	_cam->getCameraPtr()->QueueFrame(pframe); // Queue the frame back to the camera
 }
-
-
-	// Optional: Connect to custom debug slots to monitor creation/deletion
-	// static int count=0;
-	// count++;
-	// connect(processor, &QObject::destroyed, this, []() { qDebug() << "Processor destroyed: #" << count; });
-	// connect(thread, &QObject::destroyed, this, []() { qDebug() << "Thread destroyed: #" << count; });
-	// connect(thread, &QThread::started, this, []() { qDebug() << "Thread started: #" << count; });
-	// connect(thread, &QThread::finished, this, []() { qDebug() << "Thread finished: #" << count; });
diff --git a/src/frameobserver.h b/src/frameobserver.h
index 1a5a484..bac9447 100644
--- a/src/frameobserver.h
+++ b/src/frameobserver.h
@@ -1,15 +1,12 @@
 #pragma once
 
-#include "cam.h"
-#include <QObject>
+#include "typeDefinitions.h"
 #include <VmbCPP/IFrameObserver.h>
 
+using VmbCPP::IFrameObserver;
 class FrameProcessor;
 class QThreadPool;
 
-using VmbCPP::FramePtr;
-using VmbCPP::IFrameObserver;
-
 class FrameObserver : public QObject, public IFrameObserver
 {
 	Q_OBJECT
diff --git a/src/frameprocessor.cpp b/src/frameprocessor.cpp
index db7d39c..9c72b3c 100644
--- a/src/frameprocessor.cpp
+++ b/src/frameprocessor.cpp
@@ -1,6 +1,8 @@
 #include "frameprocessor.h"
 #include "frameobserver.h"
 #include "utils.h"
+#include "cam.h"
+#include "record.h"
 
 #include <opencv2/imgcodecs.hpp>
 #include <opencv2/opencv.hpp>
@@ -13,9 +15,8 @@
 #include <QImage>
 #include <QDir>
 
-FrameProcessor::FrameProcessor(const QString& outDir) : QRunnable(),
-// _pframe(pframe),
-_outDir( outDir ), //xx make class static
+FrameProcessor::FrameProcessor( CamPtr cam ) : QRunnable(),
+_cam( cam ),
 _pixelFormatStr("RGB8"),
 _params({cv::IMWRITE_JPEG_QUALITY, 99, cv::IMWRITE_JPEG_OPTIMIZE, 1, cv::IMWRITE_JPEG_RST_INTERVAL,4}),
 _width(0),
@@ -23,6 +24,7 @@ _height(0),
 _timestamp(0)
 {
 	setAutoDelete(false);
+	// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 }
 
 FrameProcessor::~FrameProcessor()
@@ -41,8 +43,8 @@ void FrameProcessor::setFrame(const FramePtr pframe)
 // post: frame needs to be requeued
 void FrameProcessor::run()
 {
-	static VmbUint64_t _count = 0; //all cams, all processors, totalframes
-	++_count;
+	// static VmbUint64_t _count = 0; //all cams, all processors, totalframes
+	// ++_count;
 
 	unsigned char* pdata = nullptr;
 	_pframe->GetBuffer(pdata);
@@ -58,7 +60,8 @@ void FrameProcessor::run()
 
 	cv::Mat frameMat(_height, _width, CV_8UC3, pdata);
 
-	QString filename = _outDir + QString::number(_timestamp) + ".jpg";
+	QString filename = _cam->rec()->dir() + QDir::separator() + QString::number(_timestamp) + ".jpg";
+	// qDebug() << "📸  Writing frame to file: " << filename;
 	bool ret = cv::imwrite(filename.toStdString(), frameMat, _params);
 	if (!ret)
 		qWarning() << "⚠️  Could not write frame to file: " << filename;
@@ -71,5 +74,3 @@ void FrameProcessor::run()
 	emit frameProcessed(_pframe);
 	// _pframe = FramePtr(nullptr); //need to reset pframe?
 }
-
-
diff --git a/src/frameprocessor.h b/src/frameprocessor.h
index 0278aa0..a95a9dd 100644
--- a/src/frameprocessor.h
+++ b/src/frameprocessor.h
@@ -1,19 +1,16 @@
 #pragma once
 
-#include "iprinter.h"
+#include "typeDefinitions.h"
 
-#include <QObject>
 #include <QRunnable>
 #include <VmbCPP/SharedPointerDefines.h>
 
-using VmbCPP::FramePtr;
-
 class FrameProcessor : public QObject, public QRunnable
 {
 	Q_OBJECT
 
 public:
-	explicit FrameProcessor(const QString&);
+	explicit FrameProcessor( CamPtr cam );
 	~FrameProcessor();
 
 	void run() override;
@@ -24,8 +21,8 @@ signals:
 
 
 private:
+	CamPtr _cam;
 	FramePtr _pframe;
-	const QString _outDir;
 	const QString _pixelFormatStr;
 	const std::vector<int> _params;
 
diff --git a/src/iprinter.cpp b/src/iprinter.cpp
index ecdac25..f332a3d 100644
--- a/src/iprinter.cpp
+++ b/src/iprinter.cpp
@@ -2,6 +2,7 @@
 
 #include <QDebug>
 #include <QTimer>
+#include <QDateTime>
 
 #ifdef CONSOLE
 #include "cmd/console.h"
@@ -165,3 +166,9 @@ QString IPrinter::formatTime(const int& milliseconds)
 	else
 		return QString::asprintf("%02dh:%02dm:%02ds", hours, minutes, seconds);
 }
+
+QString IPrinter::curDateTime()
+{
+	QDateTime currentDateTime = QDateTime::currentDateTime();
+	return currentDateTime.toString("yyMMdd-HHmmss");
+}
diff --git a/src/iprinter.h b/src/iprinter.h
index a2732d7..bb7e6e0 100644
--- a/src/iprinter.h
+++ b/src/iprinter.h
@@ -45,6 +45,7 @@ public:
 
 protected:
 	QString formatTime(const int&);
+	QString curDateTime();
 
 private:
 	int getTerminalWidth();
diff --git a/src/pingScan.sh b/src/pingScan.sh
index fe34115..9bc26d4 100755
--- a/src/pingScan.sh
+++ b/src/pingScan.sh
@@ -1,28 +1,10 @@
- #!/bin/bash
+#!/bin/bash
 
 #scans class-B subnet 169.254.i.j
 #watch CPU usage and adapt max_jobs / timeout / step_size vars to ur system
 ############################### Alternatives ###############################
 ## faster alternative:
-#	search MAC address (4m) !!
-# 	sudo arp-scan --interface=enp0s31f6 --localnet | grep 00:0a:47:1d:2a:66
-###############################
-## other alternatives
-## can also use nmap but takes long ~45m:
-# sudo nmap -sP --script=broadcast-dhcp-discover 169.254.0.0/16
-## smaller test:
-# sudo nmap -sP 169.254.220.0-225.255
-## or:
-# sudo nmap -sP 169.254.0.0/16
-# sudo arp-scan --localnet
-## check server logs
-# # http://192.168.0.1/common_page/login.html -> login?
-## Wireshark
-#	 and begin capturing packets on the network interface connected to your local network.
-# 	Filter for Broadcast and Multicast Traffic: Look for packets that are broadcast or multicast, as these can reveal the presence of your device.
-#     Use filters like eth.dst == ff:ff:ff:ff:ff:ff for broadcast or ip.dst == 224.0.0.0/4 for multicast.
-#	Inspect the Traffic: Look for traffic that might come from the camera. If you know the MAC address of the camera,
-#  	you can filter for it using eth.addr == xx:xx:xx:xx:xx:xx.
+# 	sudo arp-scan --interface=enp0s31f6 --localnet
 ###############################
 
 step_size=12
diff --git a/src/record.cpp b/src/record.cpp
index 0263d46..aa219da 100644
--- a/src/record.cpp
+++ b/src/record.cpp
@@ -34,8 +34,6 @@ _frames(FramePtrVector(utils::threadsPerCam()))
 void Record::init(CamPtr cam)
 {
 	_cam = cam;
-	_dir = utils::outDir() + QDir::separator() + cam->name() + QDir::separator();
-
 }
 
 void Record::setDur(seconds dur)
@@ -66,7 +64,8 @@ seconds Record::dur()
 */
 void Record::start()
 {
-	if(!checkDirExists())
+	//create dir for recording
+	if(!checkDir(utils::outDir() + QDir::separator() + _cam->name() + QDir::separator() + curDateTime()))
 		return;
 
 	try
@@ -117,8 +116,9 @@ void Record::start()
 */
 void Record::stop()
 {
+	showProgressBar();
+
 	_updateTimer->stop();
-		showProgressBar();
 	if(_timer->isActive())
 		_timer->stop(); //user stop or error
 
@@ -143,14 +143,34 @@ void Record::stop()
 		return;
 	}
 
-	showStats();
+	auto STATS = stats();
+	info(STATS);
+	write(STATS,"stats");
 }
 
-void Record::showStats()
+bool Record::write(QStringList sl, QString fileName)
 {
-	info("-------------------------------");
-	info("get cam features:");
-	_cam->printCamFeatures({
+
+	QDir dir(_dir);
+	QString filePath = dir.filePath(fileName); // Construct the file path
+	QFile file(filePath);
+	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+		error("Failed to open file:"+filePath);
+		return false;
+	}
+
+	QTextStream out(&file);
+	out << sl.join("\n");
+	return true;
+} // calls file.close();
+
+
+QStringList Record::stats()
+{
+	QStringList _stats;
+	_stats << "-------------------------------";
+	_stats << "cam features:";
+	_stats << _cam->getCamFeatures({
 		"AcquisitionFrameRate",
 		"ExposureTime",
 		"Gain",
@@ -162,9 +182,9 @@ void Record::showStats()
 		"PixelSize",
 	});
 
-	info("-------------------------------");
-	info("get stream stats:");
-	_cam->printStreamFeatures({
+	_stats << "-------------------------------";
+	_stats << "stream stats:";
+	_stats << _cam->getStreamFeatures({
 		"StatFrameRate",
 		"StatFrameDropped",
 		"StatFrameRescued",
@@ -178,16 +198,21 @@ void Record::showStats()
 		"StatTimeElapsed",
 		"StatFrameDelivered",
 	});
+
+	return _stats;
 }
 
 void Record::showProgressBar()
 {
-	info( progressBar(_timer) ); //
+	info( progressBar() );
 }
 
-QString Record::getProgressBar()
+QString Record::progressBar(int percentage)
 {
-	return progressBar(_timer);
+	if(percentage == -1)
+		return IPrinter::progressBar(_timer);
+	else
+		return IPrinter::progressBar(percentage);
 }
 
 void Record::checkDiskSpace(const QString &dir, seconds dur)
@@ -200,7 +225,7 @@ void Record::checkDiskSpace(const QString &dir, seconds dur)
 	qint64 used = calcDirSize(dir);
 
 	int usedPercentage = (double(used) / total) * 100;
-	info(progressBar(usedPercentage)); // << cuz of this line, the function is here not in utils...
+	progressBar(usedPercentage); // << cuz of this line, the function is here not in utils...
 
 	qint64 estimated = dur.count() * utils::fps() * utils::frameSize();
 
@@ -225,11 +250,11 @@ void Record::checkDiskSpace(const QString &dir, seconds dur)
 		return QString::number(displaySize, 'f', 2) + " " + unit;
 	};
 
-	qDebug() << "Used Space:" << formatSize(used);
-	qDebug() << "Available Space:" << formatSize(available);
-	qDebug() << "Total Space:" << formatSize(total);
-	qDebug() << "Used Percentage:" << usedPercentage << "%";
-	qDebug() << "Estimated Recording Space:" << formatSize(estimated);
+	print("Used Space",formatSize(used));
+	print("Available Space",formatSize(available));
+	print("Total Space",formatSize(total));
+	print(QString("Used Percentage: %1%").arg(usedPercentage));
+	print("Estimated Recording Space",formatSize(estimated));
 
 	// Check if estimated recording space exceeds available space
 	if (estimated > available) {
@@ -255,17 +280,24 @@ qint64 Record::calcDirSize(const QDir &dirrr) {
 	return size;
 }
 
-bool Record::checkDirExists()
+// check if dir exists and if it doesnt, create it
+// set _dir
+// checkdiskspace()
+bool Record::checkDir(QString dirPath)
 {
-	//check if dir exists and if it doesnt, create it
-	QDir dir(_dir);
+	if( dirPath.isEmpty() )
+		dirPath = utils::outDir();
+
+	QDir dir(dirPath);
 	if (!dir.exists() && !dir.mkpath(".") )
 	{
-		error("could not create directory: " + _dir);
+		error("could not create directory: " + dirPath);
 		return false;
 	}
 
-	checkDiskSpace(utils::outDir(), dur());
-	info("writing frames to: " + _dir);
+	_dir = dirPath;
+
+	checkDiskSpace(dirPath, dur());
+	info("writing frames to" + dirPath);
 	return true;
 }
diff --git a/src/record.h b/src/record.h
index dae9848..73ff9f5 100644
--- a/src/record.h
+++ b/src/record.h
@@ -6,7 +6,6 @@
 #include <QDir>
 #include <chrono>
 
-
 class QTimer;
 
 class Record : public IPrinter
@@ -24,8 +23,8 @@ public:
 	seconds dur();
 
 
+	bool checkDir(QString dirPath="");
 	void checkDiskSpace(const QString &, seconds);
-	bool checkDirExists();
 	qint64 calcDirSize(const QDir &);
 
 	operator bool() const {	return _cam != nullptr;	}
@@ -34,11 +33,12 @@ public:
 
 public slots:
 	void stop();
-	void showStats();
+	QStringList stats();
 	void showProgressBar();
-	QString getProgressBar();
+	QString progressBar(int percentage=-1);
 
 private:
+	bool write(QStringList, QString);
 
 	CamPtr _cam;
 	QTimer* _timer;
-- 
GitLab