浏览代码

Add RecorderMutex

JDierkse 2 年之前
父节点
当前提交
59f4409ab4

+ 7 - 7
API/WebAPI.cpp

@@ -30,7 +30,7 @@ WebAPI::~WebAPI()
 {
 }
 
-Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool, Http::HttpClient* pHttpClient, const std::string& path, const std::string& ffmpeg, const std::string& uri, const std::vector<Http::HttpPostData>& postData)
+Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool, Http::HttpClient* pHttpClient, Util::RecorderMutexPointer pRecorderMutex, const std::string& path, const std::string& ffmpeg, const std::string& uri, const std::vector<Http::HttpPostData>& postData)
 {
 	if (!StringAlgorithm::iequals(uri, "/api") && !StringAlgorithm::istarts_with(uri, "/api/"))
 	{
@@ -69,7 +69,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		reply.status = Http::HttpServer::HttpReply::Status::Ok;
 		if (StringAlgorithm::iequals("Digoo", brand))
 		{
-			auto recorder = Recorder::DigooRecorder(pHttpClient, settings);
+			auto recorder = Recorder::DigooRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))
@@ -79,7 +79,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		}
 		else if (StringAlgorithm::iequals("Foscam", brand))
 		{
-			auto recorder = Recorder::FoscamRecorder(pHttpClient, settings);
+			auto recorder = Recorder::FoscamRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))
@@ -89,7 +89,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		}
 		else if (StringAlgorithm::iequals("RTSP", brand))
 		{
-			auto recorder = Recorder::RTSPRecorder(pHttpClient, settings);
+			auto recorder = Recorder::RTSPRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))
@@ -99,7 +99,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		}
 		else if (StringAlgorithm::iequals("VStarCam", brand))
 		{
-			auto recorder = Recorder::VStarCamRecorder(pHttpClient, settings);
+			auto recorder = Recorder::VStarCamRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))
@@ -109,7 +109,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		}
 		else if (StringAlgorithm::iequals("WatchBot", brand))
 		{
-			auto recorder = Recorder::WatchBotRecorder(pHttpClient, settings);
+			auto recorder = Recorder::WatchBotRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))
@@ -119,7 +119,7 @@ Http::HttpServer::HttpReply WebAPI::ProcessQuery(ctpl::thread_pool* pThreadPool,
 		}
 		else if (StringAlgorithm::iequals("ZModo", brand))
 		{
-			auto recorder = Recorder::ZModoRecorder(pHttpClient, settings);
+			auto recorder = Recorder::ZModoRecorder(pHttpClient, settings, pRecorderMutex);
 			if (StringAlgorithm::iequals("Snapshot", action))
 				reply.content = recorder.Snapshot(pThreadPool, ffmpeg);
 			else if (StringAlgorithm::iequals("MultiSnapshot", action))

+ 2 - 1
API/WebAPI.h

@@ -1,6 +1,7 @@
 #ifndef API_WEBAPI_H
 #define API_WEBAPI_H
 
+#include "Util/RecorderMutex.h"
 #include <HttpPostData.h>
 #include <HttpServer.h>
 #include <ctpl_stl.h>
@@ -23,7 +24,7 @@ public:
 	WebAPI();
 	~WebAPI();
 
-	static Http::HttpServer::HttpReply ProcessQuery(ctpl::thread_pool* pThreadPool, Http::HttpClient* pHttpClient, const std::string& path, const std::string& ffmpeg, const std::string& uri, const std::vector<Http::HttpPostData>& postData);
+	static Http::HttpServer::HttpReply ProcessQuery(ctpl::thread_pool* pThreadPool, Http::HttpClient* pHttpClient, Util::RecorderMutexPointer pRecorderMutex, const std::string& path, const std::string& ffmpeg, const std::string& uri, const std::vector<Http::HttpPostData>& postData);
 };
 
 } // namespace API

+ 3 - 1
Application/CameraRecorder.cc

@@ -1,4 +1,5 @@
 #include "API/WebAPI.h"
+#include "Util/RecorderMutex.h"
 #include <ctpl_stl.h>
 #include <INIReader.h>
 #include <Logging.h>
@@ -41,7 +42,8 @@ int main(int argc, char** argv)
 
 		ctpl::thread_pool threadPool(6);
 		Http::HttpClient httpClient;
