赞
踩
好久没来做贡献了,今天贴一个最近弄的一个小东西,实时语音识别,该技术目前已经很普遍,不做过多介绍了
网上找了很久,没有找到例子,不是要分就是要分,我只想说,程序猿何苦为难程序猿。。。。
而且下载的例子也都不是实时语音转写,基本都是短语音或者音频转写,没办法了,自己搞吧。
网站看到一篇帖子,借鉴一个前辈写的讯飞识别语音的例子做为参考,修改了一下,可以实现 实时语音转写
https://blog.csdn.net/qq_40582463/article/details/107983905
本案例对接的是 百度平台 WebSocket API 实时语音专写 ,因为百度有免费额度,讯飞还需要企业认证,做为平民玩家,只能优先使用方便并还免费的。
另外其他几个平台对接也都差不多,案例是使用C#语言 实现WebSocket进行通信对接,其他语言各平台可能会有SDK或Demo,但是都没有C#的。。
如果有想是要C# 对接其它平台的,代码可以作为参考,本人大致看了讯飞与百度的,对接都大同小异!
只是参数上有一些区别,这个看个人选择哪个平台做对接。最大差别嘛,收费不一样
废话不多说了,直接上代码,只有一个文件,就不打源码包了,基本引用及重要方法都已注释!
也不需要大家使用积分下载,用的时候说声谢谢就行。
- using NAudio.Wave;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using System;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading;
- using System.Web;
- using WebSocket4Net;
-
- namespace ConsoleApp
- {
- /// <summary>
- /// 百度实时语音识别 WebSocket
- /// </summary>
- class Program
- { //引用俩个包,Nuget下可以找到, websocket Naudio
-
- //百度新账户注册送10个小时免费试用,测试肯定够
- private const String appid = "XXXXX";//到控制台-语音合成页面获取
- private const String apiSecret = "XXXXXX";//到控制台-语音合成页面获取
- private const String apiKey = "XXXXX";//到控制台-语音合成页面获取
- //private static FileStream fs = new FileStream("test.pcm", FileMode.Open);//从音频文件进行语音识别时会用到
- enum Status
- {
- FirstFrame = 0,
- ContinueFrame = 1,
- LastFrame = 2
- }
-
- private static WebSocket webSocket;
- private static IWaveIn recorder;//录音机
- private static volatile Status status = Status.FirstFrame;
-
- static void Main(string[] args)
- {
-
- string ts = GenerateTimeStamp();
-
- string yb = EncryptUtil.HMACSHA1Text(EncryptUtil.GetMd5Code(appid + ts), apiKey);
-
- string uril = "wss://vop.baidu.com/realtime_asr?sn="+Guid.NewGuid().ToString();
- //初始化录音机
- recorder = new WaveInEvent { WaveFormat = new WaveFormat(16000, 1) };
- recorder.DataAvailable += OnDataAvailable;
- recorder.RecordingStopped += OnRecordingStopped;
-
- //开始请求 WebSocket
- webSocket = new WebSocket(uril);
- webSocket.Opened += OnOpened;
- webSocket.DataReceived += OnDataReceived;
- webSocket.MessageReceived += OnMessageReceived;
- webSocket.Open();
-
- //停止
- Console.Read();
- status = Status.LastFrame;
- webSocket.Closed += OnClosed;
- webSocket.Error += OnError;
-
- } //请求开始
- private static void OnDataAvailable(object sender, WaveInEventArgs e)
- {
- switch (status)
- {
- case Status.FirstFrame:握手
- {
- dynamic frame = new JObject();
- frame.type = "START";
- frame.data = new JObject
- {
- { "appid",appid},
- { "appkey","appkey"},
- { "dev_pid",15372},
- { "cuid","cuid-1"},
- { "format","pcm"},
- { "sample",16000},
- };
- webSocket.Send(frame.ToString());
- status = Status.ContinueFrame;
- }
- break;
- case Status.ContinueFrame://开始发送
- {
- dynamic frame = new JObject();
- frame = Convert.ToBase64String(e.Buffer);
- webSocket.Send(e.Buffer,0, e.Buffer.Length);
- }
- break;
- case Status.LastFrame://关闭
- {
- dynamic frame = new JObject();
- frame.type = "FINISH";
- webSocket.Send(frame.ToString());
- recorder.StopRecording();
- }
- break;
- default:
- break;
- }
- }
- //返回结果处理
- private static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
- {
- //返回的JSON串"{\"err_msg\":\"OK\",\"err_no\":0,\"log_id\":1542502511,\"result\":\"你好\",\"sn\":\"c36964c8-d86c-4a06-b7cf-8939539d3eb8_ws_1\",\"type\":\"MID_TEXT\"}\n"
- Console.WriteLine(e.Message);
- dynamic msg = JsonConvert.DeserializeObject(e.Message);
-
- if (msg.err_msg !="OK")
- {
- Console.WriteLine($"error => {msg.message},err_no => {msg.err_no}");
- return;
- }
- var ws = msg.result;
- if (ws == null)
- {
- return;
- }
-
- Console.Write(ws);
- Console.WriteLine();
- }
-
- private static void OnError(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
- {
- Console.WriteLine("OnError");
- Console.WriteLine(e.Exception.Message);
- }
- private static void OnClosed(object sender, EventArgs e)
- {
- Console.WriteLine("OnClosed");
- recorder.DataAvailable -= OnDataAvailable;
- }
-
-
- private static void OnDataReceived(object sender, DataReceivedEventArgs e)
- {
- Console.WriteLine("OnDataReceived");
- Console.WriteLine(e.Data.Length);
- }
-
-
- private static void OnRecordingStopped(object sender, StoppedEventArgs e)
- {
- Console.WriteLine("OnRecordingStopped");
- Console.WriteLine(e.Exception?.Message);
- }
- /// <summary>
- /// 检查麦克风
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private static void OnOpened(object sender, EventArgs e)
- {
- Console.WriteLine("OnOpened");
- try
- {
- recorder.StartRecording();
- }
- catch (Exception ex)
- {
-
- Console.WriteLine("未插入麦克风,程序关闭");
- }
-
- }
- /// <summary>
- /// 时间戳
- /// </summary>
- /// <returns></returns>
- public static string GenerateTimeStamp()
- {
- TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
- return Convert.ToInt64(ts.TotalSeconds).ToString();
- }
-
- }
- }
加密方法,忘记是哪个前辈写的,直接用吧,反正我是很懒的。。。
- public class EncryptUtil
- {
-
- public static string GetMd5Code(string text)
- {
- try
- {
- //MD5类是抽象类
- MD5 md5 = MD5.Create();
- //需要将字符串转成字节数组
- byte[] buffer = Encoding.Default.GetBytes(text);
- //加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
- byte[] md5buffer = md5.ComputeHash(buffer);
- string str = null;
- // 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
- foreach (byte b in md5buffer)
- {
- //得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
- //但是在和对方测试过程中,发现我这边的MD5加密编码,经常出现少一位或几位的问题;
- //后来分析发现是 字符串格式符的问题, X 表示大写, x 表示小写,
- //X2和x2表示不省略首位为0的十六进制数字;
- str += b.ToString("x2");
- }
- Console.WriteLine(str);//202cb962ac59075b964b07152d234b70
- return str;
- }
- catch (Exception e)
- {
- System.Diagnostics.Debug.WriteLine("GetMd5Code exception:" + e.Message);
- }
- return null;
- }
-
-
- #region HMACSHA1加密 对二进制数据转Base64后再返回
- /// <summary>
- /// HMACSHA1加密
- /// </summary>
- /// <param name="text">要加密的原串</param>
- ///<param name="key">私钥</param>
- /// <returns></returns>
- public static string HMACSHA1Text(string text, string key)
- {
- try
- {
- //HMACSHA1加密
- HMACSHA1 hmacsha1 = new HMACSHA1
- {
- Key = System.Text.Encoding.UTF8.GetBytes(key)
- };
-
- byte[] dataBuffer = System.Text.Encoding.UTF8.GetBytes(text);
- byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);
-
- return Convert.ToBase64String(hashBytes);
- }
- catch (Exception e)
- {
- System.Diagnostics.Debug.WriteLine("HMACSHA1Text exception:" + e.Message);
- }
- return null;
- }
- #endregion
-
-
-
- }
大家有问题,可以留言,本人不一定什么时候在来,看到后会第一时间回复,与大家进行交流!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。