当前位置:   article > 正文

C#实现百度AI-实时语音识别转写-附源码_百度 实时语音识别

百度 实时语音识别

好久没来做贡献了,今天贴一个最近弄的一个小东西,实时语音识别,该技术目前已经很普遍,不做过多介绍了

网上找了很久,没有找到例子,不是要分就是要分,我只想说,程序猿何苦为难程序猿。。。。

而且下载的例子也都不是实时语音转写,基本都是短语音或者音频转写,没办法了,自己搞吧。

网站看到一篇帖子,借鉴一个前辈写的讯飞识别语音的例子做为参考,修改了一下,可以实现 实时语音转写

https://blog.csdn.net/qq_40582463/article/details/107983905

 

本案例对接的是 百度平台 WebSocket API 实时语音专写 ,因为百度有免费额度,讯飞还需要企业认证,做为平民玩家,只能优先使用方便并还免费的。

另外其他几个平台对接也都差不多,案例是使用C#语言 实现WebSocket进行通信对接,其他语言各平台可能会有SDK或Demo,但是都没有C#的。。

如果有想是要C# 对接其它平台的,代码可以作为参考,本人大致看了讯飞与百度的,对接都大同小异!

只是参数上有一些区别,这个看个人选择哪个平台做对接。最大差别嘛,收费不一样

废话不多说了,直接上代码,只有一个文件,就不打源码包了,基本引用及重要方法都已注释!