-		Http::HttpServer::CallbackMethod callback = std::bind(&CameraRecorder::API::WebAPI::ProcessQuery, &threadPool, &httpClient, path.str(), ffmpeg, std::placeholders::_1, std::placeholders::_2);
+		CameraRecorder::Util::RecorderMutex recorderMutex;
+		Http::HttpServer::CallbackMethod callback = std::bind(&CameraRecorder::API::WebAPI::ProcessQuery, &threadPool, &httpClient, &recorderMutex, path.str(), ffmpeg, std::placeholders::_1, std::placeholders::_2);
 
 		Http::HttpServer server(port, callback);
 		Logging::Log(Logging::Severity::Info, "Startup Complete");

+ 2 - 1
Recorder/DigooRecorder.cpp

@@ -6,7 +6,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-DigooRecorder::DigooRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+DigooRecorder::DigooRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {

+ 1 - 1
Recorder/DigooRecorder.h

@@ -17,7 +17,7 @@ namespace Recorder {
 class DigooRecorder : public virtual Recorder
 {
 public:
-	DigooRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	DigooRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~DigooRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 34 - 4
Recorder/FoscamRecorder.cpp

@@ -13,7 +13,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-FoscamRecorder::FoscamRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+FoscamRecorder::FoscamRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {
@@ -56,7 +57,12 @@ std::string FoscamRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std::
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	//pThreadPool->push( [pHttpClient, settings, dateTimeString, pRecorderMutex](int) {
+	//	pRecorderMutex->RegisterRecording(settings.IpAddress);
+		FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//	pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	//} );
 
 	return fileName;
 }
@@ -85,12 +91,24 @@ std::string FoscamRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, const
 			return std::string();
 		}
 	}
+
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "FoscamRecorder MultiSnapshot Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages](int) { FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages); } );
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages);
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }
@@ -124,6 +142,12 @@ std::string FoscamRecorder::Video(ctpl::thread_pool* pThreadPool, const std::str
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "FoscamRecorder Video Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "mp4", dateTimeString);
 
@@ -132,7 +156,13 @@ std::string FoscamRecorder::Video(ctpl::thread_pool* pThreadPool, const std::str
 
 	std::string cmd(command.str());
 	Logging::Log(Logging::Severity::Debug, cmd);
-	pThreadPool->push( [cmd](int) { int retval = std::system(cmd.c_str()); } );
+	Settings settings = m_settings;
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		int retval = std::system(cmd.c_str());
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }

+ 1 - 1
Recorder/FoscamRecorder.h

@@ -18,7 +18,7 @@ namespace Recorder {
 class FoscamRecorder : public virtual Recorder
 {
 public:
-	FoscamRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	FoscamRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~FoscamRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 36 - 4
Recorder/RTSPRecorder.cpp

@@ -8,7 +8,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-RTSPRecorder::RTSPRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+RTSPRecorder::RTSPRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {
@@ -43,12 +44,20 @@ std::string RTSPRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std::st
 		}
 	}
 
+	//if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	//	return std::string();
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString, 0);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	RTSPRecorder::Snapshots(ffmpeg, settings, dateTimeString, 1);
+	//Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	//pThreadPool->push( [ffmpeg, settings, dateTimeString, pRecorderMutex](int) {
+	//	pRecorderMutex->RegisterRecording(settings.IpAddress);
+		RTSPRecorder::Snapshots(ffmpeg, settings, dateTimeString, 1);
+	//	pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	//} );
 
 	return fileName;
 }
