mod_recorder.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. #include "mod_recorder.h"
  2. #ifdef RVC_OS_WIN
  3. #include "stdafx.h"
  4. #include "filecryption.h"
  5. #else
  6. #include <sys/stat.h>
  7. #endif // RVC_OS_WIN
  8. #include "Event.h"
  9. #include "y2k_time.h"
  10. #include <string.h>
  11. #include "mod_facetracking/sysvar.h"
  12. #include "mod_interactivecontrol/Event.h"
  13. #include "mod_mediacontroller/Event.h"
  14. using namespace Recorder;
  15. #ifndef RVC_MAX_VIDEO_NAME_LEN
  16. #define RVC_MAX_VIDEO_NAME_LEN 256
  17. #endif
  18. #ifndef RVC_FILEENC_STR
  19. #define RVC_FILEENC_STR "enc_"
  20. #endif
  21. #ifndef MAX_LOG_LEN
  22. #define MAX_LOG_LEN 512
  23. #endif
  24. #ifndef RVC_TRANSATCION_RECORD_SUFFIX
  25. #define RVC_TRANSATCION_RECORD_SUFFIX "B_"
  26. #endif // !RVC_TRANSATCION_RECORD_SUFFIX
  27. static unsigned long GetFileSize(const char* pfilename)
  28. {
  29. #ifdef RVC_OS_WIN
  30. unsigned long usize = 0;
  31. if (NULL == pfilename) {
  32. return usize;
  33. }
  34. FILE* pFile = fopen(pfilename, "rb");
  35. if (pFile) {
  36. fseek(pFile, 0, SEEK_END);
  37. usize = ftell(pFile);
  38. fclose(pFile);
  39. }
  40. return usize;
  41. #else
  42. struct stat statbuf;
  43. stat(pfilename, &statbuf);
  44. return statbuf.st_size;
  45. #endif
  46. }
  47. static const char* GetFileName(const char* pfilename)
  48. {
  49. if (NULL == pfilename) {
  50. return NULL;
  51. }
  52. return strstr(pfilename, RVC_TRANSATCION_RECORD_SUFFIX);
  53. }
  54. static void LogVideoSizeInfo(const char* pszMessage)
  55. {
  56. unsigned long ufilesize = GetFileSize(pszMessage);
  57. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_VIDEO_SIZE, CSimpleStringA::Format("%s file size is %u byte.", pszMessage, ufilesize).GetData());
  58. }
  59. void rvcDbg(const char* fmt, ...)
  60. {
  61. va_list arg;
  62. va_start(arg, fmt);
  63. int n = vsnprintf(NULL, 0, fmt, arg);
  64. if (n >= MAX_LOG_LEN) {
  65. char* buf = (char*)malloc((size_t)(n + 1));
  66. vsnprintf(buf, n + 1, fmt, arg);
  67. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  68. free(buf);
  69. }
  70. else{
  71. char strlog[MAX_LOG_LEN] = {0};
  72. vsnprintf(strlog, MAX_LOG_LEN, fmt, arg);
  73. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  74. }
  75. va_end(arg);
  76. }
  77. static bool rvcMoveFile(const char* strSrcFile, const char* strDstFile)
  78. {
  79. bool bRet = false;
  80. if (NULL == strSrcFile || NULL == strDstFile) {
  81. return bRet;
  82. }
  83. #ifdef RVC_OS_WIN
  84. bRet = MoveFile(strSrcFile, strDstFile);
  85. #else
  86. if (0 == rename(strSrcFile, strDstFile)) {
  87. bRet = true;
  88. }
  89. #endif // RVC_OS_WIN
  90. return bRet;
  91. }
  92. void RecordServiceSession::Handle_StartTransactionRecord(SpReqAnsContext<RecorderSerVice_StartTransactionRecord_Req, RecorderSerVice_StartTransactionRecord_Ans>::Pointer ctx)
  93. {
  94. DbgToBeidou(ctx->link, __FUNCTION__)();
  95. if (m_pEntity->GetStartFlag()) {
  96. m_pEntity->StopRecord();
  97. }
  98. m_pEntity->SetRecordSessionID(ctx->Req.VideoName.GetData());
  99. m_pEntity->StartRecord(CSimpleStringA::Format("%s%s", RVC_TRANSATCION_RECORD_SUFFIX, ctx->Req.VideoName.GetData()).GetData());
  100. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start video record %s.", ctx->Req.VideoName.GetData());
  101. ctx->Answer(Error_Succeed);
  102. }
  103. void RecordServiceSession::Handle_StopTransactionRecord(SpReqAnsContext<RecorderSerVice_StopTransactionRecord_Req, RecorderSerVice_StopTransactionRecord_Ans>::Pointer ctx)
  104. {
  105. DbgToBeidou(ctx->link, __FUNCTION__)();
  106. m_pEntity->StopRecord();
  107. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop video record %s.", ctx->Req.VideoName.GetData());
  108. ctx->Answer(Error_Succeed);
  109. }
  110. void CRecorderEntity::OnPreStart(CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext)
  111. {
  112. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  113. pTransactionContext->SendAnswer(Error);
  114. }
  115. void CRecorderEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext)
  116. {
  117. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  118. pTransactionContext->SendAnswer(Error);
  119. }
  120. ErrorCodeEnum CRecorderEntity::__OnStart(ErrorCodeEnum preOperationError)
  121. {
  122. ErrorCodeEnum Error = Error_Succeed;
  123. m_eDeviceType = RvcGetDeviceType();
  124. if (preOperationError != Error_Succeed) {
  125. return preOperationError;
  126. }
  127. m_iActiveCamera = CAMERA_TYPE_ENV;
  128. m_iCameraState = 'N';
  129. InitRecorder();
  130. int i = 0;
  131. m_arrListener.Init(7);
  132. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_PAUSE_RECORD, NULL, false);
  133. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, EVENT_MOD_CONTINUE_RECORD, NULL, false);
  134. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_RECORDER_SECTION_FINISHED, NULL, false);
  135. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_RECORDER_WHOLE_FINISHED, NULL, false);
  136. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_START_BUSINESSRECORD_FAILED, NULL, false);
  137. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED, NULL, false);
  138. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_Middle, Error_IgnoreAll, LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED, NULL, false);
  139. GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA,this);
  140. GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE,this);
  141. CSimpleStringA strValue;
  142. GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue);
  143. m_iCameraState = strValue[0];
  144. if (strValue[0] == 'E'){
  145. m_iActiveCamera = CAMERA_TYPE_OPT;
  146. if (eStand1SPlusType == m_eDeviceType){
  147. m_iActiveCamera = CAMERA_TYPE_ERROR;
  148. }
  149. }
  150. else if (strValue[0] == 'O'){
  151. m_iActiveCamera = CAMERA_TYPE_ENV;
  152. }
  153. else if(strValue[0] == 'B'){
  154. m_iActiveCamera = CAMERA_TYPE_ERROR;
  155. }
  156. else if (strValue[0] == 'N'){
  157. m_iActiveCamera = CAMERA_TYPE_ENV;
  158. }
  159. Error = GetFunction()->GetPath("Temp", m_TempDir);
  160. if (Error != Error_Succeed) {
  161. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record temp path failed!");
  162. }
  163. if (m_TempDir.GetLength() > 0 && m_TempDir[m_TempDir.GetLength()-1] != SPLIT_SLASH) {
  164. m_TempDir += SPLIT_SLASH_STR;
  165. }
  166. Error = GetFunction()->GetPath("UploadVideo", m_RecordSaveDir);
  167. if (Error != Error_Succeed) {
  168. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record save path failed!");
  169. }
  170. if (m_RecordSaveDir.GetLength() > 0 && m_RecordSaveDir[m_RecordSaveDir.GetLength()-1] != SPLIT_SLASH) {
  171. m_RecordSaveDir += SPLIT_SLASH_STR;
  172. }
  173. return Error;
  174. }
  175. void CRecorderEntity::OnStarted()
  176. {
  177. CSystemStaticInfo si;
  178. ErrorCodeEnum Error = GetFunction()->GetSystemStaticInfo(si);
  179. if (Error == Error_Succeed) {
  180. m_strAppVersion = si.InstallVersion.ToString();
  181. m_strTerminalId = si.strTerminalID;
  182. }
  183. LoadEntityConfig();
  184. //DeleteExceptionLogFiles();
  185. SaveExceptionRecordVideos();
  186. if (m_vRecordList.size() > 0) {
  187. HandleExceptionRecordVideos();
  188. PostVideoRecordInfos();
  189. }
  190. }
  191. bool CRecorderEntity::InitRecorder()
  192. {
  193. bool bRet = false;
  194. if (eStand1SPlusType == m_eDeviceType) {
  195. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
  196. REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, NULL);
  197. }
  198. else {
  199. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE,
  200. REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE, REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE);
  201. }
  202. return bRet;
  203. }
  204. bool CRecorderEntity::ReleaseRecorder()
  205. {
  206. if (m_pRecorder) {
  207. delete m_pRecorder;
  208. m_pRecorder = NULL;
  209. }
  210. return true;
  211. }
  212. ErrorCodeEnum CRecorderEntity::__OnClose(ErrorCodeEnum preOperationError)
  213. {
  214. if (preOperationError != Error_Succeed) {
  215. return preOperationError;
  216. }
  217. for (int i = 0; i < m_arrListener.GetCount(); ++i) {
  218. GetFunction()->UnsubscribeLog(m_arrListener[i]);
  219. }
  220. GetFunction()->UnregistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA);
  221. GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE);
  222. StopRecord();
  223. return Error_Succeed;
  224. }
  225. CServerSessionBase* CRecorderEntity::OnNewSession(const char* pszRemoteEntityName, const char* pszClass)
  226. {
  227. return new RecordServiceSession(this);
  228. }
  229. void CRecorderEntity::Debug(record_loglevel elevel, const char *fmt, ...)
  230. {
  231. if (RECORD_LOG_INFO <= elevel) {
  232. va_list arg;
  233. va_start(arg, fmt);
  234. int n = vsnprintf(NULL, 0, fmt, arg);
  235. if (n >= MAX_LOG_LEN) {
  236. char* buf = (char*)malloc((size_t)(n + 1));
  237. vsnprintf(buf, n + 1, fmt, arg);
  238. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  239. free(buf);
  240. }
  241. else{
  242. char strlog[MAX_LOG_LEN] = {0};
  243. vsnprintf(strlog, MAX_LOG_LEN, fmt, arg);
  244. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  245. }
  246. va_end(arg);
  247. }
  248. }
  249. void CRecorderEntity::vDebug(record_loglevel elevel, const char* str, va_list list)
  250. {
  251. if (RECORD_LOG_INFO <= elevel) {
  252. int n = vsnprintf(NULL, 0, str, list);
  253. if (n >= MAX_LOG_LEN) {
  254. char* buf = (char*)malloc((size_t)(n + 1));
  255. vsnprintf(buf, n + 1, str, list);
  256. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  257. free(buf);
  258. }
  259. else {
  260. char strlog[MAX_LOG_LEN] = { 0 };
  261. vsnprintf(strlog, MAX_LOG_LEN, str, list);
  262. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  263. }
  264. }
  265. }
  266. int CRecorderEntity::GetActiveCamera()
  267. {
  268. return m_iActiveCamera;
  269. }
  270. ErrorCodeEnum CRecorderEntity::LoadEntityConfig()
  271. {
  272. ErrorCodeEnum Error = Error_Succeed;
  273. int iTimeOut = RVC_HTTPTIMEOUT;
  274. CSimpleStringA strHttpServerAddr("");
  275. CSmartPointer<IConfigInfo> spConfig;
  276. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  277. if (spFunction->OpenConfig(Config_CenterSetting, spConfig) == Error_Succeed) {
  278. spConfig->ReadConfigValue("Recorder", "http_video_record_addr", strHttpServerAddr);
  279. spConfig->ReadConfigValueInt("Recorder", "http_timeout", iTimeOut);
  280. }
  281. else {
  282. Error = Error_Failed;
  283. }
  284. if (strHttpServerAddr.GetLength() > 0) {
  285. m_strHttpServerAddr = strHttpServerAddr;
  286. }
  287. m_eRecordType = eMP4;
  288. if (iTimeOut > 0 && iTimeOut < 20 * RVC_HTTPTIMEOUT) {
  289. m_iHttpTimeOut = iTimeOut;
  290. }
  291. return Error;
  292. }
  293. ErrorCodeEnum CRecorderEntity::PostVideoRecordInfos()
  294. {
  295. ErrorCodeEnum Error = Error_Failed;
  296. char strtimenow[MAX_PATH] = { 0 };
  297. y2k_time_t nowtime = y2k_time_now();
  298. y2k_to_string(nowtime, strtimenow, MAX_PATH);
  299. video_record_info_t video_params;
  300. video_params.strServerURL = m_strHttpServerAddr;
  301. video_params.strAPI = m_strHttpServerAPI;
  302. video_params.strAppVersion = m_strAppVersion;
  303. video_params.strRecordEndTime = strtimenow;
  304. video_params.strTerminalNo = m_strTerminalId;
  305. video_params.iBusinessStatus = (int)m_eBusinessStatus;
  306. if (eFailed == m_eBusinessStatus) {
  307. if (m_vRecordList.size() > 0) {
  308. video_params.iBusinessStatus = eInterrupt;
  309. }
  310. }
  311. video_params.strRecordID = m_strRecordName;
  312. for (vector<record_item_t>::iterator it = m_vRecordList.begin(); it < m_vRecordList.end(); ++it) {
  313. video_params.vRecordList.push_back(*it);
  314. }
  315. unsigned int uposttime = 0;
  316. CSimpleStringA strErrorMsg("");
  317. if (0 == post_video_recordinfo_list(uposttime, strErrorMsg, &video_params, m_iHttpTimeOut, false)) {
  318. LogWarn(Severity_Low, Error_Debug, LOG_EVT_POST_RECORDINFO_COST_TIME, CSimpleStringA::Format("post video record infos cost time is %ums.", uposttime).GetData());
  319. Error = Error_Succeed;
  320. }
  321. else {
  322. LogWarn(Severity_Middle, Error_Exception, LOG_EVT_POST_RECORDINFO_FAILED, strErrorMsg.GetData());
  323. }
  324. m_vRecordList.clear();
  325. return Error;
  326. }
  327. ErrorCodeEnum CRecorderEntity::HandleExceptionRecordVideos()
  328. {
  329. ErrorCodeEnum Error = Error_Failed;
  330. const char* videofilename = m_vRecordList[0].file_path.c_str();
  331. if (NULL == videofilename) {
  332. return Error;
  333. }
  334. char strSession[RVC_MAX_VIDEO_NAME_LEN] = { 0 };
  335. int iSeriesNum = -1;
  336. char strFormat[RVC_MAX_VIDEO_NAME_LEN] = { 0 };
  337. if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)) {
  338. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename);
  339. return Error;
  340. }
  341. SetRecordSessionID(strSession + strlen(RVC_TRANSATCION_RECORD_SUFFIX));
  342. while (--iSeriesNum >= 0) {
  343. CSimpleStringA strFilePath("");
  344. strFilePath = CSimpleStringA::Format("%s%s_%d.%s", m_RecordSaveDir.GetData(), strSession, iSeriesNum, strFormat);
  345. if (ExistsFile(strFilePath.GetData())) {
  346. AddToVideoRecordList(strFilePath.GetData());
  347. }
  348. else {
  349. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File {%s} is not exist.", strFilePath.GetData());
  350. }
  351. }
  352. return Error;
  353. }
  354. ErrorCodeEnum CRecorderEntity::AddToVideoRecordList(const char* videofilename)
  355. {
  356. ErrorCodeEnum Error = Error_Failed;
  357. if (NULL == videofilename) {
  358. return Error;
  359. }
  360. record_item_t* item = new record_item_t();
  361. item->file_path = videofilename;
  362. item->file_length = (int)GetFileSize(videofilename);
  363. const char* strfilename = GetFileName(videofilename);
  364. if (strfilename) {
  365. item->file_name = strfilename;
  366. }
  367. m_vRecordList.push_back(*item);
  368. Error = Error_Succeed;
  369. return Error;
  370. }
  371. void CRecorderEntity::OnRecordFailed(eRvcRecordFailedCase eCase, const char *pszMessage, bool bRecordDevFault)
  372. {
  373. m_eBusinessStatus = eFailed;
  374. if (!bRecordDevFault){
  375. LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"0");
  376. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDING_FAILED, CSimpleStringA::Format("%s 本地录音录像失败,已停止!", pszMessage ? pszMessage : " ").GetData());
  377. }
  378. else{
  379. LogEvent(Severity_Middle,LOG_EVT_RECORDFAILED,"1");
  380. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORDING_FAILED, CSimpleStringA::Format("%s 本地录音录像设备故障,尝试恢复中(预计10s内),请稍等", pszMessage ? pszMessage : " ").GetData());
  381. }
  382. }
  383. void CRecorderEntity::OnRecordEntityExcption()
  384. {
  385. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_ENTITY_EXCEPTION, "OnRecordEntityExcption!");
  386. }
  387. void CRecorderEntity::OnRecordFinished()
  388. {
  389. }
  390. int CRecorderEntity:: GetCameraState()
  391. {
  392. return m_iCameraState;
  393. }
  394. void CRecorderEntity::OnASectionFinished(const char *pszMessage, int iSerialNum, bool bfinished)
  395. {
  396. if (false == bfinished){
  397. LogEvent(Severity_Middle, LOG_EVT_RECORDER_SECTION_FINISHED, pszMessage);
  398. }
  399. else{
  400. LogEvent(Severity_Middle, LOG_EVT_RECORDER_WHOLE_FINISHED, pszMessage);
  401. }
  402. }
  403. void CRecorderEntity::OnLog(const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel,
  404. const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID,
  405. const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext& pLinkInfo)
  406. {
  407. switch (dwUserCode)
  408. {
  409. case EVENT_MOD_PAUSE_RECORD:
  410. m_pRecorder->PauseRecord();
  411. if (m_bStarted) {
  412. m_pRecorder->CloseVideoFile();
  413. }
  414. break;
  415. case EVENT_MOD_CONTINUE_RECORD:
  416. m_pRecorder->ContinueRecord();
  417. break;
  418. case LOG_EVT_RECORDER_SECTION_FINISHED:
  419. {
  420. LogVideoSizeInfo(pszMessage);
  421. if (m_bEncFlag){
  422. HandleEncryptVideoRecord(pszMessage);
  423. }
  424. HandleSaveVideoRecord(pszMessage);
  425. }
  426. break;
  427. case LOG_EVT_RECORDER_WHOLE_FINISHED:
  428. {
  429. LogVideoSizeInfo(pszMessage);
  430. if (m_bEncFlag){
  431. HandleEncryptVideoRecord(pszMessage);
  432. }
  433. HandleFinishedVideoRecord(pszMessage);
  434. PostVideoRecordInfos();
  435. }
  436. break;
  437. case LOG_EVT_START_BUSINESSRECORD_FAILED:
  438. m_eBusinessStatus = eFailed;
  439. PostVideoRecordInfos();
  440. break;
  441. case LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED:
  442. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STARTED event");
  443. break;
  444. case LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED:
  445. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv LOG_EVT_MEDIACONTROLLER_CAMERA_STOPPED event");
  446. break;
  447. default:
  448. break;
  449. }
  450. }
  451. void CRecorderEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName)
  452. {
  453. if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
  454. {
  455. m_iCameraState = pszValue[0];
  456. if (pszValue[0] == 'E'){
  457. m_iActiveCamera = CAMERA_TYPE_OPT;
  458. }
  459. else if (pszValue[0] == 'O'){
  460. m_iActiveCamera = CAMERA_TYPE_ENV;
  461. }
  462. else if(pszValue[0] == 'B'){
  463. m_iActiveCamera = CAMERA_TYPE_ERROR;
  464. }
  465. else if (pszValue[0] == 'N'){
  466. m_iActiveCamera = CAMERA_TYPE_ENV;
  467. }
  468. }
  469. else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0)
  470. {
  471. if (m_iCameraState == 'N'){
  472. if (pszValue[0] == 'E'){
  473. m_iActiveCamera = CAMERA_TYPE_ENV;
  474. }
  475. else if (pszValue[0] == 'O'){
  476. m_iActiveCamera = CAMERA_TYPE_OPT;
  477. }
  478. }
  479. }
  480. }
  481. void CRecorderEntity::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  482. {
  483. if (Test_ShakeHand == eTestType){
  484. pTransactionContext->SendAnswer(Error_Succeed);
  485. }
  486. }
  487. void CRecorderEntity::StartRecord(const char *videofilename)
  488. {
  489. int fps = 5;
  490. Rvc_RecordAudioParam_t tAudioParams;
  491. tAudioParams.eRecordType = eSingleSide;
  492. tAudioParams.eOutPutType = eLowDefinition;
  493. tAudioParams.bIsNsOn = true;
  494. tAudioParams.iNsPolicy = 2;
  495. tAudioParams.iAudioOutBitRate = 8;
  496. tAudioParams.bIsTransOn = false;
  497. tAudioParams.iAudioChannels = 1;
  498. if (m_pRecorder->StartVideoRecord(fps, 75, m_eRecordType, &tAudioParams, NULL, false, true, m_TempDir.GetData(), m_RecordSaveDir.GetLength(), videofilename, strlen(videofilename)))
  499. {
  500. m_bStarted = true;
  501. m_eBusinessStatus = eSuccess;
  502. }
  503. }
  504. void CRecorderEntity::StopRecord()
  505. {
  506. if (m_bStarted) {
  507. m_pRecorder->StopVideoRecord();
  508. m_bStarted = false;
  509. }
  510. }
  511. void CRecorderEntity::SetRecordSessionID(const char* strRecordID)
  512. {
  513. if (NULL != strRecordID) {
  514. memset(m_strRecordName, 0 , MAX_PATH);
  515. snprintf(m_strRecordName, MAX_PATH, "%s", strRecordID);
  516. }
  517. }
  518. void CRecorderEntity::GetRecordSessionID(char* strRecordID, size_t uLen)
  519. {
  520. if (NULL != strRecordID) {
  521. snprintf(strRecordID, uLen, "%s", m_strRecordName);
  522. }
  523. }
  524. DeviceTypeEnum CRecorderEntity::RvcGetDeviceType()
  525. {
  526. DeviceTypeEnum eType = eStand2sType;
  527. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  528. CSystemStaticInfo stStaticinfo;
  529. spFunction->GetSystemStaticInfo(stStaticinfo);
  530. if (_stricmp(stStaticinfo.strMachineType.GetData(), "RVC.Stand1SPlus") == 0) {
  531. eType = eStand1SPlusType;
  532. }
  533. else if (_stricmp(stStaticinfo.strMachineType.GetData(), "RVC.CardStore") == 0 || _stricmp(stStaticinfo.strMachineType.GetData(), "RVC.CardPrinter") == 0) {
  534. eType = eCardStore;
  535. }
  536. else {
  537. eType = eStand2sType;
  538. }
  539. if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) {
  540. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]);
  541. }
  542. m_terminalNo = stStaticinfo.strTerminalID;
  543. return eType;
  544. }
  545. int CRecorderEntity::HandleFinishedVideoRecord(const char* videofilename)
  546. {
  547. int iRet = -1;
  548. if (NULL == videofilename){
  549. return iRet;
  550. }
  551. char strSession[RVC_MAX_VIDEO_NAME_LEN] = {0};
  552. int iSeriesNum = -1;
  553. char strFormat[RVC_MAX_VIDEO_NAME_LEN] = {0};
  554. if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)){
  555. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename);
  556. return iRet;
  557. }
  558. CSimpleStringA srcfile = CSimpleStringA::Format("%s%s_%d_end.%s", m_TempDir.GetData(), strSession, iSeriesNum, strFormat);
  559. CSimpleStringA dstfile = CSimpleStringA::Format("%s%s_%d_end.%s", m_RecordSaveDir.GetData(), strSession, iSeriesNum, strFormat);
  560. bool bRet = false;
  561. if (ExistsFile(srcfile.GetData())){
  562. bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData());
  563. if(!bRet) {
  564. #ifdef RVC_OS_WIN
  565. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData()).GetData());
  566. #else
  567. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData()).GetData());
  568. #endif // RVC_OS_WIN
  569. }
  570. else {
  571. AddToVideoRecordList(dstfile.GetData());
  572. }
  573. }
  574. srcfile = CSimpleStringA::Format("%s%s_%d.%s",m_TempDir.GetData(), strSession, iSeriesNum-1, strFormat);
  575. dstfile = CSimpleStringA::Format("%s%s_%d.%s",m_RecordSaveDir.GetData(), strSession, iSeriesNum-1, strFormat);
  576. if (ExistsFile(srcfile.GetData())){
  577. bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData());
  578. if(!bRet) {
  579. #ifdef RVC_OS_WIN
  580. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData()).GetData());
  581. #else
  582. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData()).GetData());
  583. #endif // RVC_OS_WIN
  584. }
  585. else {
  586. AddToVideoRecordList(dstfile.GetData());
  587. }
  588. }
  589. iRet = 0;
  590. return iRet;
  591. }
  592. int CRecorderEntity::HandleEncryptVideoRecord(const char* videofilename)
  593. {
  594. int iRet = -1;
  595. if (NULL == videofilename){
  596. return iRet;
  597. }
  598. #ifdef RVC_OS_WIN
  599. filecryption_callback_t cb = {0};
  600. cb.dbg = &rvcDbg;
  601. char strOutFile[MAX_PATH] = {0};
  602. int iresult = encryption_file(strOutFile, MAX_PATH, videofilename, &cb, eVerA);
  603. if (0 != iresult){
  604. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_ENCRYPT_FAILED, CSimpleStringA::Format("encryption file %s failed, delete out temp file %s!", videofilename, strOutFile).GetData());
  605. if (!DeleteFile(strOutFile)){
  606. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile);
  607. }
  608. return iRet;
  609. }
  610. BOOL bRet = DeleteFile(videofilename);
  611. if(!bRet) {
  612. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_DELETE_FAILED, CSimpleStringA::Format("Error Code %lu while delete %s, delete out temp file[%s]!", GetLastError(), videofilename, strOutFile).GetData());
  613. if (!DeleteFile(strOutFile)){
  614. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("DeleteFile file %s failed!", strOutFile);
  615. }
  616. return iRet;
  617. }
  618. else{
  619. if (!rename(strOutFile, videofilename)){
  620. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("rename %s to %s Success!",strOutFile, videofilename);
  621. iRet = 0;
  622. }
  623. else{
  624. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("Error Code %lu while rename %s.", GetLastError(), strOutFile).GetData());
  625. }
  626. }
  627. #endif // RVC_OS_WIN
  628. return iRet;
  629. }
  630. int CRecorderEntity::HandleSaveVideoRecord(const char* videofilename)
  631. {
  632. int iRet = -1;
  633. if (NULL == videofilename){
  634. return iRet;
  635. }
  636. char strSession[RVC_MAX_VIDEO_NAME_LEN] = {0};
  637. int iSeriesNum = -1;
  638. char strFormat[RVC_MAX_VIDEO_NAME_LEN] = {0};
  639. if (-1 == GetRecordVideoInfo(videofilename, strSession, RVC_MAX_VIDEO_NAME_LEN, &iSeriesNum, strFormat, RVC_MAX_VIDEO_NAME_LEN)){
  640. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[%s] get record video info failed.", videofilename);
  641. return iRet;
  642. }
  643. CSimpleStringA srcfile = CSimpleStringA::Format("%s%s_%d.%s", m_TempDir.GetData(), strSession, iSeriesNum, strFormat);
  644. CSimpleStringA dstfile = CSimpleStringA::Format("%s%s_%d.%s", m_RecordSaveDir.GetData(), strSession, iSeriesNum, strFormat);
  645. if (ExistsFile(srcfile.GetData())) {
  646. bool bRet = rvcMoveFile(srcfile.GetData(), dstfile.GetData());
  647. if (!bRet) {
  648. #ifdef RVC_OS_WIN
  649. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s ", GetLastError(), srcfile.GetData()));
  650. #else
  651. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("%s(%d) while move %s ", strerror(errno), errno, srcfile.GetData()));
  652. #endif // RVC_OS_WIN
  653. }
  654. else {
  655. AddToVideoRecordList(dstfile.GetData());
  656. }
  657. }
  658. iRet = 0;
  659. return iRet;
  660. }
  661. int CRecorderEntity::GetRecordVideoInfo(const char* videofilename, char* strSession, size_t uSessionLen, int* iSeriesNum, char* strFormat, size_t uFormatLen)
  662. {
  663. int iRet = -1;
  664. char strFileName[RVC_MAX_VIDEO_NAME_LEN] = {0};
  665. size_t uLen = strlen(videofilename);
  666. if (uLen <= RVC_MAX_VIDEO_NAME_LEN){
  667. const char *pIndex = strrchr(videofilename, SPLIT_SLASH);
  668. if (pIndex){
  669. snprintf(strFileName, RVC_MAX_VIDEO_NAME_LEN, "%s", pIndex + 1);
  670. }
  671. }
  672. else{
  673. return iRet;
  674. }
  675. int ioffset = 0;
  676. if (0 == memcmp(strFileName, RVC_TRANSATCION_RECORD_SUFFIX, strlen(RVC_TRANSATCION_RECORD_SUFFIX))) {
  677. ioffset = strlen(RVC_TRANSATCION_RECORD_SUFFIX);
  678. }
  679. char* pNum = strstr(strFileName+ioffset, "_");
  680. if (pNum){
  681. *pNum = 0;
  682. strcpy(strSession, strFileName);
  683. pNum++;
  684. }
  685. else{
  686. return iRet;
  687. }
  688. char* pend = strstr(pNum, "_end");
  689. if (pend){
  690. *pend = 0;
  691. *iSeriesNum = atoi(pNum);
  692. pNum = pend + 1;
  693. }
  694. char* pFormat = strstr(pNum, ".");
  695. if (pFormat){
  696. *pFormat = 0;
  697. pFormat++;
  698. strcpy(strFormat, pFormat);
  699. }
  700. else{
  701. return iRet;
  702. }
  703. if (NULL == pend){
  704. *iSeriesNum = atoi(pNum);
  705. }
  706. iRet = 0;
  707. return iRet;
  708. }
  709. int CRecorderEntity::SaveExceptionRecordVideos()
  710. {
  711. int iRet = -1;
  712. #ifdef RVC_OS_WIN
  713. char srcFilePath[MAX_PATH]={0};
  714. WIN32_FIND_DATA FindFileData;
  715. HANDLE hFind;
  716. bool fFinished = false;
  717. char strVideoFormat[MAX_PATH] = { 0 };
  718. if (eMP4 == m_eRecordType) {
  719. _snprintf(strVideoFormat, MAX_PATH, "%s", RECORD_MP4_SUFFIX);
  720. }
  721. else {
  722. _snprintf(strVideoFormat, MAX_PATH, "%s", RECORD_WMV_SUFFIX);
  723. }
  724. _snprintf(srcFilePath, MAX_PATH, "%s*.%s", m_TempDir.GetData(), strVideoFormat);
  725. hFind = FindFirstFile(srcFilePath, &FindFileData);
  726. if (INVALID_HANDLE_VALUE != hFind)
  727. {
  728. while (!fFinished){
  729. if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes){
  730. goto on_next;
  731. }
  732. if (NULL == strstr(FindFileData.cFileName, "S_") && NULL == strstr(FindFileData.cFileName, "G_")){
  733. CSimpleStringA srcfile = CSimpleStringA::Format("%s%s",m_TempDir.GetData(), FindFileData.cFileName);
  734. if (m_bEncFlag){
  735. filecryption_callback_t cb = {0};
  736. cb.dbg = &rvcDbg;
  737. if (false == is_file_encrypted(srcfile.GetData(), &cb)){
  738. HandleEncryptVideoRecord(srcfile.GetData());
  739. }
  740. else{
  741. char* pIndex = NULL;
  742. if (pIndex = strstr(FindFileData.cFileName, RVC_FILEENC_STR)){
  743. char strname[MAX_PATH] = {0};
  744. memcpy(strname, pIndex+strlen(RVC_FILEENC_STR), strlen(pIndex+strlen(RVC_FILEENC_STR)));
  745. CSimpleStringA tempsrcfile = CSimpleStringA::Format("%s%s",m_TempDir.GetData(), strname);
  746. if (!rename(srcfile.GetData(),tempsrcfile.GetData())){
  747. srcfile = tempsrcfile;
  748. memset(FindFileData.cFileName, 0, MAX_PATH);
  749. memcpy(FindFileData.cFileName, strname, strlen(strname));
  750. }
  751. else{
  752. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_RENAME_FAILED, CSimpleStringA::Format("Error Code %lu while rename %s.", GetLastError(), srcfile.GetData()).GetData());
  753. }
  754. }
  755. }
  756. }
  757. CSimpleStringA dstfile = CSimpleStringA::Format("%s%s",m_RecordSaveDir.GetData(), FindFileData.cFileName);
  758. BOOL bRet = MoveFile(srcfile.GetData(), dstfile.GetData());
  759. if(!bRet) {
  760. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORDER_MOVE_FAILED, CSimpleStringA::Format("Error Code %u while move %s -> %s", GetLastError(), srcfile.GetData(), dstfile.GetData()).GetData());
  761. }
  762. else{
  763. AddToVideoRecordList(dstfile.GetData());
  764. iRet = 0;
  765. }
  766. }
  767. on_next:
  768. if (!FindNextFile(hFind, &FindFileData)){
  769. if (GetLastError() == ERROR_NO_MORE_FILES){
  770. fFinished = true;
  771. }
  772. else{
  773. break;
  774. }
  775. }
  776. }
  777. FindClose(hFind);
  778. }
  779. #endif // RVC_OS_WIN
  780. return iRet;
  781. }
  782. SP_BEGIN_ENTITY_MAP()
  783. SP_ENTITY(CRecorderEntity)
  784. SP_END_ENTITY_MAP()