mod_SalesRecorder.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738
  1. #include "stdafx.h"
  2. #include "mod_SalesRecorder.h"
  3. using namespace SalesRecorder;
  4. #include "rvc_media_common.h"
  5. #include "fileutil.h"
  6. #include "array.h"
  7. #include <memutil.h>
  8. #include <algorithm>
  9. #include <Windows.h>
  10. #include "Event.h"
  11. #include "mod_customeraware/Event.h"
  12. #include "mod_facetracking/sysvar.h"
  13. #include <assert.h>
  14. #include "EventCode.h"
  15. #include "..\\mod_interactivecontrol\\InteractiveControl_client_g.h"
  16. #include "..\\mod_interactivecontrol\\InteractiveControl_def_g.h"
  17. #include "../mod_interactivecontrol/Event.h"
  18. using namespace InteractiveControl;
  19. #ifndef RVC_MIN_FILESIZE
  20. #define RVC_MIN_FILESIZE 10240
  21. #endif
  22. #define SYSVAR_CALLTYPE "CallType"
  23. #define CALLTYPE_NORMAL 'N' // 呼叫类型,普通模式
  24. #define CALLTYPE_MOBILE 'M' // 呼叫类型,手机模式
  25. #define MAX_DISK_PERCENT 95 // 磁盘最大占用百分比
  26. static const char* record_failed_case_table[] = {
  27. "[RTA3L01] 启动录像失败,初始化失败",
  28. "[RTA3L02] 启动录像失败,字体为空,添加水印失败",
  29. "[RTA3L03] 开始录像失败,请稍后(约30秒)再试",
  30. "[RTA3L04] 录像失败,摄像头故障,获取不到视频,请联系厂商进行维修",
  31. "[RTA3L05] 录像失败,获取不到远端音频,请检查风险提示音是否正常播放且音量大小是否正常",
  32. "[RTA3L06] 录像失败,麦克风故障,获取不到本地音频,请联系厂商进行维修",
  33. "[RTA3L07] 录像失败,系统不支持当前音频采样率",
  34. "[RTA3L08] 录像失败,音频流写入失败,请稍后(约30秒)再试",
  35. "[RTA3L09] 录像失败,获取不到远端视频,请稍后(约30秒)再试"
  36. };
  37. static BOOL CheckDiskStatus(const char *szRoot, int nPercent, int *pFreeRatio)
  38. {
  39. #ifdef RVC_OS_WIN
  40. _ULARGE_INTEGER lpFreeBytesAvailableToCaller = {}, lpTotalNumberOfBytes = {}, lpTotalNumberOfFreeBytes = {};
  41. BOOL ret = GetDiskFreeSpaceEx(szRoot, &lpFreeBytesAvailableToCaller, &lpTotalNumberOfBytes, &lpTotalNumberOfFreeBytes);
  42. if (ret == 0)
  43. {
  44. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("CheckDiskStatus.GetDiskFreeSpaceEx failed(%d).",GetLastError());
  45. return FALSE;
  46. }
  47. DWORD dwTotal = lpTotalNumberOfBytes.QuadPart/1048576;
  48. DWORD dwTotalFree = lpTotalNumberOfFreeBytes.QuadPart/1048576;
  49. int ratio = dwTotalFree*100/dwTotal;
  50. *pFreeRatio = ratio;
  51. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("free disk %d MB, %d percent free.\n", dwTotalFree, ratio);
  52. //if (ratio < (100-MAX_DISK_PERCENT))
  53. if (ratio < (100-nPercent))
  54. {
  55. return FALSE;
  56. }
  57. return TRUE;
  58. #else
  59. //todo 调用resourcewatcher
  60. return TRUE;
  61. #endif
  62. }
  63. static int hch2int(char hch)
  64. {
  65. if (hch >= '0' && hch <= '9')
  66. return hch-'0';
  67. else if (hch >= 'a' && hch <= 'f')
  68. return hch-'a'+10;
  69. else if (hch >= 'A' && hch <= 'F')
  70. return hch-'A'+10;
  71. return 0;
  72. }
  73. static long hexstr2int(const char *str, int len)
  74. {
  75. long result = 0;
  76. if (str && len <= strlen(str)) {
  77. for (int i = 0; i < len; ++i) {
  78. result += (hch2int(str[i]) << ((len-i-1) << 2));
  79. }
  80. }
  81. return result;
  82. }
  83. static CSimpleStringA VideoSerialID2TimeString(const char *videoserialid)
  84. {
  85. DWORD nTimeTicks = hexstr2int(videoserialid,8);
  86. return ((CSmallDateTime)nTimeTicks).ToTimeString();
  87. }
  88. static void CStringSplit(char* str, char** result, const char* del)
  89. {
  90. char *p = strtok(str, del);
  91. while(p != NULL)
  92. {
  93. *result++ = p;
  94. p = strtok(NULL, del);
  95. }
  96. }
  97. // 寻找某目录下与通配符匹配的文件
  98. static BOOL FindMatchedFile(LPCSTR sFindPath, LPCSTR sFindFileName, ULONGLONG& uCountFile)
  99. {
  100. char sPath[MAX_PATH];
  101. ZeroMemory(sPath, MAX_PATH);
  102. char sFormatFileName[MAX_PATH + 2] = "*";
  103. WIN32_FIND_DATA FindFileData;
  104. HANDLE hFind;
  105. BOOL fFinished = FALSE;
  106. strcpy(sFormatFileName, sFindPath);
  107. if (sFindPath[strlen(sFindPath) - 1] != SPLIT_SLASH)
  108. {
  109. strcat(sFormatFileName, SPLIT_SLASH_STR);
  110. strcat(sFormatFileName, "*");
  111. }
  112. else
  113. {
  114. strcat(sFormatFileName, "*");
  115. }
  116. strcat(sFormatFileName, sFindFileName);
  117. strcat(sFormatFileName, "*");
  118. hFind = FindFirstFile(sFormatFileName, &FindFileData);
  119. if (hFind == INVALID_HANDLE_VALUE)
  120. {
  121. return FALSE;
  122. }
  123. else
  124. {
  125. while (!fFinished)
  126. {
  127. strcpy(sPath, sFindPath);
  128. if (sPath[strlen(sPath) - 1] != SPLIT_SLASH)
  129. {
  130. strcat(sPath, SPLIT_SLASH_STR);
  131. }
  132. strcat(sPath, FindFileData.cFileName);
  133. if (!(FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes))
  134. {
  135. ++uCountFile;
  136. }
  137. if (!FindNextFile(hFind, &FindFileData))
  138. {
  139. if (GetLastError() == ERROR_NO_MORE_FILES)
  140. {
  141. fFinished = TRUE;
  142. }
  143. else
  144. {
  145. break;
  146. }
  147. }
  148. }
  149. FindClose(hFind);
  150. }
  151. return TRUE;
  152. }
  153. static CSimpleStringA DecryptString(LPCTSTR lpszEncrpyted)
  154. {
  155. if (NULL == lpszEncrpyted) {
  156. return CSimpleStringA("");
  157. }
  158. int iEncrypt = 0;
  159. int len = strlen(lpszEncrpyted);
  160. CSimpleStringA csPlainTxt('\0', (len) / 2 + 1);
  161. int iCh = 0;
  162. for (int i = 0; i < len; i += 2) {
  163. sscanf(lpszEncrpyted + i, "%02X", &iCh);
  164. csPlainTxt[i / 2] = (char)(((char)iCh) ^ (128 | (iEncrypt++ & 127)));
  165. }
  166. return CSimpleStringA((LPCTSTR)csPlainTxt);
  167. }
  168. static unsigned long GetFileSize(const char* pfilename)
  169. {
  170. unsigned long usize = 0;
  171. if (NULL == pfilename){
  172. return usize;
  173. }
  174. FILE* pFile = fopen(pfilename, "rb");
  175. if (pFile){
  176. fseek(pFile, 0, SEEK_END);
  177. usize = ftell(pFile);
  178. fclose(pFile);
  179. }
  180. return usize;
  181. }
  182. void SalesRecordServiceSession::Handle_GetOFLVideoRecords( SpReqAnsContext<SalesRecorderSerVice_GetOFLVideoRecords_Req, SalesRecorderSerVice_GetOFLVideoRecords_Ans>::Pointer ctx )
  183. {
  184. DbgToBeidou(ctx->link, __FUNCTION__)();
  185. ctx->Answer(Error_Succeed);
  186. }
  187. void SalesRecordServiceSession::Handle_CheckVideoDiskStatus( SpReqAnsContext<SalesRecorderSerVice_CheckVideoDiskStatus_Req, SalesRecorderSerVice_CheckVideoDiskStatus_Ans>::Pointer ctx )
  188. {
  189. DbgToBeidou(ctx->link, __FUNCTION__)();
  190. int nFreeRatio = 0;
  191. int bSufficient = CheckDiskStatus((LPCTSTR)ctx->Req.DriveLetter,m_pEntity->m_max_disk_percent,&nFreeRatio);
  192. ctx->Ans.IsSufficient = bSufficient;
  193. ctx->Ans.FreeRatio = nFreeRatio;
  194. ctx->Answer(Error_Succeed);
  195. }
  196. void SalesRecordServiceSession::Handle_PlayVideo(SpReqAnsContext<SalesRecorderSerVice_PlayVideo_Req, SalesRecorderSerVice_PlayVideo_Ans>::Pointer ctx)
  197. {
  198. DbgToBeidou(ctx->link, __FUNCTION__)();
  199. ErrorCodeEnum ErrorCode = m_pEntity->HandleDisplayVideo();
  200. ctx->Answer(ErrorCode);
  201. }
  202. void SalesRecordServiceSession::Handle_SaveVideo(SpReqAnsContext<SalesRecorderSerVice_SaveVideo_Req, SalesRecorderSerVice_SaveVideo_Ans>::Pointer ctx)
  203. {
  204. DbgToBeidou(ctx->link, __FUNCTION__)();
  205. ErrorCodeEnum ErrorCode = m_pEntity->HandleSaveVideo();
  206. ctx->Answer(ErrorCode);
  207. }
  208. void SalesRecordServiceSession::Handle_StopRecord(SpReqAnsContext<SalesRecorderSerVice_StopRecord_Req, SalesRecorderSerVice_StopRecord_Ans>::Pointer ctx)
  209. {
  210. DbgToBeidou(ctx->link, __FUNCTION__)();
  211. ErrorCodeEnum ErrorCode = m_pEntity->HandleStopRecord((LPCTSTR)CSimpleStringW2A(ctx->Req.VideoName));
  212. ctx->Answer(ErrorCode);
  213. }
  214. void SalesRecordServiceSession::Handle_SetAudioTransFlag(SpReqAnsContext<SalesRecorderSerVice_SetAudioTransFlag_Req, SalesRecorderSerVice_SetAudioTransFlag_Ans>::Pointer ctx)
  215. {
  216. DbgToBeidou(ctx->link, __FUNCTION__)();
  217. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Audio transmission flag is %s.", ctx->Req.TransFlag ? "true" : "false");
  218. ctx->Answer(Error_Succeed);
  219. }
  220. void SalesRecordServiceSession::Handle_StopShowVideo(SpReqAnsContext<SalesRecorderSerVice_StopShowVideo_Req, SalesRecorderSerVice_StopShowVideo_Ans>::Pointer ctx)
  221. {
  222. DbgToBeidou(ctx->link, __FUNCTION__)();
  223. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Stop Show Video.");
  224. ErrorCodeEnum ErrorCode = m_pEntity->HandleStopShowVideo();
  225. ctx->Answer(ErrorCode);
  226. }
  227. void SalesRecordServiceSession::Handle_PlaySalesRecord(SpReqAnsContext<SalesRecorderSerVice_PlaySalesRecord_Req, SalesRecorderSerVice_PlaySalesRecord_Ans>::Pointer ctx)
  228. {
  229. DbgToBeidou(ctx->link, __FUNCTION__)();
  230. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Stop Show Video.");
  231. ErrorCodeEnum ErrorCode = m_pEntity->HandlePlaySalesRecordVideo(ctx->Req.WndX, ctx->Req.WndY, ctx->Req.WndWidth, ctx->Req.WndHeight);
  232. ctx->Answer(ErrorCode);
  233. }
  234. void SalesRecordServiceSession::Handle_StartRemoteRecord(SpReqAnsContext<SalesRecorderSerVice_StartRemoteRecord_Req, SalesRecorderSerVice_StartRemoteRecord_Ans>::Pointer ctx)
  235. {
  236. DbgToBeidou(ctx->link, __FUNCTION__)();
  237. ErrorCodeEnum ErrorCode = m_pEntity->HandleStartRecord(ctx->Req.VideoName.GetData(), true);
  238. ctx->Answer(ErrorCode);
  239. }
  240. void SalesRecordServiceSession::Handle_DeleteVideo(SpReqAnsContext<SalesRecorderSerVice_DeleteVideo_Req, SalesRecorderSerVice_DeleteVideo_Ans>::Pointer ctx)
  241. {
  242. DbgToBeidou(ctx->link, __FUNCTION__)();
  243. ErrorCodeEnum ErrorCode = m_pEntity->HandleDeleteVideo();
  244. ctx->Answer(ErrorCode);
  245. }
  246. void SalesRecordServiceSession::Handle_AppendWatermark(SpReqAnsContext<SalesRecorderSerVice_AppendWatermark_Req, SalesRecorderSerVice_AppendWatermark_Ans>::Pointer ctx)
  247. {
  248. DbgToBeidou(ctx->link, __FUNCTION__)();
  249. ErrorCodeEnum ErrorCode = m_pEntity->HandleVideoAppendWatermark(CSimpleStringW2A(ctx->Req.VideoName).GetData(), CSimpleStringW2A(ctx->Req.Watermark).GetData());
  250. ctx->Answer(ErrorCode);
  251. }
  252. CServerSessionBase * CSalesRecorderEntity::OnNewSession( const char* pszRemoteEntityName, const char * pszClass )
  253. {
  254. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("%s connected class = %s!", pszRemoteEntityName, pszClass);
  255. return new SalesRecordServiceSession(this);
  256. }
  257. void CSalesRecorderEntity::OnPreStart( CAutoArray<CSimpleStringA> strArgs,CSmartPointer<ITransactionContext> pTransactionContext )
  258. {
  259. ErrorCodeEnum Error = __OnStart(Error_Succeed);
  260. pTransactionContext->SendAnswer(Error);
  261. }
  262. ErrorCodeEnum CSalesRecorderEntity::__OnStart( ErrorCodeEnum preOperationError )
  263. {
  264. //MessageBoxA(0,0,0,0);
  265. m_eDeviceType = eStand2sType;
  266. m_nSysCallType = 0;
  267. m_bNeedRestart = false;
  268. m_eAudioOutQuality = eUltraHD;
  269. m_bIsAudioNsOn = false;
  270. m_iAudioNsPolicy = 2;
  271. m_iAudioChannels = 1;
  272. m_xIdlePre = m_xKernelPre = m_xUserPre = 0;
  273. if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)){
  274. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Set Process(%d) RealTime Priority Success.",GetCurrentProcessId());
  275. }
  276. m_eDeviceType = RvcGetDeviceType();
  277. int iAudioQuality = 3;
  278. int iAudioNsPolicy = 2;
  279. int iIsAudioNsOn = 0;
  280. int iAudioChannels = 1;
  281. int iLogLevel = 1;
  282. int iLowestLevel = 1;
  283. int iRecordType = 0;
  284. m_max_disk_percent = MAX_DISK_PERCENT;
  285. m_audio_samplerate = 8;
  286. CSmartPointer<IConfigInfo> spConfig;
  287. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  288. if (spFunction->OpenConfig(Config_CenterSetting, spConfig) == Error_Succeed) {
  289. spConfig->ReadConfigValueInt("SalesRecorder","MaxDiskPercent",m_max_disk_percent);
  290. spConfig->ReadConfigValueInt("SalesRecorder","AudioSampleRate",m_audio_samplerate);
  291. spConfig->ReadConfigValueInt("SalesRecorder","AudioBitRate",m_audio_out_bitrate);
  292. spConfig->ReadConfigValueInt("SalesRecorder","WholeSection",m_bWholeSection);
  293. spConfig->ReadConfigValueInt("SalesRecorder","ApplyHighQuality",m_bApplyHighQuality);
  294. spConfig->ReadConfigValueInt("SalesRecorder","AudioNsPolicy",iAudioNsPolicy);
  295. spConfig->ReadConfigValueInt("SalesRecorder","IsAudioNsOn",iIsAudioNsOn);
  296. spConfig->ReadConfigValueInt("SalesRecorder","AudioQuality",iAudioQuality);
  297. spConfig->ReadConfigValueInt("SalesRecorder","AudioChannels",iAudioChannels);
  298. spConfig->ReadConfigValueInt("SalesRecorder","LogLevel",iLogLevel);
  299. spConfig->ReadConfigValueInt("SalesRecorder","LowestLevel",iLowestLevel);
  300. spConfig->ReadConfigValueInt("SalesRecorder", "RecordType", iRecordType);
  301. }
  302. if (m_max_disk_percent <= 0 || m_max_disk_percent >= 100) {
  303. m_max_disk_percent = MAX_DISK_PERCENT;
  304. }
  305. if (iLogLevel <= RECORD_LOG_ERROR && iLogLevel > 0){
  306. m_loglevel = (record_loglevel)iLogLevel;
  307. }
  308. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_loglevel:%d", m_loglevel);
  309. if (iLowestLevel <= RECORD_LOG_ERROR && iLowestLevel > 0){
  310. m_lowestlevel = (record_loglevel)iLowestLevel;
  311. }
  312. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_lowestlevel:%d", m_lowestlevel);
  313. if (0 != iRecordType) {
  314. m_eRecordType = eMP4;
  315. }
  316. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("video format is %s.", m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  317. SetRecordAudioQuality(iAudioQuality);
  318. SetRecordAudioNsPolicy(iAudioNsPolicy);
  319. SetRecordAudioChannles(iAudioChannels);
  320. if (0 != iIsAudioNsOn){
  321. m_bIsAudioNsOn = true;
  322. }
  323. if (m_bWholeSection != 0 && m_bWholeSection != 1){
  324. m_bWholeSection = FALSE;
  325. }
  326. if (m_bApplyHighQuality != 0 && m_bApplyHighQuality != 1){
  327. m_bApplyHighQuality = FALSE;
  328. }
  329. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("m_bApplyHighQuality:%d",m_bApplyHighQuality);
  330. if (preOperationError != Error_Succeed) {
  331. return preOperationError;
  332. }
  333. ErrorCodeEnum Error = Error_Succeed;
  334. m_iActiveCamera = CAMERA_TYPE_ENV;
  335. m_iCameraState = 'N';
  336. int i = 0;
  337. m_arrListener.Init(3);
  338. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU, NULL, false);
  339. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_VIDEOAPPENDWATERMARK, NULL, false);
  340. GetFunction()->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_High, Error_IgnoreAll, LOG_EVT_SALESRECORD_ENTITY_EXCEPTION, NULL, false);
  341. GetFunction()->RegistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA,this);
  342. GetFunction()->RegistSysVarEvent(SYSVAR_CAMERASTATE,this);
  343. CSimpleStringA strValue;
  344. GetFunction()->GetSysVar(SYSVAR_CAMERASTATE, strValue);
  345. m_iCameraState = strValue[0];
  346. if (strValue[0] == 'E'){
  347. m_iActiveCamera = CAMERA_TYPE_OPT;
  348. }
  349. else{
  350. m_iActiveCamera = CAMERA_TYPE_ENV;
  351. }
  352. GetFunction()->RegistSysVarEvent(SYSVAR_CALLTYPE, this);
  353. GetFunction()->GetSysVar(SYSVAR_CALLTYPE, strValue);
  354. if (strValue[0] == CALLTYPE_NORMAL) {
  355. m_nSysCallType = 0;
  356. }
  357. else if (strValue[0] == CALLTYPE_MOBILE) {
  358. m_nSysCallType = 1;
  359. }
  360. else {
  361. assert(0);
  362. }
  363. Error = GetFunction()->RegistSysVarEvent("SessionID", this);
  364. if (Error != Error_Succeed)
  365. {
  366. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("register sysvar %s failed!", "SessionID");
  367. }
  368. Error = GetFunction()->GetPath("Temp", m_TempDir);
  369. if (Error != Error_Succeed) {
  370. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record temp path failed!");
  371. }
  372. if (m_TempDir.GetLength() > 0 && m_TempDir[m_TempDir.GetLength()-1] != SPLIT_SLASH) {
  373. m_TempDir += SPLIT_SLASH_STR;
  374. }
  375. Error = GetFunction()->GetPath("UploadVideo", m_RecordSaveDir);
  376. if (Error != Error_Succeed) {
  377. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get global record save path failed!");
  378. }
  379. if (m_RecordSaveDir.GetLength() > 0 && m_RecordSaveDir[m_RecordSaveDir.GetLength()-1] != SPLIT_SLASH) {
  380. m_RecordSaveDir += SPLIT_SLASH_STR;
  381. }
  382. return Error;
  383. }
  384. void CSalesRecorderEntity::OnStarted()
  385. {
  386. LogEvent(Severity_Middle, LOG_EVT_MOD_SALESRECORDER_STARTED_SUCCESS, "sales recorder entity started successfully.");
  387. }
  388. void CSalesRecorderEntity::OnPreClose( EntityCloseCauseEnum eCloseCause,CSmartPointer<ITransactionContext> pTransactionContext )
  389. {
  390. ErrorCodeEnum Error = __OnClose(Error_Succeed);
  391. pTransactionContext->SendAnswer(Error);
  392. }
  393. ErrorCodeEnum CSalesRecorderEntity::__OnClose( ErrorCodeEnum preOperationError )
  394. {
  395. if (preOperationError != Error_Succeed) {
  396. return preOperationError;
  397. }
  398. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  399. for (int i = 0; i < m_arrListener.GetCount(); ++i) {
  400. spFunction->UnsubscribeLog(m_arrListener[i]);
  401. }
  402. GetFunction()->UnregistSysVarEvent(SYSVAR_ACTIVETRACKINGCAMERA);
  403. GetFunction()->UnregistSysVarEvent(SYSVAR_CAMERASTATE);
  404. StopRecord();
  405. return Error_Succeed;
  406. }
  407. void CSalesRecorderEntity::OnSelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  408. {
  409. if (Test_ShakeHand == eTestType)
  410. {
  411. if (m_bNeedRestart){
  412. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("[OnSelfTest] entity need restart now.");
  413. pTransactionContext->SendAnswer(Error_Unexpect);
  414. }
  415. else{
  416. pTransactionContext->SendAnswer(Error_Succeed);
  417. }
  418. }
  419. }
  420. void CSalesRecorderEntity::Debug(record_loglevel elevel, const char *fmt, ...)
  421. {
  422. record_loglevel entitylevel = (m_lowestlevel > m_loglevel) ? m_lowestlevel : m_loglevel;
  423. if (entitylevel <= elevel) {
  424. va_list arg;
  425. va_start(arg, fmt);
  426. int n = _vscprintf(fmt, arg);
  427. if (n >= 512) {
  428. char* buf = (char*)malloc((size_t)(n + 1));
  429. _vsnprintf(buf, n + 1, fmt, arg);
  430. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  431. free(buf);
  432. }
  433. else{
  434. char strlog[512] = {0};
  435. _vsnprintf(strlog, 512, fmt, arg);
  436. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  437. }
  438. va_end(arg);
  439. }
  440. }
  441. void CSalesRecorderEntity::vDebug(record_loglevel elevel, const char* str, va_list list)
  442. {
  443. if (RECORD_LOG_INFO <= elevel) {
  444. int n = _vscprintf(str, list);
  445. if (n >= 512) {
  446. char* buf = (char*)malloc((size_t)(n + 1));
  447. _vsnprintf(buf, n + 1, str, list);
  448. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  449. free(buf);
  450. }
  451. else {
  452. char strlog[512] = { 0 };
  453. _vsnprintf(strlog, 512, str, list);
  454. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  455. }
  456. }
  457. }
  458. int CSalesRecorderEntity::GetActiveCamera()
  459. {
  460. return m_iActiveCamera;
  461. }
  462. int CSalesRecorderEntity::GetCameraState()
  463. {
  464. //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get active camera = %d", m_iCameraState);
  465. return m_iCameraState;
  466. }
  467. void CSalesRecorderEntity::OnRecordFailed(eRvcRecordFailedCase eCase, const char *pszMessage, bool bRecordDevFault)
  468. {
  469. double fCpuUsage = GetSystemCpuUsage();
  470. if (fCpuUsage > 50.0){
  471. LogWarn(Severity_Low, Error_Debug, LOG_EVT_UI_RECORDFAILED_FOR_HIGHCPU, "more than 50 percent.");
  472. }
  473. if (eCase < eDefault && eCase >= 0){
  474. LogEvent(Severity_Middle, LOG_EVT_UI_RECORDFAILED, record_failed_case_table[eCase]);
  475. }
  476. m_loglevel = RECORD_LOG_INFO;
  477. char strmsg[MAX_PATH] = {0};
  478. _snprintf(strmsg, MAX_PATH, "{%s} current memory usage is %d, and cpu usage is %f.",pszMessage ? pszMessage : " ", GetSystemMemoryUsage(), fCpuUsage);
  479. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_SALESRECORD_FAILED, strmsg);
  480. if (eBeginFailed == eCase){
  481. m_bNeedRestart = true;
  482. RealSelfCheck();
  483. }
  484. }
  485. void CSalesRecorderEntity::OnRecordEntityExcption()
  486. {
  487. LogEvent(Severity_High,LOG_EVT_SALESRECORD_ENTITY_EXCEPTION,"现场销售双录出现异常,请稍候重录,系统正在恢复中,预计60秒!");
  488. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_ENTITY_EXCEPTION, "sales record entity exception!");
  489. }
  490. void CSalesRecorderEntity::OnRecordFinished()
  491. {
  492. LogEvent(Severity_High, LOG_EVT_SALESRECORD_FINISHED, "现场销售双录已完成.");
  493. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_FINISHED, "现场销售双录已完成.");
  494. }
  495. void CSalesRecorderEntity::WmpDebug( const char *fmt, ... )
  496. {
  497. va_list arg;
  498. va_start(arg, fmt);
  499. int n = _vscprintf(fmt, arg);
  500. if (n >= 512) {
  501. char* buf = (char*)malloc((size_t)(n + 1));
  502. _vsnprintf(buf, n + 1, fmt, arg);
  503. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", buf);
  504. free(buf);
  505. }
  506. else {
  507. char strlog[512] = { 0 };
  508. _vsnprintf(strlog, 512, fmt, arg);
  509. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strlog);
  510. }
  511. va_end(arg);
  512. }
  513. // 定时任务:扫描是否有待提交的离线双录记录 add by ly @2018/02/08
  514. void CSalesRecorderEntity::OnTimeout( DWORD dwTimerID )
  515. {
  516. }
  517. void CSalesRecorderEntity::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
  518. {
  519. if (_stricmp(pszKey, SYSVAR_CAMERASTATE) == 0)
  520. {
  521. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("camera state from : %c to %c", pszOldValue[0], pszValue[0]);
  522. m_iCameraState = pszValue[0];
  523. if (pszValue[0] == 'E')
  524. {
  525. m_iActiveCamera = CAMERA_TYPE_OPT;
  526. }
  527. else
  528. {
  529. m_iActiveCamera = CAMERA_TYPE_ENV;
  530. }
  531. }
  532. else if (_stricmp(pszKey, SYSVAR_ACTIVETRACKINGCAMERA) == 0)
  533. {
  534. if (m_iCameraState == 'N')
  535. {
  536. if (pszValue[0] == 'E')
  537. {
  538. m_iActiveCamera = CAMERA_TYPE_ENV;
  539. }
  540. else if (pszValue[0] == 'O')
  541. {
  542. m_iActiveCamera = CAMERA_TYPE_OPT;
  543. }
  544. }
  545. }
  546. else if (_stricmp(pszKey, SYSVAR_CALLTYPE) == 0)
  547. {
  548. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("sys calltype from: %c to %c", pszOldValue[0], pszValue[0]);
  549. if(pszValue[0] == CALLTYPE_NORMAL)
  550. {
  551. m_nSysCallType = 0;
  552. }
  553. else if(pszValue[0] == CALLTYPE_MOBILE)
  554. {
  555. m_nSysCallType = 1;
  556. }
  557. else
  558. {
  559. m_nSysCallType = -1;
  560. }
  561. }
  562. }
  563. void CSalesRecorderEntity::OnLog( const CAutoArray<CUUID> &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray<DWORD> &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext &pLinkInfo)
  564. {
  565. // 响应客户经理销售录像相关的事件
  566. switch (dwUserCode)
  567. {
  568. case LOG_EVT_UI_RETURNMENU:
  569. HandleReturnMenu();
  570. break;
  571. case LOG_EVT_SALESRECORD_ENTITY_EXCEPTION:
  572. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("handle sales record entity exception, and message is %s.", pszMessage);
  573. HandleSalesRecordEntityException(pszMessage);
  574. break;
  575. default:
  576. break;
  577. }
  578. }
  579. void CSalesRecorderEntity::StartPhone2PadRecord(const int fps, const char* wmvfilename, int videoquality, int audioOutBitRate, SubtitleParam* subtitleParam, BOOL bWholeSection, BOOL bSessionManage, eRvcRecordType eRecordType)
  580. {
  581. bool bRet = false;
  582. if ((ePadtype == m_eDeviceType) || (eMobilePadType == m_eDeviceType) || (eDesk1SType == m_eDeviceType) || (eDesk2SIntegratedType == m_eDeviceType))
  583. {
  584. //在线双录,录像统一使用前置摄像头, pad 版增加远端视频队列
  585. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("m_pRecorder local video is REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE.");
  586. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  587. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  588. }
  589. else if (eDesk2SType == m_eDeviceType)
  590. {
  591. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_SALES_EWS_SHM_RTP_QUEUE,
  592. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  593. }
  594. else
  595. {
  596. // == 2
  597. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  598. REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  599. }
  600. Rvc_RecordAudioParam_t tAudioParams;
  601. tAudioParams.eRecordType = ePhone2Pad;
  602. tAudioParams.eOutPutType = m_eAudioOutQuality;
  603. tAudioParams.bIsNsOn = m_bIsAudioNsOn;
  604. tAudioParams.iNsPolicy = m_iAudioNsPolicy;
  605. tAudioParams.iAudioOutBitRate = 8;
  606. tAudioParams.bIsTransOn = false;
  607. tAudioParams.iAudioChannels = 1;
  608. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("init lib wmv record success! and record type is %s and output audio quality is %s, audio noise suppression flag is %s. noise suppression policy is %d, video format is %s.", record_type_table[eRecordType], audio_quality_type_table[m_eAudioOutQuality], tAudioParams.bIsNsOn ? "true" : "false", tAudioParams.iNsPolicy, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  609. if (m_pRecorder->StartVideoRecord(fps, videoquality, m_eRecordType, &tAudioParams, subtitleParam, bWholeSection, FALSE, (LPCSTR)m_TempDir,
  610. m_TempDir.GetLength(), wmvfilename, strlen(wmvfilename)))
  611. {
  612. m_bStarted = TRUE;
  613. }
  614. }
  615. bool CSalesRecorderEntity::GetStandardQualityOnSiteSalesRecorder(const eRvcRecordType eRecordType)
  616. {
  617. bool bRet = false;
  618. if ((ePadtype == m_eDeviceType) || (eMobilePadType == m_eDeviceType) || eDesk2SType == m_eDeviceType)
  619. {
  620. if (ePad2Agent != eRecordType) {
  621. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  622. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  623. }
  624. else{
  625. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  626. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  627. }
  628. }
  629. else if(eDesk1SType == m_eDeviceType || eDesk2SIntegratedType == m_eDeviceType)
  630. {
  631. if (ePad2Agent != eRecordType) {
  632. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  633. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  634. }
  635. else {
  636. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  637. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  638. }
  639. }
  640. else
  641. {
  642. if (eStand2Agent != eRecordType){
  643. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  644. REC_COMMON_VIDEO_OPT_SHM_RTP_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  645. }
  646. else{
  647. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  648. REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  649. }
  650. }
  651. return bRet;
  652. }
  653. bool CSalesRecorderEntity::GetHighQualityOnSiteSalesRecorder(const eRvcRecordType eRecordType)
  654. {
  655. bool bRet = false;
  656. if (ePadtype == m_eDeviceType || eMobilePadType == m_eDeviceType || eDesk2SType == m_eDeviceType)
  657. {
  658. if (ePad2Agent == eRecordType) {
  659. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  660. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  661. }
  662. else {
  663. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  664. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  665. }
  666. }
  667. else if (eDesk1SType == m_eDeviceType || eDesk2SIntegratedType == m_eDeviceType)
  668. {
  669. if (ePad2Agent == eRecordType) {
  670. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_RTP_QUEUE,
  671. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  672. }
  673. else {
  674. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SALESOL_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  675. NULL, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  676. }
  677. }
  678. else
  679. {
  680. if (eStand2Agent != eRecordType){
  681. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  682. REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE);
  683. }
  684. else{
  685. m_pRecorder = new Clibvideorecord(&bRet, this, REC_COMMON_AUDIO_SHM_QUEUE, REC_COMMON_VIDEO_ENV_SHM_SNAPSHOT_QUEUE,
  686. REC_COMMON_VIDEO_OPT_SHM_SNAPSHOT_QUEUE, REC_COMMON_AUDIO_SALES_SHM_QUEUE, REC_COMMON_VIDEO_REMOTE_SHM_RTP_QUEUE, REC_COMMON_REMOTEAUDIO_SHM_QUEUE);
  687. }
  688. }
  689. return bRet;
  690. }
  691. void CSalesRecorderEntity::StartOnSiteSalesRecord(const int fps, const char* wmvfilename, int videoquality, int audioOutBitRate, SubtitleParam* subtitleParam, BOOL bWholeSection, BOOL bSessionManage, eRvcRecordType eRecordType)
  692. {
  693. bool bRet = false;
  694. if (m_bApplyHighQuality)
  695. {
  696. bRet = GetHighQualityOnSiteSalesRecorder(eRecordType);
  697. }
  698. else
  699. {
  700. bRet = GetStandardQualityOnSiteSalesRecorder(eRecordType);
  701. }
  702. if (false == bRet){
  703. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get onsite sales recorder failed.");
  704. return;
  705. }
  706. Rvc_RecordAudioParam_t tAudioParams;
  707. tAudioParams.eRecordType = eRecordType;
  708. tAudioParams.eOutPutType = m_eAudioOutQuality;
  709. tAudioParams.bIsNsOn = m_bIsAudioNsOn;
  710. tAudioParams.iNsPolicy = m_iAudioNsPolicy;
  711. tAudioParams.iAudioOutBitRate = audioOutBitRate;
  712. tAudioParams.bIsTransOn = false;
  713. tAudioParams.iAudioChannels = m_iAudioChannels;
  714. if (eStand2Agent == eRecordType || ePad2Agent == eRecordType) {
  715. tAudioParams.eOutPutType = eLowDefinition;
  716. tAudioParams.bIsNsOn = false;
  717. }
  718. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("init record lib success! and record type is %s and output audio quality is %s, audio noise suppression flag is %s. noise suppression policy is %d, video format is %s.", record_type_table[eRecordType], audio_quality_type_table[m_eAudioOutQuality], tAudioParams.bIsNsOn ? "true" : "false", tAudioParams.iNsPolicy, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  719. if (m_pRecorder->StartVideoRecord(fps, videoquality, m_eRecordType, &tAudioParams, subtitleParam, bWholeSection, FALSE, (LPCSTR)m_TempDir,
  720. m_TempDir.GetLength(), wmvfilename, strlen(wmvfilename)))
  721. {
  722. m_bStarted = TRUE;
  723. }
  724. else {
  725. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Start WmvRecord failed!");
  726. }
  727. }
  728. void CSalesRecorderEntity::StartRecord(const char *wmvfilename, int videoquality, int audioOutBitRate, SubtitleParam *subtitleParam /* = NULL */, BOOL bWholeSection /* = FALSE */, BOOL bSessionManage /* = FALSE */, eRvcRecordType eRecordType /* = eSingleSide */)
  729. {
  730. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("wmvfilename = %s", wmvfilename);
  731. //Dbg("strPath = %s", (LPCSTR)m_TempDir);
  732. int fps = 5;
  733. //是否需要录制双向视频和音频
  734. if(m_nSysCallType == 1)
  735. {
  736. StartPhone2PadRecord(fps, wmvfilename, videoquality, audioOutBitRate, subtitleParam, bWholeSection, bSessionManage, eRecordType);
  737. }
  738. // 现场销售录音录像
  739. else
  740. {
  741. StartOnSiteSalesRecord(fps, wmvfilename, videoquality, audioOutBitRate, subtitleParam, bWholeSection, bSessionManage, eRecordType);
  742. }
  743. }
  744. ErrorCodeEnum CSalesRecorderEntity::StopRecord()
  745. {
  746. ErrorCodeEnum eCode = Error_Succeed;
  747. if (m_bStarted) {
  748. m_pRecorder->StopVideoRecord();
  749. delete m_pRecorder;
  750. m_pRecorder = NULL;
  751. m_bStarted = FALSE;
  752. }
  753. //else{
  754. // eCode = Error_InvalidState;
  755. //}
  756. return eCode;
  757. }
  758. ErrorCodeEnum CSalesRecorderEntity::ShowVideo( const char *wmvfilename )
  759. {
  760. ErrorCodeEnum ErrorCode = Error_Succeed;
  761. return ErrorCode;
  762. }
  763. ErrorCodeEnum CSalesRecorderEntity::PlaySalesRecordVideo( const char *wmvfilename, int iWndX, int iWndY, int iWndWidth, int iWndHeight)
  764. {
  765. ErrorCodeEnum ErrorCode = Error_Succeed;
  766. return ErrorCode;
  767. }
  768. void CSalesRecorderEntity::DeleteAllVideo( const char *wmvfilename )
  769. {
  770. if(!m_bStarted)
  771. {
  772. CSimpleStringA strPath;
  773. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", strPath);
  774. if (Error == Error_Succeed) {
  775. if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != '\\') {
  776. strPath += "\\";
  777. }
  778. ULONGLONG uVideoCount = 0;
  779. // 删除客户经理录像 edit by ly 2018/03/05
  780. CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.%s", wmvfilename, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  781. BOOL bRet = FindMatchedFile((LPCSTR)strPath, (LPCSTR)strFindFileName, uVideoCount);
  782. if(bRet)
  783. {
  784. strFindFileName = strFindFileName.SubString(0,strFindFileName.GetLength()-5);
  785. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to get sales record count while delete video!");
  786. CSimpleStringA fileName;
  787. BOOL bDeleteSucc = TRUE;
  788. for(int i = 0; i != uVideoCount; ++i)
  789. {
  790. fileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)strPath, (LPCSTR)strFindFileName, i, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  791. bRet = DeleteFile((LPCSTR)fileName);
  792. if(!bRet) {
  793. bDeleteSucc = FALSE;
  794. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while delete %s ", GetLastError(), (LPCSTR)fileName);
  795. }
  796. }
  797. if (bDeleteSucc) {
  798. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to delete sales video!");
  799. }
  800. }
  801. else
  802. {
  803. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sales videos not exist or have been deleted!");
  804. }
  805. // 删除见证录像
  806. uVideoCount = 0;
  807. strFindFileName = CSimpleStringA::Format("W_%s*.%s", wmvfilename, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  808. bRet = FindMatchedFile((LPCSTR)strPath, (LPCSTR)strFindFileName, uVideoCount);
  809. if(bRet)
  810. {
  811. strFindFileName = strFindFileName.SubString(0,strFindFileName.GetLength()-5);
  812. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to get witness record count while delete video!");
  813. CSimpleStringA fileName;
  814. BOOL bDeleteSucc = TRUE;
  815. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("uVideoCount=%d", uVideoCount);
  816. for(int i = 0; i != uVideoCount; ++i)
  817. {
  818. fileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)strPath, (LPCSTR)strFindFileName, i, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  819. bRet = DeleteFile((LPCSTR)fileName);
  820. if(!bRet) {
  821. bDeleteSucc = FALSE;
  822. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while delete %s ", GetLastError(), (LPCSTR)fileName);
  823. }
  824. }
  825. if (bDeleteSucc) {
  826. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to delete witness video!");
  827. }
  828. }
  829. else
  830. {
  831. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("witness videos not exist or have been deleted!");
  832. }
  833. }
  834. }
  835. }
  836. ErrorCodeEnum CSalesRecorderEntity::DeleteVideo( const char *wmvfilename )
  837. {
  838. ErrorCodeEnum ErrorCode = Error_Succeed;
  839. if(!m_bStarted)
  840. {
  841. CSimpleStringA strPath;
  842. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", strPath);
  843. if (Error == Error_Succeed) {
  844. if (strPath.GetLength() > 0 && strPath[strPath.GetLength()-1] != '\\') {
  845. strPath += "\\";
  846. }
  847. CSimpleStringA strFindFileName = CSimpleStringA::Format("%s*.%s", wmvfilename, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  848. ULONGLONG uVideoCount = 0;
  849. BOOL bRet = FindMatchedFile((LPCSTR)strPath, (LPCTSTR)strFindFileName, uVideoCount);
  850. if(bRet)
  851. {
  852. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to get record count while delete video!");
  853. CSimpleStringA fileName;
  854. BOOL bDeleteSucc = TRUE;
  855. for(int i = 0; i != uVideoCount; ++i)
  856. {
  857. fileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)strPath, wmvfilename, i, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  858. bRet = DeleteFile((LPCSTR)fileName);
  859. if(!bRet) {
  860. bDeleteSucc = FALSE;
  861. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while delete %s ", GetLastError(), (LPCSTR)fileName);
  862. }
  863. }
  864. if (bDeleteSucc) {
  865. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to delete videos!");
  866. }
  867. }
  868. else
  869. {
  870. ErrorCode = Error_NotExist;
  871. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[DeleteVideo] videos not exist or have been deleted!");
  872. }
  873. }
  874. }
  875. else {
  876. ErrorCode = Error_NotImpl;
  877. }
  878. return ErrorCode;
  879. }
  880. /*
  881. SaveVideo包含两步,找到录像和移动录像
  882. Error_Succeed 提交上传成功
  883. Error_NotExist not exist
  884. Error_NotImpl 方法执行失败
  885. */
  886. ErrorCodeEnum CSalesRecorderEntity::SaveVideo( const char *wmvfilename)
  887. {
  888. ErrorCodeEnum ErrorCode = Error_Succeed;
  889. if(!m_bStarted)
  890. {
  891. CSimpleStringA sourPath;
  892. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", sourPath);
  893. if(Error == Error_Succeed)
  894. {
  895. if (sourPath.GetLength() > 0 && sourPath[sourPath.GetLength()-1] != '\\') {
  896. sourPath += "\\";
  897. }
  898. ULONGLONG uVideoCount = 0;
  899. CSimpleStringA strFindFileName = CSimpleStringA::Format("S_%s*.%s", wmvfilename, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  900. BOOL bRet = FindMatchedFile((LPCSTR)sourPath, (LPCSTR)strFindFileName, uVideoCount);
  901. if(bRet)
  902. {
  903. strFindFileName = strFindFileName.SubString(0,strFindFileName.GetLength()-5);
  904. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("succeed to get sales record count while save video!");
  905. CSimpleStringA destPath;
  906. Error = GetFunction()->GetPath("UploadVideo", destPath);
  907. if(Error == Error_Succeed)
  908. {
  909. if (destPath.GetLength() > 0 && destPath[destPath.GetLength()-1] != '\\') {
  910. destPath += "\\";
  911. }
  912. CSimpleStringA sourFileName, destFileName;
  913. BOOL bMoveSucc = TRUE;
  914. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("strFindFileName=%s", (LPCSTR)strFindFileName);
  915. for(int i = 0; i != uVideoCount; ++i)
  916. {
  917. sourFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)sourPath, (LPCSTR)strFindFileName, i, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  918. destFileName = CSimpleStringA::Format("%s%s_%d.%s", (LPCSTR)destPath, (LPCSTR)strFindFileName, i, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  919. unsigned long ufilesize = GetFileSize(sourFileName.GetData());
  920. char strtext[MAX_PATH] = {0};
  921. _snprintf(strtext, MAX_PATH, "%s file size is %u byte.", (LPCSTR)sourFileName, ufilesize);
  922. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_FILESIZE, strtext);
  923. bRet = MoveFile((LPCSTR)sourFileName, (LPCSTR)destFileName);
  924. if(!bRet) {
  925. bMoveSucc = FALSE;
  926. ErrorCode = Error_NotImpl;
  927. char strinfo[MAX_PATH] = {0};
  928. _snprintf(strinfo, MAX_PATH, "Error Code %lu while move %s.", GetLastError(), (LPCSTR)sourFileName);
  929. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_SAVED_FAILED, strinfo);
  930. if (183 == GetLastError()){
  931. ErrorCode = Error_InvalidState;
  932. }
  933. }
  934. if (ufilesize > RVC_MIN_FILESIZE){
  935. }
  936. else{
  937. char strmsg[MAX_PATH] = {0};
  938. _snprintf(strmsg, MAX_PATH, "%s file size is %u.", (LPCSTR)sourFileName, ufilesize);
  939. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_INVALID_FILE, strmsg);
  940. }
  941. }
  942. if (bMoveSucc) {
  943. char strmsg[MAX_PATH] = {0};
  944. _snprintf(strmsg, MAX_PATH, "succeed to save sales video, move it from %s to %s.", sourFileName.GetData(), destFileName.GetData());
  945. LogWarn(Severity_Low, Error_Debug, LOG_EVT_RECORD_SAVED_SUCCESS, strmsg);
  946. }
  947. }
  948. }
  949. else{
  950. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_RECORD_SAVED_FAILED, "sales videos not exist or have been deleted");
  951. ErrorCode = Error_NotExist;
  952. }
  953. }
  954. }
  955. else{
  956. ErrorCode = Error_InvalidState;
  957. }
  958. return ErrorCode;
  959. }
  960. CSimpleStringA CSalesRecorderEntity::GetTerminalStage()
  961. {
  962. CSmartPointer<IEntityFunction> Func = GetFunction();
  963. CSimpleStringA strValue = "";
  964. Func->GetSysVar("TerminalStage", strValue);
  965. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("TerminalStage:%s", (LPCTSTR)strValue);
  966. return strValue;
  967. }
  968. ErrorCodeEnum CSalesRecorderEntity::StopRecordVideo()
  969. {
  970. auto rc = Error_Succeed;
  971. auto pUIClient = new UIService_ClientBase(this);
  972. if(pUIClient->Connect() != Error_Succeed)
  973. {
  974. pUIClient->SafeDelete();
  975. pUIClient = NULL;
  976. rc = Error_DevConnFailed;
  977. }
  978. else
  979. {
  980. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("UIClient connected success!");
  981. UIService_StopRecordVideo_Req req;
  982. UIService_StopRecordVideo_Ans ans;
  983. rc = (*pUIClient)(EntityResource::getLink().upgradeLink())->StopRecordVideo(req, ans, 5000);
  984. if(rc != Error_Succeed)
  985. {
  986. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Stop record video failed return 0x%08x", rc);
  987. }
  988. pUIClient->GetFunction()->CloseSession();
  989. pUIClient->SafeDelete();
  990. pUIClient = NULL;
  991. }
  992. return rc;
  993. }
  994. ErrorCodeEnum CSalesRecorderEntity::HandleStartRecord(const char *pszMessage, const bool bRemoteRecord)
  995. {
  996. ErrorCodeEnum Error = Error_Succeed;
  997. eRvcRecordType eRecordType = eSingleSide;
  998. if (NULL == pszMessage){
  999. return Error_Param;
  1000. }
  1001. size_t ulen = strlen(pszMessage);
  1002. char *tmp = new char[ulen+1];
  1003. strncpy_s(tmp, ulen+1, pszMessage, ulen);
  1004. char *result[16] = {0};
  1005. //CStringSplit(tmp, result, "@");
  1006. // 解决中文stringsplit偶现乱码的问题 edit by ly@2018/07/04
  1007. auto arr1 = CSimpleStringA2W(tmp).Split('@');
  1008. auto arr2 = CAutoArray<CSimpleStringA>(arr1.GetCount());
  1009. for (int i = 0; i < arr1.GetCount(); ++i)
  1010. {
  1011. arr2[i] = CSimpleStringW2A(arr1[i]);
  1012. result[i] = const_cast<LPSTR>(arr2[i].GetData());
  1013. }
  1014. sprintf(m_SalesVideoName, "%s", result[4]);//录像名:录像类型标志_录像流水号(如S_C13213EF)
  1015. RecordSubTitle subTitle;
  1016. ZeroMemory(&subTitle,sizeof(RecordSubTitle));
  1017. CSimpleStringA strCardNo = DecryptString(result[5]);
  1018. if (sizeof(subTitle.CustCardNo) > strCardNo.GetLength()){
  1019. strcpy_s(subTitle.CustCardNo, strCardNo.GetData());
  1020. }
  1021. else{
  1022. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Invalid CustCardNo.");
  1023. }
  1024. char *pStr = result[6];
  1025. CSimpleStringW szCustName = CSimpleStringA2W(pStr);
  1026. if (szCustName.GetLength() <= 4) {
  1027. strcpy(subTitle.CustName, pStr);
  1028. }
  1029. else {
  1030. CSimpleStringW aa = szCustName.SubString(0,4);
  1031. sprintf(subTitle.CustName,"%s...",(LPCTSTR)CSimpleStringW2A(aa));
  1032. }
  1033. // 解决产品代码、产品名称过长,画面上显示不下的问题
  1034. // 朝朝赢和招财赢支持双向录像
  1035. pStr = result[7];
  1036. int nProductCodeLen = strlen(pStr);
  1037. if (nProductCodeLen <= 10) {
  1038. strcpy(subTitle.ProductCode, pStr);
  1039. }
  1040. else {
  1041. char aa[5]={0},bb[5]={0};
  1042. strncpy(aa, pStr, 4);
  1043. strncpy(bb, pStr+nProductCodeLen-4, 4);
  1044. sprintf(subTitle.ProductCode,"%s...%s",aa,bb);
  1045. }
  1046. pStr = result[8];
  1047. CSimpleStringW szProductName = CSimpleStringA2W(pStr);
  1048. if (szProductName.GetLength() <= 5) {
  1049. strcpy(subTitle.ProductName, pStr);
  1050. }
  1051. else {
  1052. CSimpleStringW aa = szProductName.SubString(0,3);
  1053. CSimpleStringW bb = szProductName.SubString(szProductName.GetLength()-2,2);
  1054. sprintf(subTitle.ProductName,"%s...%s",(LPCTSTR)CSimpleStringW2A(aa),(LPCTSTR)CSimpleStringW2A(bb));
  1055. }
  1056. if (result[9]) {
  1057. strcpy(subTitle.SapID, result[9]);
  1058. } else {
  1059. subTitle.SapID[0] = '\0';
  1060. }
  1061. if (result[10]) {
  1062. pStr = result[10];
  1063. CSimpleStringW szCustManagerName = CSimpleStringA2W(pStr);
  1064. if (szCustManagerName.GetLength() <= 4) {
  1065. strcpy(subTitle.CustManagerName, result[10]);
  1066. }
  1067. else {
  1068. CSimpleStringW aa = szCustManagerName.SubString(0,4);
  1069. sprintf(subTitle.CustManagerName,"%s...",(LPCTSTR)CSimpleStringW2A(aa));
  1070. }
  1071. } else {
  1072. subTitle.CustManagerName[0] = '\0';
  1073. }
  1074. delete[] tmp;
  1075. tmp = NULL;
  1076. SubtitleParam subtitleParam;
  1077. ZeroMemory(&subtitleParam,sizeof(SubtitleParam));
  1078. subtitleParam.bSubtitle = TRUE;
  1079. subtitleParam.bSubtitleSection = TRUE;
  1080. subtitleParam.topSubtitleData[0] = '\0';
  1081. if (strlen(subTitle.SapID)>0&&strlen(subTitle.CustManagerName)>0){
  1082. sprintf(subtitleParam.bottomSubtitleData1, "%s %s %s", subTitle.CustCardNo, subTitle.CustName, subTitle.ProductCode);
  1083. sprintf(subtitleParam.bottomSubtitleData2, "%s %s %s", subTitle.ProductName, subTitle.SapID, subTitle.CustManagerName);
  1084. }
  1085. else{
  1086. sprintf(subtitleParam.bottomSubtitleData1, "%s %s", subTitle.CustCardNo, subTitle.CustName);
  1087. sprintf(subtitleParam.bottomSubtitleData2, "%s %s", subTitle.ProductCode, subTitle.ProductName);
  1088. }
  1089. int i_audio_out_bitrate = m_audio_out_bitrate;
  1090. if (bRemoteRecord)
  1091. {
  1092. if (m_eDeviceType == eStand2sType) { //如果是大机
  1093. eRecordType = eStand2Agent; //可视柜台大机的双向录像
  1094. }
  1095. else{
  1096. eRecordType = ePad2Agent; //可视柜台pad的双向录像
  1097. }
  1098. if(256 == m_audio_out_bitrate){
  1099. i_audio_out_bitrate = 128;
  1100. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("change remote record audio out bitrate to %d.", i_audio_out_bitrate);
  1101. }
  1102. }
  1103. StartRecord(m_SalesVideoName, 90, i_audio_out_bitrate, &subtitleParam, m_bWholeSection, FALSE, eRecordType);
  1104. char strmsg[MAX_PATH] = {0};
  1105. _snprintf(strmsg, MAX_PATH, "start remote record %s.", m_SalesVideoName);
  1106. LogWarn(Severity_Low, Error_Debug, LOG_EVT_START_REMOTERECORD, strmsg);
  1107. return Error;
  1108. }
  1109. ErrorCodeEnum CSalesRecorderEntity::HandleStopRecord(const char *pszMessage)
  1110. {
  1111. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop record video name is %s!", m_SalesVideoName);
  1112. ErrorCodeEnum ErrorCode = StopRecord();
  1113. return ErrorCode;
  1114. }
  1115. ErrorCodeEnum CSalesRecorderEntity::HandleSetAudioTransmissionFlag(bool bFlag)
  1116. {
  1117. ErrorCodeEnum ErrorCode = Error_Succeed;
  1118. return ErrorCode;
  1119. }
  1120. ErrorCodeEnum CSalesRecorderEntity::HandleDisplayVideo()
  1121. {
  1122. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("play record file name is %s!", m_SalesVideoName);
  1123. ErrorCodeEnum ErrorCode = ShowVideo(m_SalesVideoName);
  1124. return ErrorCode;
  1125. }
  1126. ErrorCodeEnum CSalesRecorderEntity::HandlePlaySalesRecordVideo(int iWndX, int iWndY, int iWndWidth, int iWndHeight)
  1127. {
  1128. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("play sales record video file name is %s!", m_SalesVideoName);
  1129. ErrorCodeEnum ErrorCode = PlaySalesRecordVideo(m_SalesVideoName, iWndX, iWndY, iWndWidth, iWndHeight);
  1130. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("play sales record video return code is 0x%08x.", ErrorCode);
  1131. return ErrorCode;
  1132. }
  1133. ErrorCodeEnum CSalesRecorderEntity::HandleStopShowVideo()
  1134. {
  1135. // 视频播放 libwmpplayer
  1136. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop show video record file name is %s!", m_SalesVideoName);
  1137. ErrorCodeEnum ErrorCode = Error_Succeed;
  1138. return ErrorCode;
  1139. }
  1140. ErrorCodeEnum CSalesRecorderEntity::HandleSaveVideo()
  1141. {
  1142. ErrorCodeEnum ErrorCode = Error_Succeed;
  1143. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Save Record Name is %s.", m_SalesVideoName);
  1144. // 将视频从tmp移动到uploadvideo
  1145. ErrorCode = SaveVideo(m_SalesVideoName+2);
  1146. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1147. return ErrorCode;
  1148. }
  1149. ErrorCodeEnum CSalesRecorderEntity::HandleDeleteVideo()
  1150. {
  1151. ErrorCodeEnum ErrorCode = Error_Succeed;
  1152. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Delete Record Name is %s.", m_SalesVideoName);
  1153. // 删除tmp中的视频
  1154. ErrorCode = DeleteVideo(m_SalesVideoName);
  1155. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1156. return ErrorCode;
  1157. }
  1158. void CSalesRecorderEntity::HandleReturnMenu()
  1159. {
  1160. CSimpleStringA strValue;
  1161. GetFunction()->GetSysVar("DesktopType", strValue);
  1162. if (strValue != CSimpleStringA("U"))
  1163. {
  1164. if (m_bStarted) // 如果正在进行客户经理录像
  1165. {
  1166. // 停止录像
  1167. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop record and return menu!");
  1168. StopRecord();
  1169. }
  1170. // 删除tmp中的视频
  1171. if (strlen(m_SalesVideoName) > 0)
  1172. {
  1173. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("delete sales record!");
  1174. DeleteAllVideo(m_SalesVideoName+2);
  1175. }
  1176. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1177. }
  1178. }
  1179. void CSalesRecorderEntity::HandleUkeyPullout()
  1180. {
  1181. if (m_SalesVideoName && strstr(m_SalesVideoName, "OFL"))
  1182. {
  1183. if (m_bStarted) // 如果正在进行客户经理录像
  1184. {
  1185. // 停止录像
  1186. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop record and return menu!");
  1187. StopRecord();
  1188. }
  1189. // 删除录像记录临时文件
  1190. CSimpleStringA cfn = CSimpleStringA::Format("%s%s.txt", (LPCTSTR)m_TempDir, m_SalesVideoName);
  1191. DeleteFile(cfn);
  1192. // 删除tmp中的视频
  1193. if (strlen(m_SalesVideoName) > 0)
  1194. {
  1195. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("delete sales record!");
  1196. DeleteAllVideo(m_SalesVideoName+4);
  1197. }
  1198. ZeroMemory(m_SalesVideoName,sizeof(m_SalesVideoName));
  1199. StopRecordVideo();
  1200. }
  1201. }
  1202. ErrorCodeEnum CSalesRecorderEntity::HandleVideoAppendWatermark(const char* pszVideoName, const char* pszWaterMark)
  1203. {
  1204. ErrorCodeEnum Error = Error_Failed;
  1205. if (NULL == pszWaterMark){
  1206. return Error_Param;
  1207. }
  1208. if (m_bStarted && (NULL != m_pRecorder)) {
  1209. if (m_pRecorder->SetRightVideoWaterMark(pszWaterMark)) {
  1210. Error = Error_Succeed;
  1211. }
  1212. }
  1213. return Error;
  1214. }
  1215. ErrorCodeEnum CSalesRecorderEntity::HandleSalesRecordEntityException(const char* pszMessage)
  1216. {
  1217. // 通知到业务中台
  1218. SalesRecordException evt;
  1219. evt.failedmsg = CSimpleStringA2W(pszMessage==NULL?"现场销售双录过程出现异常!":pszMessage);
  1220. SpSendBroadcast(GetFunction(), SP_MSG_OF(SalesRecordException), SP_MSG_SIG_OF(SalesRecordException), evt);
  1221. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("[dbg] SalesRecord entity exception broadcast sent!");
  1222. //停止录像
  1223. StopRecord();
  1224. m_bNeedRestart = true;
  1225. //重启实体
  1226. RealSelfCheck();
  1227. return Error_Succeed;
  1228. }
  1229. ErrorCodeEnum CSalesRecorderEntity::RealSelfCheck()
  1230. {
  1231. ErrorCodeEnum Error = Error_Succeed;
  1232. SelfChekerClient* pSelfcheckClient = new SelfChekerClient(this);
  1233. Error = pSelfcheckClient->Connect();
  1234. if (Error != Error_Succeed)
  1235. {
  1236. pSelfcheckClient->SafeDelete();
  1237. pSelfcheckClient = NULL;
  1238. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("SelfcheckClient connect fail!");
  1239. }
  1240. else
  1241. {
  1242. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SelfcheckClient connect success!");
  1243. }
  1244. if (pSelfcheckClient)
  1245. {
  1246. SelfCheckerService_RealCheck_Req req;
  1247. req.name = GetEntityName();
  1248. SelfCheckerService_RealCheck_Ans ans;
  1249. DWORD Timeout = 500;
  1250. Error = pSelfcheckClient->RealCheck(req,ans,Timeout);
  1251. if (Error!=Error_Succeed)
  1252. {
  1253. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("RealSelfcheck fail!");
  1254. }
  1255. else
  1256. {
  1257. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("RealSelfcheck success!");
  1258. }
  1259. }
  1260. LogWarn(Severity_Middle, Error_Debug, LOG_EVT_ENTITY_RESTART, "sales record entity self restart.");
  1261. return Error;
  1262. }
  1263. bool IsMatchedVideo(WIN32_FIND_DATA fileData)
  1264. {
  1265. bool bRet = false;
  1266. if ('S' == fileData.cFileName[0] || 'W' == fileData.cFileName[0]){
  1267. SYSTEMTIME sysTime;
  1268. FileTimeToSystemTime(&fileData.ftCreationTime, &sysTime);
  1269. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("File %s create data info is %d %d %d.", fileData.cFileName, sysTime.wYear, sysTime.wMonth, sysTime.wDay);
  1270. if ((2020 == sysTime.wYear) && (sysTime.wMonth == 1)){
  1271. if (sysTime.wDay >= 3 && sysTime.wDay <= 10){
  1272. bRet = true;
  1273. }
  1274. }
  1275. }
  1276. return bRet;
  1277. }
  1278. void CSalesRecorderEntity::UploadTempPathVideos()
  1279. {
  1280. CSimpleStringA sourPath;
  1281. CSimpleStringA destPath;
  1282. ErrorCodeEnum Error = GetFunction()->GetPath("Temp", sourPath);
  1283. Error = GetFunction()->GetPath("UploadVideo", destPath);
  1284. if (sourPath.GetLength() > 0 && sourPath[sourPath.GetLength()-1] != SPLIT_SLASH) {
  1285. sourPath += SPLIT_SLASH_STR;
  1286. }
  1287. if (destPath.GetLength() > 0 && destPath[destPath.GetLength()-1] != SPLIT_SLASH) {
  1288. destPath += SPLIT_SLASH_STR;
  1289. }
  1290. if(Error == Error_Succeed)
  1291. {
  1292. char srcFilePath[MAX_PATH]={0};
  1293. WIN32_FIND_DATA FindFileData;
  1294. HANDLE hFind;
  1295. BOOL fFinished = FALSE;
  1296. sprintf_s(srcFilePath, MAX_PATH, "%s*.%s", sourPath, m_eRecordType == eMP4 ? RECORD_MP4_SUFFIX : RECORD_WMV_SUFFIX);
  1297. hFind = FindFirstFile(srcFilePath, &FindFileData);
  1298. if (INVALID_HANDLE_VALUE != hFind)
  1299. {
  1300. while (!fFinished)
  1301. {
  1302. if (FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes)
  1303. {
  1304. continue;
  1305. }
  1306. if (IsMatchedVideo(FindFileData)){
  1307. CSimpleStringA sourFileName = CSimpleStringA::Format("%s%s", (LPCSTR)sourPath, FindFileData.cFileName);
  1308. CSimpleStringA destFileName = CSimpleStringA::Format("%sBAK_%s", (LPCSTR)destPath, FindFileData.cFileName);
  1309. if(!MoveFile((LPCSTR)sourFileName, (LPCSTR)destFileName)) {
  1310. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Error Code %lu while move %s ", GetLastError(), (LPCSTR)sourFileName);
  1311. }else{
  1312. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Move File %s success.", (LPCSTR)sourFileName);
  1313. }
  1314. }
  1315. else{
  1316. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("File (%s) is not matched.", FindFileData.cFileName);
  1317. }
  1318. if (!FindNextFile(hFind, &FindFileData))
  1319. {
  1320. if (GetLastError() == ERROR_NO_MORE_FILES)
  1321. {
  1322. fFinished = TRUE;
  1323. }
  1324. else
  1325. {
  1326. break;
  1327. }
  1328. }
  1329. }
  1330. FindClose(hFind);
  1331. }
  1332. }
  1333. }
  1334. int CSalesRecorderEntity::GetSystemMemoryUsage()
  1335. {
  1336. // Use to convert bytes to KB
  1337. #define DIV 1024
  1338. MEMORYSTATUSEX statex;
  1339. statex.dwLength = sizeof (statex);
  1340. GlobalMemoryStatusEx (&statex);
  1341. return statex.dwMemoryLoad;
  1342. }
  1343. double CSalesRecorderEntity::GetSystemCpuUsage()
  1344. {
  1345. double ratio = 0;
  1346. #define _WIN32_WINNT 0x0601
  1347. FILETIME idleTime,kernelTime,userTime;
  1348. BOOL ret = GetSystemTimes(&idleTime,&kernelTime,&userTime);
  1349. if (ret == 0)
  1350. {
  1351. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("GetSystemCPUStatus.GetSystemTimes failed(%d).",GetLastError());
  1352. return 80.0;
  1353. }
  1354. __int64 xIdle,xKernel,xUser;
  1355. xIdle = idleTime.dwHighDateTime;
  1356. xIdle <<= 32;
  1357. xIdle |= idleTime.dwLowDateTime;
  1358. xKernel = kernelTime.dwHighDateTime;
  1359. xKernel <<= 32;
  1360. xKernel |= kernelTime.dwLowDateTime;
  1361. xUser = userTime.dwHighDateTime;
  1362. xUser <<= 32;
  1363. xUser |= userTime.dwLowDateTime;
  1364. if (m_xIdlePre != 0)
  1365. {
  1366. __int64 xI,xK,xU;
  1367. xI = xIdle - m_xIdlePre;
  1368. xK = xKernel - m_xKernelPre;
  1369. xU = xUser - m_xUserPre;
  1370. if ((xK +xU) != 0)
  1371. ratio = (xK - xI + xU) * 100 / (xK + xU);
  1372. }
  1373. m_xIdlePre = xIdle;
  1374. m_xKernelPre = xKernel;
  1375. m_xUserPre = xUser;
  1376. return ratio;
  1377. }
  1378. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioQuality(int iAudioQuality)
  1379. {
  1380. ErrorCodeEnum eRet = Error_Succeed;
  1381. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("iAudioQuality == %d.", iAudioQuality);
  1382. switch (iAudioQuality)
  1383. {
  1384. case 1:
  1385. m_eAudioOutQuality = eLowDefinition;
  1386. break;
  1387. case 2:
  1388. m_eAudioOutQuality = eStandardDefinition;
  1389. break;
  1390. case 3:
  1391. m_eAudioOutQuality = eHighDefinition;
  1392. break;
  1393. case 4:
  1394. m_eAudioOutQuality = eUltraHD;
  1395. break;
  1396. default:
  1397. m_eAudioOutQuality = eUltraHD;
  1398. break;
  1399. }
  1400. return eRet;
  1401. }
  1402. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioNsPolicy(int iNsPolicy)
  1403. {
  1404. ErrorCodeEnum eRet = Error_Succeed;
  1405. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("iNsPolicy == %d.", iNsPolicy);
  1406. if (1 == iNsPolicy || 3 == iNsPolicy){
  1407. m_iAudioNsPolicy = iNsPolicy;
  1408. }
  1409. else{
  1410. m_iAudioNsPolicy = 2;
  1411. }
  1412. return eRet;
  1413. }
  1414. ErrorCodeEnum CSalesRecorderEntity::SetRecordAudioChannles(int iAudioChannles)
  1415. {
  1416. ErrorCodeEnum eRet = Error_Succeed;
  1417. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Get iAudioChannles == %d.", iAudioChannles);
  1418. m_iAudioChannels = 2;
  1419. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Set AudioChannles == %d.", m_iAudioChannels);
  1420. return eRet;
  1421. }
  1422. DeviceTypeEnum CSalesRecorderEntity::RvcGetDeviceType()
  1423. {
  1424. DeviceTypeEnum eType = eStand2sType;
  1425. CSmartPointer<IEntityFunction> spFunction = GetFunction();
  1426. CSystemStaticInfo stStaticinfo;
  1427. spFunction->GetSystemStaticInfo(stStaticinfo);
  1428. m_terminalNo = stStaticinfo.strTerminalID;
  1429. if (stricmp(stStaticinfo.strMachineType, "RVC.PAD") == 0) {
  1430. if (stricmp(stStaticinfo.strSite, "CMB.FLB") == 0) {
  1431. eType = eMobilePadType;
  1432. }
  1433. else {
  1434. eType = ePadtype;
  1435. }
  1436. }
  1437. else if (stricmp(stStaticinfo.strMachineType, "RVC.Desk2S") == 0) {
  1438. eType = eDesk2SType;
  1439. WORD nMajor = stStaticinfo.MachineVersion.GetMajor();
  1440. WORD nMinor = stStaticinfo.MachineVersion.GetMinor();
  1441. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("MachineVersion is %d.%d", nMajor, nMinor);
  1442. if (2 == nMajor) {
  1443. eType = eDesk2SIntegratedType;
  1444. }
  1445. }
  1446. else if (stricmp(stStaticinfo.strMachineType, "RPM.Stand1S") == 0) {
  1447. eType = eRpm1sType;
  1448. }
  1449. else if (stricmp(stStaticinfo.strMachineType, "RVC.Desk1S") == 0) {
  1450. eType = eDesk1SType;
  1451. }
  1452. else if (stricmp(stStaticinfo.strMachineType, "RVC.CardStore") == 0 || stricmp(stStaticinfo.strMachineType, "RVC.CardPrinter") == 0) {
  1453. eType = eCardStore;
  1454. }
  1455. else {
  1456. eType = eStand2sType;
  1457. }
  1458. if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) {
  1459. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]);
  1460. }
  1461. return eType;
  1462. }
  1463. SelfChekerClient::SelfChekerClient( CSalesRecorderEntity *pEntity ) : SelfCheckerService_ClientBase(pEntity)
  1464. {
  1465. }
  1466. SP_BEGIN_ENTITY_MAP()
  1467. SP_ENTITY(CSalesRecorderEntity)
  1468. SP_END_ENTITY_MAP()