@@ -78,12 +87,23 @@ std::string RTSPRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, const st
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "RTSPRecorder MultiSnapshot Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString, 0);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	pThreadPool->push( [ffmpeg, settings, dateTimeString, numberOfImages](int) { RTSPRecorder::Snapshots(ffmpeg, settings, dateTimeString, numberOfImages); } );
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [ffmpeg, settings, dateTimeString, numberOfImages, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		RTSPRecorder::Snapshots(ffmpeg, settings, dateTimeString, numberOfImages);
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }
@@ -116,6 +136,12 @@ std::string RTSPRecorder::Video(ctpl::thread_pool* pThreadPool, const std::strin
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "RTSPRecorder Video Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "mp4", dateTimeString, 0);
 
@@ -124,7 +150,13 @@ std::string RTSPRecorder::Video(ctpl::thread_pool* pThreadPool, const std::strin
 
 	std::string cmd(command.str());
 	Logging::Log(Logging::Severity::Debug, cmd);
-	pThreadPool->push( [cmd](int) { int retval = std::system(cmd.c_str()); } );
+	Settings settings = m_settings;
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		int retval = std::system(cmd.c_str());
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }

+ 1 - 1
Recorder/RTSPRecorder.h

@@ -18,7 +18,7 @@ namespace Recorder {
 class RTSPRecorder : public virtual Recorder
 {
 public:
-	RTSPRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	RTSPRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~RTSPRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 2 - 1
Recorder/Recorder.cpp

@@ -4,7 +4,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-Recorder::Recorder()
+Recorder::Recorder(Util::RecorderMutexPointer pRecorderMutex) :
+    m_pRecorderMutex(pRecorderMutex)
 {
 }
 

+ 5 - 1
Recorder/Recorder.h

@@ -1,6 +1,7 @@
 #ifndef RECORDER_RECORDER_H
 #define RECORDER_RECORDER_H
 
+#include "Util/RecorderMutex.h"
 #include <ctpl_stl.h>
 #include <string>
 
@@ -11,12 +12,15 @@ namespace Recorder {
 class Recorder
 {
 public:
-	Recorder();
+	Recorder(Util::RecorderMutexPointer pRecorderMutex);
 	~Recorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) = 0;
 	virtual std::string MultiSnapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg, int numberOfImages) = 0;
 	virtual std::string Video(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) = 0;
+
+protected:
+	Util::RecorderMutexPointer m_pRecorderMutex;
 };
 
 } // namespace Recorder

+ 36 - 4
Recorder/VStarCamRecorder.cpp

@@ -10,7 +10,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-VStarCamRecorder::VStarCamRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+VStarCamRecorder::VStarCamRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {
@@ -45,12 +46,20 @@ std::string VStarCamRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std
 		}
 	}
 
+	//if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	//	return std::string();
+
 	std::string dateTimeString = Util::GetDateTimeString(true);
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString, 0);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	VStarCamRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	//pThreadPool->push( [pHttpClient, settings, dateTimeString, pRecorderMutex](int) {
+	//	pRecorderMutex->RegisterRecording(settings.IpAddress);
+		VStarCamRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//	pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	//} );
 
 	return fileName;
 }
@@ -80,12 +89,23 @@ std::string VStarCamRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, cons
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "VStarCamRecorder MultiSnapshot Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString(true);
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString, 0);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages](int) { VStarCamRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages); } );
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		VStarCamRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages);
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }
@@ -119,6 +139,12 @@ std::string VStarCamRecorder::Video(ctpl::thread_pool* pThreadPool, const std::s
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "VStarCamRecorder Video Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString(true);
 	std::string fileName = GetFileName(m_settings, "mp4", dateTimeString, 0);
 
@@ -127,7 +153,13 @@ std::string VStarCamRecorder::Video(ctpl::thread_pool* pThreadPool, const std::s
 
 	std::string cmd(command.str());
 	Logging::Log(Logging::Severity::Debug, cmd);
-	pThreadPool->push( [cmd](int) { int retval = std::system(cmd.c_str()); } );
+	Settings settings = m_settings;
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		int retval = std::system(cmd.c_str());
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }

+ 1 - 1
Recorder/VStarCamRecorder.h

@@ -18,7 +18,7 @@ namespace Recorder {
 class VStarCamRecorder : public virtual Recorder
 {
 public:
-	VStarCamRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	VStarCamRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~VStarCamRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 36 - 4
Recorder/WatchBotRecorder.cpp

@@ -13,7 +13,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-WatchBotRecorder::WatchBotRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+WatchBotRecorder::WatchBotRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {
@@ -48,12 +49,20 @@ std::string WatchBotRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std
 		}
 	}
 
+	//if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	//	return std::string();
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	//pThreadPool->push( [pHttpClient, settings, dateTimeString, pRecorderMutex](int) {
+	//	pRecorderMutex->RegisterRecording(settings.IpAddress);
+		WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
+	//	pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	//} );
 
 	return fileName;
 }
@@ -83,12 +92,23 @@ std::string WatchBotRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, cons
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "WatchBotRecorder MultiSnapshot Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "jpg", dateTimeString);
 
 	Http::HttpClient* pHttpClient = m_pHttpClient;
 	Settings settings = m_settings;
-	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages](int) { WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages); } );
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages);
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }
@@ -121,6 +141,12 @@ std::string WatchBotRecorder::Video(ctpl::thread_pool* pThreadPool, const std::s
 		}
 	}
 