也不需要大家使用积分下载,用的时候说声谢谢就行。

  1. using NAudio.Wave;
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. using System;
  5. using System.Security.Cryptography;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Web;
  9. using WebSocket4Net;
  10. namespace ConsoleApp
  11. {
  12. /// <summary>
  13. /// 百度实时语音识别 WebSocket
  14. /// </summary>
  15. class Program
  16. { //引用俩个包,Nuget下可以找到, websocket Naudio
  17. //百度新账户注册送10个小时免费试用,测试肯定够
  18. private const String appid = "XXXXX";//到控制台-语音合成页面获取
  19. private const String apiSecret = "XXXXXX";//到控制台-语音合成页面获取
  20. private const String apiKey = "XXXXX";//到控制台-语音合成页面获取
  21. //private static FileStream fs = new FileStream("test.pcm", FileMode.Open);//从音频文件进行语音识别时会用到
  22. enum Status
  23. {
  24. FirstFrame = 0,
  25. ContinueFrame = 1,
  26. LastFrame = 2
  27. }
  28. private static WebSocket webSocket;
  29. private static IWaveIn recorder;//录音机
  30. private static volatile Status status = Status.FirstFrame;
  31. static void Main(string[] args)
  32. {
  33. string ts = GenerateTimeStamp();
  34. string yb = EncryptUtil.HMACSHA1Text(EncryptUtil.GetMd5Code(appid + ts), apiKey);
  35. string uril = "wss://vop.baidu.com/realtime_asr?sn="+Guid.NewGuid().ToString();
  36. //初始化录音机
  37. recorder = new WaveInEvent { WaveFormat = new WaveFormat(16000, 1) };
  38. recorder.DataAvailable += OnDataAvailable;
  39. recorder.RecordingStopped += OnRecordingStopped;
  40. //开始请求 WebSocket
  41. webSocket = new WebSocket(uril);
  42. webSocket.Opened += OnOpened;
  43. webSocket.DataReceived += OnDataReceived;
  44. webSocket.MessageReceived += OnMessageReceived;
  45. webSocket.Open();
  46. //停止
  47. Console.Read();
  48. status = Status.LastFrame;
  49. webSocket.Closed += OnClosed;
  50. webSocket.Error += OnError;
  51. } //请求开始
  52. private static void OnDataAvailable(object sender, WaveInEventArgs e)
  53. {
  54. switch (status)
  55. {
  56. case Status.FirstFrame:握手
  57. {
  58. dynamic frame = new JObject();
  59. frame.type = "START";
  60. frame.data = new JObject
  61. {
  62. { "appid",appid},
  63. { "appkey","appkey"},
  64. { "dev_pid",15372},
  65. { "cuid","cuid-1"},
  66. { "format","pcm"},
  67. { "sample",16000},
  68. };
  69. webSocket.Send(frame.ToString());
  70. status = Status.ContinueFrame;
  71. }
  72. break;
  73. case Status.ContinueFrame://开始发送
  74. {
  75. dynamic frame = new JObject();
  76. frame = Convert.ToBase64String(e.Buffer);
  77. webSocket.Send(e.Buffer,0, e.Buffer.Length);
  78. }
  79. break;
  80. case Status.LastFrame://关闭
  81. {
  82. dynamic frame = new JObject();
  83. frame.type = "FINISH";
  84. webSocket.Send(frame.ToString());
  85. recorder.StopRecording();
  86. }
  87. break;
  88. default:
  89. break;
  90. }
  91. }
  92. //返回结果处理
  93. private static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
  94. {
  95. //返回的JSON串"{\"err_msg\":\"OK\",\"err_no\":0,\"log_id\":1542502511,\"result\":\"你好\",\"sn\":\"c36964c8-d86c-4a06-b7cf-8939539d3eb8_ws_1\",\"type\":\"MID_TEXT\"}\n"
  96. Console.WriteLine(e.Message);
  97. dynamic msg = JsonConvert.DeserializeObject(e.Message);
  98. if (msg.err_msg !="OK")
  99. {
  100. Console.WriteLine($"error => {msg.message},err_no => {msg.err_no}");
  101. return;
  102. }
  103. var ws = msg.result;
  104. if (ws == null)
  105. {
  106. return;
  107. }
  108. Console.Write(ws);
  109. Console.WriteLine();
  110. }
  111. private static void OnError(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
  112. {
  113. Console.WriteLine("OnError");
  114. Console.WriteLine(e.Exception.Message);
  115. }
  116. private static void OnClosed(object sender, EventArgs e)
  117. {
  118. Console.WriteLine("OnClosed");
  119. recorder.DataAvailable -= OnDataAvailable;
  120. }
  121. private static void OnDataReceived(object sender, DataReceivedEventArgs e)
  122. {
  123. Console.WriteLine("OnDataReceived");
  124. Console.WriteLine(e.Data.Length);
  125. }
  126. private static void OnRecordingStopped(object sender, StoppedEventArgs e)
  127. {
  128. Console.WriteLine("OnRecordingStopped");
  129. Console.WriteLine(e.Exception?.Message);
  130. }
  131. /// <summary>
  132. /// 检查麦克风
  133. /// </summary>
  134. /// <param name="sender"></param>
  135. /// <param name="e"></param>
  136. private static void OnOpened(object sender, EventArgs e)
  137. {
  138. Console.WriteLine("OnOpened");
  139. try
  140. {
  141. recorder.StartRecording();
  142. }
  143. catch (Exception ex)
  144. {
  145. Console.WriteLine("未插入麦克风,程序关闭");
  146. }
  147. }
  148. /// <summary>
  149. /// 时间戳
  150. /// </summary>
  151. /// <returns></returns>
  152. public static string GenerateTimeStamp()
  153. {
  154. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  155. return Convert.ToInt64(ts.TotalSeconds).ToString();
  156. }
  157. }
  158. }

 加密方法,忘记是哪个前辈写的,直接用吧,反正我是很懒的。。。

  1. public class EncryptUtil
  2. {
  3. public static string GetMd5Code(string text)
  4. {
  5. try
  6. {
  7. //MD5类是抽象类
  8. MD5 md5 = MD5.Create();
  9. //需要将字符串转成字节数组
  10. byte[] buffer = Encoding.Default.GetBytes(text);
  11. //加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
  12. byte[] md5buffer = md5.ComputeHash(buffer);
  13. string str = null;
  14. // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
  15. foreach (byte b in md5buffer)
  16. {
  17. //得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
  18. //但是在和对方测试过程中,发现我这边的MD5加密编码,经常出现少一位或几位的问题;
  19. //后来分析发现是 字符串格式符的问题, X 表示大写, x 表示小写,
  20. //X2和x2表示不省略首位为0的十六进制数字;
  21. str += b.ToString("x2");
  22. }
  23. Console.WriteLine(str);//202cb962ac59075b964b07152d234b70
  24. return str;
  25. }
  26. catch (Exception e)
  27. {
  28. System.Diagnostics.Debug.WriteLine("GetMd5Code exception:" + e.Message);
  29. }
  30. return null;
  31. }
  32. #region HMACSHA1加密 对二进制数据转Base64后再返回
  33. /// <summary>
  34. /// HMACSHA1加密
  35. /// </summary>
  36. /// <param name="text">要加密的原串</param>
  37. ///<param name="key">私钥</param>
  38. /// <returns></returns>
  39. public static string HMACSHA1Text(string text, string key)
  40. {
  41. try
  42. {
  43. //HMACSHA1加密
  44. HMACSHA1 hmacsha1 = new HMACSHA1
  45. {
  46. Key = System.Text.Encoding.UTF8.GetBytes(key)
  47. };
  48. byte[] dataBuffer = System.Text.Encoding.UTF8.GetBytes(text);
  49. byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
  50. return Convert.ToBase64String(hashBytes);
  51. }
  52. catch (Exception e)
  53. {
  54. System.Diagnostics.Debug.WriteLine("HMACSHA1Text exception:" + e.Message);
  55. }
  56. return null;
  57. }
  58. #endregion
  59. }

大家有问题,可以留言,本人不一定什么时候在来,看到后会第一时间回复,与大家进行交流!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/376464
推荐阅读
相关标签
  

闽ICP备14008679号