FoscamRecorder.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "FoscamRecorder.h"
  2. #include "Util/Util.h"
  3. #include <HttpClient.h>
  4. #include <JpegImageCollection.h>
  5. #include <Logging.h>
  6. #include <filesystem/path.h>
  7. #include <fstream>
  8. #include <iostream>
  9. #include <sstream>
  10. #include <thread>
  11. namespace CameraRecorder {
  12. namespace Recorder {
  13. FoscamRecorder::FoscamRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
  14. Recorder(pRecorderMutex),
  15. m_pHttpClient(pHttpClient),
  16. m_settings(settings)
  17. {
  18. }
  19. FoscamRecorder::~FoscamRecorder()
  20. {
  21. }
  22. std::string FoscamRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg)
  23. {
  24. Logging::Log(Logging::Severity::Debug, "FoscamRecorder Snapshot");
  25. std::string folderName = GetFolderName(m_settings);
  26. if (!Util::FolderExists(folderName))
  27. {
  28. try
  29. {
  30. Util::CreateFolder(folderName);
  31. }
  32. catch (const std::exception& e)
  33. {
  34. std::cerr << "Exception caught" << std::endl;
  35. std::stringstream ss;
  36. ss << "Type : " << typeid(e).name() << std::endl;
  37. ss << "ERROR: " << e.what() << std::endl;
  38. Logging::Log(Logging::Severity::Error, ss.str());
  39. return std::string();
  40. }
  41. }
  42. //if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
  43. // return std::string();
  44. std::string dateTimeString = Util::GetDateTimeString();
  45. std::string fileName = GetFileName(m_settings, "jpg", dateTimeString);
  46. Http::HttpClient* pHttpClient = m_pHttpClient;
  47. Settings settings = m_settings;
  48. //Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
  49. //pThreadPool->push( [pHttpClient, settings, dateTimeString, pRecorderMutex](int) {
  50. // pRecorderMutex->RegisterRecording(settings.IpAddress);
  51. FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
  52. // pRecorderMutex->UnregisterRecording(settings.IpAddress);
  53. //} );
  54. return fileName;
  55. }
  56. std::string FoscamRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg, int numberOfImages)
  57. {
  58. Logging::Log(Logging::Severity::Debug, "FoscamRecorder MultiSnapshot");
  59. std::string folderName = GetFolderName(m_settings);
  60. if (!Util::FolderExists(folderName))
  61. {
  62. try
  63. {
  64. Util::CreateFolder(folderName);
  65. }
  66. catch (const std::exception& e)
  67. {
  68. std::cerr << "Exception caught" << std::endl;
  69. std::stringstream ss;
  70. ss << "Type : " << typeid(e).name() << std::endl;
  71. ss << "ERROR: " << e.what() << std::endl;
  72. Logging::Log(Logging::Severity::Error, ss.str());
  73. return std::string();
  74. }
  75. }
  76. if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
  77. {
  78. Logging::Log(Logging::Severity::Debug, "FoscamRecorder MultiSnapshot Cancelled, Recording in progress");
  79. return std::string();
  80. }
  81. std::string dateTimeString = Util::GetDateTimeString();
  82. std::string fileName = GetFileName(m_settings, "jpg", dateTimeString);
  83. Http::HttpClient* pHttpClient = m_pHttpClient;
  84. Settings settings = m_settings;
  85. Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
  86. pThreadPool->push( [pHttpClient, settings, dateTimeString, numberOfImages, pRecorderMutex](int) {
  87. pRecorderMutex->RegisterRecording(settings.IpAddress);
  88. FoscamRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages);
  89. pRecorderMutex->UnregisterRecording(settings.IpAddress);
  90. } );
  91. return fileName;
  92. }
  93. std::string FoscamRecorder::Video(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg)
  94. {
  95. Logging::Log(Logging::Severity::Debug, "FoscamRecorder Video");
  96. int port = 65534;
  97. std::stringstream url;
  98. url << "rtsp://" << m_settings.Username << ":" << m_settings.Password << "@" << m_settings.IpAddress << ":" << port << "/videoSub";
  99. std::string folderName = GetFolderName(m_settings);
  100. if (!Util::FolderExists(folderName))
  101. {
  102. try
  103. {
  104. Util::CreateFolder(folderName);
  105. }
  106. catch (const std::exception& e)
  107. {
  108. std::cerr << "Exception caught" << std::endl;
  109. std::stringstream ss;
  110. ss << "Type : " << typeid(e).name() << std::endl;
  111. ss << "ERROR: " << e.what() << std::endl;
  112. Logging::Log(Logging::Severity::Error, ss.str());
  113. return std::string();
  114. }
  115. }
  116. if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
  117. {
  118. Logging::Log(Logging::Severity::Debug, "FoscamRecorder Video Cancelled, Recording in progress");
  119. return std::string();
  120. }
  121. std::string dateTimeString = Util::GetDateTimeString();
  122. std::string fileName = GetFileName(m_settings, "mp4", dateTimeString);
  123. std::stringstream command;
  124. command << ffmpeg << " -i \"" << url.str() << "\" -t 30 -timeout 60 -c:v copy -an -strict experimental " << fileName << " > /dev/null 2>&1 ; " << ffmpeg << " -i " << fileName << " -vf \"select=eq(n\\,0)\" -q:v 3 " << fileName << ".jpg > /dev/null 2>&1";
  125. std::string cmd(command.str());
  126. Logging::Log(Logging::Severity::Debug, cmd);
  127. Settings settings = m_settings;
  128. Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
  129. pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
  130. pRecorderMutex->RegisterRecording(settings.IpAddress);
  131. int retval = std::system(cmd.c_str());
  132. pRecorderMutex->UnregisterRecording(settings.IpAddress);
  133. } );
  134. return fileName;
  135. }
  136. std::string FoscamRecorder::GetFolderName(const Settings& settings)
  137. {
  138. filesystem::path fileLocation(settings.Path);
  139. fileLocation = fileLocation / filesystem::path(settings.IpAddress);
  140. return fileLocation.str();
  141. }
  142. std::string FoscamRecorder::GetFileName(const Settings& settings, const std::string& extension, const std::string& dateTimeString)
  143. {
  144. filesystem::path fileLocation(GetFolderName(settings));
  145. std::string fileName = std::string(dateTimeString).append(".").append(extension);
  146. filesystem::path fullFileName = fileLocation / filesystem::path(fileName);
  147. return fullFileName.str();
  148. }
  149. void FoscamRecorder::Snapshots(Http::HttpClient* pHttpClient, const Settings& settings, std::string dateTimeString, int numberOfImages)
  150. {
  151. std::vector<Image::JpegImage> images;
  152. for (int i = 0; i < numberOfImages; ++i)
  153. images.push_back(FoscamRecorder::Snapshot(pHttpClient, settings));
  154. Image::JpegImageCollection collection(images);
  155. collection.Save(FoscamRecorder::GetFileName(settings, "jpg", dateTimeString));
  156. }
  157. Image::JpegImage FoscamRecorder::Snapshot(Http::HttpClient* pHttpClient, const Settings& settings)
  158. {
  159. std::stringstream url;
  160. url << "http://" << settings.IpAddress << ":" << settings.Port << "/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=" << settings.Username << "&pwd=" << settings.Password;
  161. Image::JpegImage image;
  162. try
  163. {
  164. Http::HttpRequest request(url.str());
  165. image.SetImageData(pHttpClient->Open(request));
  166. }
  167. catch (const std::exception& e)
  168. {
  169. std::stringstream ss;
  170. ss << "FoscamRecorder::Snapshot() - Error: " << e.what() << std::endl;
  171. Logging::Log(Logging::Severity::Error, ss.str());
  172. }
  173. return image;
  174. }
  175. } // namespace Recorder
  176. } // namespace CameraRecorder