+	if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
+	{
+		Logging::Log(Logging::Severity::Debug, "WatchBotRecorder MultiSnapshot Cancelled, Recording in progress");
+		return std::string();
+	}
+
 	std::string dateTimeString = Util::GetDateTimeString();
 	std::string fileName = GetFileName(m_settings, "mp4", dateTimeString);
 
@@ -129,7 +155,13 @@ std::string WatchBotRecorder::Video(ctpl::thread_pool* pThreadPool, const std::s
 
 	std::string cmd(command.str());
 	Logging::Log(Logging::Severity::Debug, cmd);
-	pThreadPool->push( [cmd](int) { int retval = std::system(cmd.c_str()); } );
+	Settings settings = m_settings;
+	Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
+	pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
+		pRecorderMutex->RegisterRecording(settings.IpAddress);
+		int retval = std::system(cmd.c_str());
+		pRecorderMutex->UnregisterRecording(settings.IpAddress);
+	} );
 
 	return fileName;
 }

+ 1 - 1
Recorder/WatchBotRecorder.h

@@ -18,7 +18,7 @@ namespace Recorder {
 class WatchBotRecorder : public virtual Recorder
 {
 public:
-	WatchBotRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	WatchBotRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~WatchBotRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 2 - 1
Recorder/ZModoRecorder.cpp

@@ -6,7 +6,8 @@
 namespace CameraRecorder {
 namespace Recorder {
 
-ZModoRecorder::ZModoRecorder(Http::HttpClient* pHttpClient, const Settings& settings) :
+ZModoRecorder::ZModoRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
+	Recorder(pRecorderMutex),
 	m_pHttpClient(pHttpClient),
 	m_settings(settings)
 {

+ 1 - 1
Recorder/ZModoRecorder.h

@@ -17,7 +17,7 @@ namespace Recorder {
 class ZModoRecorder : public virtual Recorder
 {
 public:
-	ZModoRecorder(Http::HttpClient* pHttpClient, const Settings& settings);
+	ZModoRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex);
 	~ZModoRecorder();
 
 	virtual std::string Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg) override;

+ 31 - 0
Util/RecorderMutex.cpp

@@ -0,0 +1,31 @@
+#include "RecorderMutex.h"
+#include <algorithm>
+
+
+namespace CameraRecorder {
+namespace Util {
+
+RecorderMutex::RecorderMutex()
+{
+}
+
+void RecorderMutex::RegisterRecording(const std::string& ipAddress)
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	m_activeRecordings.push_back(ipAddress);
+}
+
+void RecorderMutex::UnregisterRecording(const std::string& ipAddress)
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	m_activeRecordings.erase(std::remove(m_activeRecordings.begin(), m_activeRecordings.end(), ipAddress), m_activeRecordings.end());
+}
+
+bool RecorderMutex::IsRecording(const std::string& ipAddress)
+{
+	std::unique_lock<std::mutex> lock(m_mutex);
+	return std::find(m_activeRecordings.begin(), m_activeRecordings.end(), ipAddress) != m_activeRecordings.end();
+}
+
+} // namespace Util
+} // namespace CameraRecorder

+ 31 - 0
Util/RecorderMutex.h

@@ -0,0 +1,31 @@
+#ifndef UTIL_RECORDERMUTEX_H
+#define UTIL_RECORDERMUTEX_H
+
+#include <mutex>
+#include <string>
+#include <vector>
+
+
+namespace CameraRecorder {
+namespace Util {
+
+class RecorderMutex
+{
+public:
+	RecorderMutex();
+
+	void RegisterRecording(const std::string& ipAddress);
+	void UnregisterRecording(const std::string& ipAddress);
+	bool IsRecording(const std::string& ipAddress);
+
+private:
+	std::mutex m_mutex;
+	std::vector<std::string> m_activeRecordings;
+};
+
+typedef RecorderMutex* const RecorderMutexPointer;
+
+} // namespace Util
+} // namespace CameraRecorder
+
+#endif // UTIL_RECORDERMUTEX_H