WatchBotRecorder.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include "WatchBotRecorder.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 <vector>
  11. namespace CameraRecorder {
  12. namespace Recorder {
  13. WatchBotRecorder::WatchBotRecorder(Http::HttpClient* pHttpClient, const Settings& settings, Util::RecorderMutexPointer pRecorderMutex) :
  14. Recorder(pRecorderMutex),
  15. m_pHttpClient(pHttpClient),
  16. m_settings(settings)
  17. {
  18. }
  19. WatchBotRecorder::~WatchBotRecorder()
  20. {
  21. }
  22. std::string WatchBotRecorder::Snapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg)
  23. {
  24. Logging::Log(Logging::Severity::Debug, "WatchBotRecorder 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. WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, 1);
  52. // pRecorderMutex->UnregisterRecording(settings.IpAddress);
  53. //} );
  54. return fileName;
  55. }
  56. std::string WatchBotRecorder::MultiSnapshot(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg, int numberOfImages)
  57. {
  58. Logging::Log(Logging::Severity::Debug, "WatchBotRecorder 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, "WatchBotRecorder 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. WatchBotRecorder::Snapshots(pHttpClient, settings, dateTimeString, numberOfImages);
  89. pRecorderMutex->UnregisterRecording(settings.IpAddress);
  90. } );
  91. return fileName;
  92. }
  93. std::string WatchBotRecorder::Video(ctpl::thread_pool* pThreadPool, const std::string& ffmpeg)
  94. {
  95. Logging::Log(Logging::Severity::Debug, "WatchBotRecorder Video");
  96. std::stringstream url;
  97. url << "http://" << m_settings.IpAddress << ":" << m_settings.Port << "/videostream.asf?user=" << m_settings.Username << "&pwd=" << m_settings.Password;
  98. std::string folderName = GetFolderName(m_settings);
  99. if (!Util::FolderExists(folderName))
  100. {
  101. try
  102. {
  103. Util::CreateFolder(folderName);
  104. }
  105. catch (const std::exception& e)
  106. {
  107. std::cerr << "Exception caught" << std::endl;
  108. std::stringstream ss;
  109. ss << "Type : " << typeid(e).name() << std::endl;
  110. ss << "ERROR: " << e.what() << std::endl;
  111. Logging::Log(Logging::Severity::Error, ss.str());
  112. return std::string();
  113. }
  114. }
  115. if (m_pRecorderMutex->IsRecording(m_settings.IpAddress))
  116. {
  117. Logging::Log(Logging::Severity::Debug, "WatchBotRecorder MultiSnapshot Cancelled, Recording in progress");
  118. return std::string();
  119. }
  120. std::string dateTimeString = Util::GetDateTimeString();
  121. std::string fileName = GetFileName(m_settings, "mp4", dateTimeString);
  122. std::stringstream command;
  123. command << ffmpeg << " -i \"" << url.str() << "\" -t 30 -timeout 60 -c:v libx264 -pix_fmt yuv420p -profile:v main -level:v 3.1 -c:a aac -strict experimental " << fileName << " > /dev/null 2>&1 ; " << ffmpeg << " -i " << fileName << " -vf \"select=eq(n\\,0)\" -q:v 3 " << fileName << ".jpg > /dev/null 2>&1";
  124. std::string cmd(command.str());
  125. Logging::Log(Logging::Severity::Debug, cmd);
  126. Settings settings = m_settings;
  127. Util::RecorderMutexPointer pRecorderMutex = m_pRecorderMutex;
  128. pThreadPool->push( [cmd, settings, pRecorderMutex](int) {
  129. pRecorderMutex->RegisterRecording(settings.IpAddress);
  130. int retval = std::system(cmd.c_str());
  131. pRecorderMutex->UnregisterRecording(settings.IpAddress);
  132. } );
  133. return fileName;
  134. }
  135. std::string WatchBotRecorder::GetFolderName(const Settings& settings)
  136. {
  137. filesystem::path fileLocation(settings.Path);
  138. fileLocation = fileLocation / filesystem::path(settings.IpAddress);
  139. return fileLocation.str();
  140. }
  141. std::string WatchBotRecorder::GetFileName(const Settings& settings, const std::string& extension, const std::string& dateTimeString)
  142. {
  143. filesystem::path fileLocation(GetFolderName(settings));
  144. std::string fileName = std::string(dateTimeString).append(".").append(extension);
  145. filesystem::path fullFileName = fileLocation / filesystem::path(fileName);
  146. return fullFileName.str();
  147. }
  148. void WatchBotRecorder::Snapshots(Http::HttpClient* pHttpClient, const Settings& settings, std::string dateTimeString, int numberOfImages)
  149. {
  150. std::vector<Image::JpegImage> images;
  151. for (int i = 0; i < numberOfImages; ++i)
  152. images.push_back(WatchBotRecorder::Snapshot(pHttpClient, settings));
  153. Image::JpegImageCollection collection(images);
  154. collection.Save(WatchBotRecorder::GetFileName(settings, "jpg", dateTimeString));
  155. }
  156. Image::JpegImage WatchBotRecorder::Snapshot(Http::HttpClient* pHttpClient, const Settings& settings)
  157. {
  158. std::stringstream url;
  159. url << "http://" << settings.IpAddress << ":" << settings.Port << "/snapshot.cgi?user=" << settings.Username << "&pwd=" << settings.Password;
  160. Image::JpegImage image;
  161. try
  162. {
  163. Http::HttpRequest request(url.str());
  164. image.SetImageData(pHttpClient->Open(request));
  165. }
  166. catch (const std::exception& e)
  167. {
  168. std::stringstream ss;
  169. ss << "WatchBotRecorder::Snapshot() - Error: " << e.what() << std::endl;
  170. Logging::Log(Logging::Severity::Error, ss.str());
  171. }
  172. return image;
  173. }
  174. } // namespace Recorder
  175. } // namespace CameraRecorder