C#實現百度AI-實時語音識別轉寫-附源碼


好久沒來園子做貢獻了,今天貼一個最近弄的一個小東西,實時語音識別,該技術目前已經很普遍,不做過多介紹了

網上找了很久,沒有找到例子,不是要分就是要分,我只想說,程序猿何苦為難程序猿。。。。

而且下載的例子也都不是實時語音轉寫,基本都是短語音或者音頻轉寫,沒辦法了,自己搞吧。

網站看到一篇帖子,借鑒一個前輩寫的訊飛識別語音的例子做為參考,修改了一下,可以實現 實時語音轉寫

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



    }

 

大家有問題,可以留言,本人不一定什么時候會再到園子逛,如果看到后會第一時間回復,與大家進行交流!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM