WebScoketClient.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System.Net.WebSockets;
  2. using Websocket.Client;
  3. using System.Text.Json;
  4. using NAudio.Wave;
  5. using AliFsmnVadSharp;
  6. using System.Reactive.Linq;
  7. using FunASRWSClient_Online;
  8. namespace WebSocketSpace
  9. {
  10. internal class CWebSocketClient
  11. {
  12. private static int chunk_interval = 10;
  13. private static int[] chunk_size = new int[] { 5, 10, 5 };
  14. private static readonly Uri serverUri = new Uri($"ws://{WSClient_Online.host}:{WSClient_Online.port}"); // 你要连接的WebSocket服务器地址
  15. private static WebsocketClient client = new WebsocketClient(serverUri);
  16. public async Task<string> ClientConnTest()
  17. {
  18. string commstatus = "WebSocket通信连接失败";
  19. try
  20. {
  21. client.Name = "funasr";
  22. client.ReconnectTimeout = null;
  23. client.ReconnectionHappened.Subscribe(info =>
  24. Console.WriteLine($"Reconnection happened, type: {info.Type}, url: {client.Url}"));
  25. client.DisconnectionHappened.Subscribe(info =>
  26. Console.WriteLine($"Disconnection happened, type: {info.Type}"));
  27. client
  28. .MessageReceived
  29. .Where(msg => msg.Text != null)
  30. .Subscribe(msg =>
  31. {
  32. rec_message(msg.Text, client);
  33. });
  34. await client.Start();
  35. if (client.IsRunning)
  36. commstatus = "WebSocket通信连接成功";
  37. }
  38. catch (Exception ex)
  39. {
  40. Console.WriteLine(ex.ToString());
  41. client.Dispose();
  42. }
  43. return commstatus;
  44. }
  45. public bool ClientFirstConnOnline(string asrmode)
  46. {
  47. if (client.IsRunning)
  48. {
  49. string firstbuff = string.Format("{{\"mode\": \"{0}\", \"chunk_size\": [{1},{2},{3}], \"chunk_interval\": {4}, \"wav_name\": \"microphone\", \"is_speaking\": true}}"
  50. , asrmode, chunk_size[0], chunk_size[1], chunk_size[2], chunk_interval);
  51. Task.Run(() => client.Send(firstbuff));
  52. }
  53. else
  54. {
  55. client.Reconnect();
  56. return false;
  57. }
  58. return true;
  59. }
  60. public bool ClientSendAudioFunc(byte[] buff) //实时识别
  61. {
  62. if (client.IsRunning)
  63. {
  64. ////发送音频数据
  65. int CHUNK = WaveCollect.wave_buffer_collectfrequency / 1000 * 60 * chunk_size[1] / chunk_interval;
  66. for (int i = 0; i < buff.Length; i += CHUNK)
  67. {
  68. byte[] send = buff.Skip(i).Take(CHUNK).ToArray();
  69. Task.Run(() => client.Send(send));
  70. Thread.Sleep(1);
  71. }
  72. }
  73. else
  74. {
  75. client.Reconnect();
  76. return false;
  77. }
  78. return true;
  79. }
  80. public void ClientLastConnOnline()
  81. {
  82. Task.Run(() => client.Send("{\"is_speaking\": false}"));
  83. }
  84. public int ClientSendFileFunc(string file_name)//文件转录 0:发送成功 ret -1:文件类型不支持 -2:通信断开
  85. {
  86. string fileExtension = Path.GetExtension(file_name);
  87. fileExtension = fileExtension.Replace(".", "");
  88. if (!(fileExtension == "mp3" || fileExtension == "mp4" || fileExtension == "wav" || fileExtension == "pcm"))
  89. return -1;
  90. if (client.IsRunning)
  91. {
  92. if (fileExtension == "wav" || fileExtension == "pcm")
  93. {
  94. string firstbuff = string.Format("{{\"mode\": \"office\", \"chunk_size\": [{0},{1},{2}], \"chunk_interval\": {3}, \"wav_name\": \"{4}\", \"is_speaking\": true, \"wav_format\":\"pcm\"}}"
  95. , chunk_size[0], chunk_size[1], chunk_size[2], chunk_interval, Path.GetFileName(file_name));
  96. Task.Run(() => client.Send(firstbuff));
  97. if (fileExtension == "wav")
  98. showWAVForm(file_name);
  99. else if (fileExtension == "pcm")
  100. showWAVForm_All(file_name);
  101. }
  102. else if (fileExtension == "mp3" || fileExtension == "mp4")
  103. {
  104. string firstbuff = string.Format("{{\"mode\": \"offline\", \"chunk_size\": \"{0},{1},{2}\", \"chunk_interval\": {3}, \"wav_name\": \"{4}\", \"is_speaking\": true, \"wav_format\":\"{5}\"}}"
  105. , chunk_size[0], chunk_size[1], chunk_size[2], chunk_interval, Path.GetFileName(file_name), fileExtension);
  106. Task.Run(() => client.Send(firstbuff));
  107. showWAVForm_All(file_name);
  108. }
  109. }
  110. else
  111. {
  112. client.Reconnect();
  113. return -2;
  114. }
  115. return 0;
  116. }
  117. private string recbuff = string.Empty;//接收累计缓存内容
  118. private string onlinebuff = string.Empty;//接收累计在线缓存内容
  119. public void rec_message(string message, WebsocketClient client)
  120. {
  121. if (message != null)
  122. {
  123. try
  124. {
  125. string name = string.Empty;
  126. JsonDocument jsonDoc = JsonDocument.Parse(message);
  127. JsonElement root = jsonDoc.RootElement;
  128. string mode = root.GetProperty("mode").GetString();
  129. string text = root.GetProperty("text").GetString();
  130. bool isfinal = root.GetProperty("is_final").GetBoolean();
  131. if (message.IndexOf("wav_name ") != -1)
  132. name = root.GetProperty("wav_name").GetString();
  133. //if (name == "microphone")
  134. // Console.WriteLine($"实时识别内容: {text}");
  135. //else
  136. // Console.WriteLine($"文件名称:{name} 文件转录内容: {text}");
  137. if (mode == "2pass-online" && WSClient_Online.onlineasrmode != "offline")
  138. {
  139. onlinebuff += text;
  140. Console.WriteLine(recbuff + onlinebuff);
  141. }
  142. else if (mode == "2pass-offline")
  143. {
  144. recbuff += text;
  145. onlinebuff = string.Empty;
  146. Console.WriteLine(recbuff);
  147. }
  148. if (isfinal && WSClient_Online.onlineasrmode != "offline")//未结束当前识别
  149. {
  150. recbuff = string.Empty;
  151. }
  152. }
  153. catch (JsonException ex)
  154. {
  155. Console.WriteLine("JSON 解析错误: " + ex.Message);
  156. }
  157. }
  158. }
  159. private void showWAVForm(string file_name)
  160. {
  161. byte[] getbyte = FileToByte(file_name).Skip(44).ToArray();
  162. for (int i = 0; i < getbyte.Length; i += 102400)
  163. {
  164. byte[] send = getbyte.Skip(i).Take(102400).ToArray();
  165. Task.Run(() => client.Send(send));
  166. Thread.Sleep(5);
  167. }
  168. Thread.Sleep(100);
  169. Task.Run(() => client.Send("{\"is_speaking\": false}"));
  170. }
  171. private void showWAVForm_All(string file_name)
  172. {
  173. byte[] getbyte = FileToByte(file_name).ToArray();
  174. for (int i = 0; i < getbyte.Length; i += 1024000)
  175. {
  176. byte[] send = getbyte.Skip(i).Take(1024000).ToArray();
  177. Task.Run(() => client.Send(send));
  178. Thread.Sleep(5);
  179. }
  180. Thread.Sleep(10);
  181. Task.Run(() => client.Send("{\"is_speaking\": false}"));
  182. }
  183. public byte[] FileToByte(string fileUrl)
  184. {
  185. try
  186. {
  187. using (FileStream fs = new FileStream(fileUrl, FileMode.Open, FileAccess.Read))
  188. {
  189. byte[] byteArray = new byte[fs.Length];
  190. fs.Read(byteArray, 0, byteArray.Length);
  191. return byteArray;
  192. }
  193. }
  194. catch
  195. {
  196. return null;
  197. }
  198. }
  199. }
  200. }