diff --git a/CPF_Cef/Common/ChunkedUpload.cs b/CPF_Cef/Common/ChunkedUpload.cs index e510f1a..3534b6d 100644 --- a/CPF_Cef/Common/ChunkedUpload.cs +++ b/CPF_Cef/Common/ChunkedUpload.cs @@ -143,7 +143,7 @@ namespace AksWebBrowser.Common string[] lines = File.ReadAllLines(tempFile); foreach (string line in lines) { - base64= base64+line; + base64 = base64 + line; } File.Delete(tempFile); //读取签字版主动回复数据 @@ -180,5 +180,156 @@ namespace AksWebBrowser.Common return "{\"keycode\":\"" + code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"suffix\":\"png\",\"data\":\"" + "签字异常" + "\"}"; } } + + /// + /// 文字转语音、录音与停止 + /// + /// + public async Task PostTTS(string type, int typeCode, string tts_text) + { + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, Parame.signUrl); + var content = new StringContent("{\r\n \"command\": \"tts\",\r\n \"command_num\": 201,\r\n \"data\": {\r\n \"operation\": \"" + type + "\",\r\n \"operation_code\": " + typeCode + ",\r\n \"parameters\": {\r\n \"data_type\": 1,\r\n \" tts_text\": \"" + tts_text + "\"}\r\n }\r\n}", null, "application/json"); + request.Content = content; + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + if (response.StatusCode.ToString() == "OK") + { + // 读取响应内容 + string body = await response.Content.ReadAsStringAsync(); + JObject jo = (JObject)JsonConvert.DeserializeObject(body); + string ret = jo["ret_info"].ToString(); + JObject jo2 = (JObject)JsonConvert.DeserializeObject(ret); + if (jo2["code"].ToString() == "0") + { + //读取data数据 + string details = jo["details"].ToString(); + return details; + } + else + { + //Log.Error("请求签字失败" + jo["message"].ToString()); + return ""; + } + } + else + { + return ""; + } + } + catch (Exception ex) + { + //Log.Error("签字异常:" + ex.Message); + return ""; + } + } + + /// + /// 获取指纹 + /// + /// + public async Task PostFinger(string type, int typeCode) + { + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, Parame.signUrl); + var content = new StringContent("{\r\n command: \"finger\",\r\n command_num: 121,\r\n data: {\r\n operation: \"" + type + "\",\r\n operation_code: " + typeCode + ",\r\n parameters: {\r\n }\r\n }\r\n }", null, "application/json"); + request.Content = content; + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + if (response.StatusCode.ToString() == "OK") + { + // 读取响应内容 + string body = await response.Content.ReadAsStringAsync(); + JObject jo = (JObject)JsonConvert.DeserializeObject(body); + string ret = jo["ret_info"].ToString(); + JObject jo2 = (JObject)JsonConvert.DeserializeObject(ret); + if (jo2["code"].ToString() == "0") + { + //读取指纹 + if (typeCode == 1) + { + //读取data数据 + string data = jo["data"].ToString(); + JObject jo3 = (JObject)JsonConvert.DeserializeObject(data); + //读取parameters数据 + string parameters = jo3["parameters"].ToString(); + JObject jo4 = (JObject)JsonConvert.DeserializeObject(parameters); + //读取签字base64 + string fpr_pic = jo4["fpr_pic"].ToString(); + return fpr_pic; + } + else + { + //关闭指纹 + return "200"; + } + } + else + { + //Log.Error("请求签字失败" + jo["message"].ToString()); + return ""; + } + } + else + { + return ""; + } + } + catch (Exception ex) + { + //Log.Error("签字异常:" + ex.Message); + return ""; + } + } + + /// + /// 录音与停止 + /// + /// + public async Task PostRecord(string type, int typeCode, string path) + { + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, Parame.signUrl); + var content = new StringContent("{\r\n \"command\": \"tts\",\r\n \"command_num\": 201,\r\n \"data\": {\r\n \"operation\": \"" + type + "\",\r\n \"operation_code\": " + typeCode + ",\r\n \"parameters\": {\r\n \"data_type\": 1,\r\n \" tts_text\": \"" + path + "\"}\r\n }\r\n}", null, "application/json"); + request.Content = content; + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + if (response.StatusCode.ToString() == "OK") + { + // 读取响应内容 + string body = await response.Content.ReadAsStringAsync(); + JObject jo = (JObject)JsonConvert.DeserializeObject(body); + string ret = jo["ret_info"].ToString(); + JObject jo2 = (JObject)JsonConvert.DeserializeObject(ret); + if (jo2["code"].ToString() == "0") + { + //读取data数据 + string details = jo["details"].ToString(); + return details; + } + else + { + //Log.Error("请求签字失败" + jo["message"].ToString()); + return ""; + } + } + else + { + return ""; + } + } + catch (Exception ex) + { + //Log.Error("签字异常:" + ex.Message); + return ""; + } + } + } } diff --git a/CPF_Cef/Devices/IDCard.cs b/CPF_Cef/Devices/IDCard.cs index f0234fd..efe74d3 100644 --- a/CPF_Cef/Devices/IDCard.cs +++ b/CPF_Cef/Devices/IDCard.cs @@ -59,28 +59,28 @@ namespace AksWebBrowser.Devices byte[] FileName = new byte[65536]; status = LibClass.ParseIDCardPic(PHMsg, 1024, 3, FileName); - //string time = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); - //string dirpath = Utils.getSystemPaht() + @"/wwwroot/Face"; - //if (!Directory.Exists(dirpath)) - //{ - // Directory.CreateDirectory(dirpath); - //} - //Log.Info(dirpath); - //var tempFile = dirpath + "/" + time + ".bmp"; - ////生成图片 - //LibClass.ParseIDCardPic(PHMsg, 1024, 2, Encoding.Default.GetBytes(tempFile)); - ////文件生成base64 - //byte[] byteArray = File.ReadAllBytes(tempFile); - //string base64String = Convert.ToBase64String(byteArray); - //Log.Info($"{base64String}"); + string time = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + string dirpath = Utils.getSystemPaht() + @"/wwwroot/Face"; + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + Log.Info(dirpath); + var tempFile = dirpath + "/" + time + ".bmp"; + //生成图片 + LibClass.ParseIDCardPic(PHMsg, 1024, 2, Encoding.Default.GetBytes(tempFile)); + //文件生成base64 + byte[] byteArray = File.ReadAllBytes(tempFile); + string base64String = Convert.ToBase64String(byteArray); + Log.Info($"{base64String}"); if (status == 0) { string txt = Encoding.UTF8.GetString(FileName); iDCardModel.ImageBase64 = "data:image/jpg;base64," + txt.Substring(0, (txt.IndexOf("=") + 1)); - ////开启人脸比对 - //LhtCF lht = new LhtCF(); - //string stat = lht.LhtCFFace(code, tempFile); - if (true)//(stat == "0") + //开启人脸比对 + LhtCF lht = new LhtCF(); + string stat = lht.LhtCFFace(code, tempFile); + if (stat == "0") { byte[] sCHMsg = new byte[520]; int itype = 0; diff --git a/CPF_Cef/Devices/LhtCF.cs b/CPF_Cef/Devices/LhtCF.cs index 4d036dd..d0f70a3 100644 --- a/CPF_Cef/Devices/LhtCF.cs +++ b/CPF_Cef/Devices/LhtCF.cs @@ -21,13 +21,7 @@ namespace AksWebBrowser.Devices private delegate int DetectCallBackDelegate(int nResultID); public LhtCF() { - //设置检测回调 - Log.Info("设置检测回调"); - if (pDetectCallBack == null) - { - pDetectCallBack = new libLhtCFs.DetectCallBack(DetectCallBackPro); - libLhtCFs.CF_SetDetectCallBack(pDetectCallBack, IntPtr.Zero); //设置回调 - } + } /// @@ -53,13 +47,36 @@ namespace AksWebBrowser.Devices status = libLhtCFs.CF_StartLiveDetectEx(10000); if (status == 0) { - + string time = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + string dirpath = Utils.getSystemPaht() + @"/wwwroot/Face"; + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + var tempFile = dirpath + "/" + time + ".jpg"; + status = libLhtCFs.CF_GetImage(0, Encoding.Default.GetBytes(tempFile)); + Log.Info("人脸路径:" + tempFile); + byte[] faceA = File.ReadAllBytes(pathfile); + Log.Info("身份证图片路径:" + pathfile); + byte[] faceB = File.ReadAllBytes(tempFile); + int score = 0; + status = libLhtCFs.CF_FaceCompare(faceA, faceB, ref score); + Log.Info("人脸比对:" + status); + Log.Info("人脸值:" + score); + if (score > 60 && status == 0) + { + status = 0; + } + else + { + status = -1; + } } //关闭视频预览窗口 - //Task.Run(() => { libLhtCFs.CF_CloseWindow(0); }); + Task.Run(() => { libLhtCFs.CF_CloseWindow(0); }); } //关闭摄像头 - //Task.Run(() => { libLhtCFs.CF_CloseCamera(); }); + Task.Run(() => { libLhtCFs.CF_CloseCamera(); }); } } } @@ -77,16 +94,8 @@ namespace AksWebBrowser.Devices //检测回调函数 public void DetectCallBackPro(int nResultID, IntPtr lpParam) { - DetectCallBackDelegate myDelegate = (message) => - { - Console.WriteLine($"Hello, {message}!"); - return 0; // 返回值 - }; - - //new DetectCallBackDelegate(DetectCallBackResultf, nResultID); - - //Task.Run(new DetectCallBackDelegate(DetectCallBackResult), nResultID); + Log.Info("检测回调函数:" + nResultID); } public int DetectCallBackResult(int nResultID) { @@ -128,6 +137,7 @@ namespace AksWebBrowser.Devices class libLhtCFs { + public static int FeatureSize = 5120; // 检测回调函数定义 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void DetectCallBack(int nEventId, IntPtr lpContext); @@ -153,7 +163,7 @@ namespace AksWebBrowser.Devices public static extern int CF_GetCameraStatus(int status); //设置检测回调函数 - [DllImport("libLhtCF", EntryPoint = "CF_GetCameraStatus", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] + [DllImport("libLhtCF", CallingConvention = CallingConvention.Cdecl)] public static extern int CF_SetDetectCallBack(DetectCallBack pCB, IntPtr lpContext); //设置彩色摄像头视频流回调 diff --git a/CPF_Cef/MainModel.cs b/CPF_Cef/MainModel.cs index eeae47a..33f7720 100644 --- a/CPF_Cef/MainModel.cs +++ b/CPF_Cef/MainModel.cs @@ -22,6 +22,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Web; +using static System.Net.Mime.MediaTypeNames; namespace AKS.EnterpriseLibrary.WebBrowser { @@ -80,6 +81,7 @@ namespace AKS.EnterpriseLibrary.WebBrowser //停止播放:{ "code":"aks100104","text":"","ispaye":true} case "aks100103": result = payleText(content); + Log.Info("文字语音播报返回:" + result); break; //aks100104 //打开高拍仪并且进行快速扫描文件 {"code":"aks100104"} @@ -89,7 +91,8 @@ namespace AKS.EnterpriseLibrary.WebBrowser //aks100105 //打开签字版 {"code":"aks100105"} case "aks100105": - result =OpenSign(content); + result = OpenSign(content); + Log.Info("签字版数据返回:" + result); break; //aks100112 //关闭签字版 {"code":"aks100112"} @@ -107,6 +110,7 @@ namespace AKS.EnterpriseLibrary.WebBrowser // 结束录音: { "code":"aks100107","url":"http://127.0.0.1/Upload","isopen":false} case "aks100107": result = SoundRecording(content); + Log.Info("开始录音、取消录音、结束录音返回:" + result); break; //aks100108 //根据文件地址在线打印 { "code":"aks100108","url":"http://127.0.0.1/test.doc","ext":"doc"} @@ -129,9 +133,12 @@ namespace AKS.EnterpriseLibrary.WebBrowser case "aks100111": result = openKey(keycode); break; - //aks100113 指纹 {"code":"aks100113"} + //aks100113 + //读取指纹 {"code":"aks100113","isclose":false} + //关闭指纹 {"code":"aks100113","isclose":true} case "aks100113": - result = ReadFingerData(keycode); + result = ReadFingerData(content); + Log.Info("指纹返回:" + result); break; default: result = "{\"keycode\":\"" + "" + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"无效指令\"}"; @@ -364,16 +371,19 @@ namespace AKS.EnterpriseLibrary.WebBrowser } else { - Task.Run(() => + Task.Run(() => { HttpPostResponseByTTS("text_to_wav", 1, text); }); + event2.WaitOne(); + string result = string.Empty; + if (string.IsNullOrEmpty(ttsStr)) { - //形成语音 - tempWav = GenerateWavFromText(text); - //////开始播放 - string command = $"sox {tempWav} -d"; - ShllCommad(command); - //AutoAudio(true, tempWav); - }); - string result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + "开始播放" + "\"}"; + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + "播放失败" + "\"}"; + SubmitLogs(result, "payleText"); + } + else + { + Task.Run(() => { string command = $"sox {ttsStr} -d"; ShllCommad(command); }); + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + "开始播放" + "\"}"; + } SubmitLogs(result, "payleText"); return result; } @@ -470,6 +480,7 @@ namespace AKS.EnterpriseLibrary.WebBrowser Task.Run(() => { HttpPostResponseBySign("open", 1, param.code); }); event2.WaitOne(); string result = sginStr; + Log.Info("签字版数据返回:" + result); SubmitLogs(result, "OpenSign"); return result; } @@ -519,28 +530,63 @@ namespace AKS.EnterpriseLibrary.WebBrowser /// /// /// - public static string ReadFingerData(string code) + public static string ReadFingerData(string content) { + var param = content.ConvertToAnonymousType(new + { + code = default(string), + isclose = default(bool) + + }); try { - if (false)//!isFuncisFuncObject("Finger") + if (!isFuncisFuncObject("ReadFingerData")) { Utils.MessagesBox("指纹设备未授权使用"); - return "{\"keycode\":\"" + code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + "指纹设备未授权使用" + "\"}"; + return "{\"keycode\":\"" + param.code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + "指纹设备未授权使用" + "\"}"; } else { - - string result = Fingerprint.LIVESCANFinger(code); - SubmitLogs(result, "Finger"); - return result; + if (param.isclose) + { + Task.Run(() => { HttpPostResponseByFinger("close", 2); }); + event2.WaitOne(); + string result = string.Empty; + if (string.IsNullOrEmpty(fingerStr)) + { + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + "关闭失败" + "\"}"; + SubmitLogs(result, "ReadFingerData"); + } + else + { + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + "关闭成功" + "\"}"; + } + SubmitLogs(result, "ReadFingerData"); + return result; + } + else { + Task.Run(() => { HttpPostResponseByFinger("open", 1); }); + event2.WaitOne(); + string result = string.Empty; + if (string.IsNullOrEmpty(fingerStr)) + { + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + "读取失败" + "\"}"; + SubmitLogs(result, "ReadFingerData"); + } + else + { + result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"data\":\"" + fingerStr + "\"}"; + } + SubmitLogs(result, "ReadFingerData"); + return result; + } } } catch (Exception ex) { //Log.Error("指纹异常: " + ex.Message + ""); - string result = "{\"keycode\":\"" + code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; - SubmitLogs(result, "Finger"); + string result = "{\"keycode\":\"" + param.code + "\",\"message\":\"Falied\",\"code\":\"400\",\"status\":false,\"data\":\"" + ex.Message + "\"}"; + SubmitLogs(result, "ReadFingerData"); return result; } } @@ -577,7 +623,9 @@ namespace AKS.EnterpriseLibrary.WebBrowser //结束录音上传文件 if (!string.IsNullOrEmpty(url) && !isopen) { - if (StopRecording()) + Task.Run(() => { HttpPostResponseByRecord("stop_record", 3, ""); }); + event2.WaitOne(); + if (string.IsNullOrEmpty(srpath)) { Task.Run(async () => { @@ -587,7 +635,7 @@ namespace AKS.EnterpriseLibrary.WebBrowser Regex re = new Regex(@"(((?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:ww‌​w.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?‌​(?:[\w]*))?)"); MatchCollection mc = re.Matches(url);//获取的是一个数组 string reurl = mc[0].ToString() + "://" + mc[1].ToString() + urlpath; - + string result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + reurl + "\"}"; SubmitLogs(result, "SoundRecording"); return result; @@ -601,7 +649,16 @@ namespace AKS.EnterpriseLibrary.WebBrowser } else if (isopen)//开始录音 { - if (StartRecording()) + string time = DateTime.Now.ToString("yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + string dirpath = Utils.getSystemPaht() + @"/wwwroot/Record"; + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + string path = dirpath + "/" + time + ".wav"; + Task.Run(() => { HttpPostResponseByRecord("start_record", 2, path); }); + event2.WaitOne(); + if (string.IsNullOrEmpty(srpath)) { string result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + "开始录音" + "\"}"; SubmitLogs(result, "SoundRecording"); @@ -616,7 +673,9 @@ namespace AKS.EnterpriseLibrary.WebBrowser } else //取消录音 { - if (StopRecording()) + Task.Run(() => { HttpPostResponseByRecord("stop_record", 3, ""); }); + event2.WaitOne(); + if (string.IsNullOrEmpty(srpath)) { srpath = string.Empty; string result = "{\"keycode\":\"" + param.code + "\",\"message\":\"success\",\"code\":\"200\",\"status\":true,\"suffix\":\"wav\",\"data\":\"" + "取消录音" + "\"}"; @@ -1182,6 +1241,66 @@ namespace AKS.EnterpriseLibrary.WebBrowser } } + private static string ttsStr = string.Empty; + /// + /// 文字转语音 + /// + private static async void HttpPostResponseByTTS(string type, int typeCode, string tts_text) + { + try + { + var httpClient = new HttpClient(); + var uploader = new ChunkedUpload(httpClient); + ttsStr = await uploader.PostTTS(type, typeCode, tts_text); + @event2.Set(); + } + catch (Exception ex) + { + //Log.Error("签字版异常:" + ex.Message); + } + } + + + private static string fingerStr = string.Empty; + /// + /// 指紋 + /// + private static async void HttpPostResponseByFinger(string type, int typeCode) + { + try + { + var httpClient = new HttpClient(); + var uploader = new ChunkedUpload(httpClient); + fingerStr = await uploader.PostFinger(type, typeCode); + @event2.Set(); + } + catch (Exception ex) + { + //Log.Error("签字版异常:" + ex.Message); + } + } + + + private static string RecordStr = string.Empty; + /// + /// 录音与停止 + /// + private static async void HttpPostResponseByRecord(string type, int typeCode, string path) + { + try + { + var httpClient = new HttpClient(); + var uploader = new ChunkedUpload(httpClient); + RecordStr = await uploader.PostRecord(type, typeCode, path); + @event2.Set(); + } + catch (Exception ex) + { + //Log.Error("签字版异常:" + ex.Message); + } + } + + /// /// 初始文件上传 /// @@ -1394,6 +1513,47 @@ namespace AKS.EnterpriseLibrary.WebBrowser return tempFile; } + /// + /// 开源文字转语音 + /// sudo apt-get install espeak + /// + /// + /// + static string GenerateWavFromText2(string text) + { + string time = DateTime.Now.ToString( + "yyyyMMddHHmmss", DateTimeFormatInfo.InvariantInfo); + string dirpath = Utils.getSystemPaht() + @"/wwwroot/WavFile"; + // Log.Info(dirpath); + if (!Directory.Exists(dirpath)) + { + Directory.CreateDirectory(dirpath); + } + var tempFile = dirpath + "/" + time + ".wav"; + try + { + text = text.Replace("(", "").Replace(")", "、"); + ProcessStartInfo startInfo = new ProcessStartInfo + { + FileName = "espeak", + Arguments = $" -vzh -s 150 \"{text}\" -w {tempFile}", // 设置语速为150,输出为WAV文件 + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + }; + using (Process process = Process.Start(startInfo)) + { + process.WaitForExit(); // 等待进程结束 + process.Close(); + process.Dispose(); + } + } + catch (Exception ex) + { + //Log.Error("文字转语音失败:" + ex.Message); + } + return tempFile; + } /// /// 是否已获取收取 ///