C#讯飞语音合成、语音听写WebSocket版

需要根据using的命名空间,自行添加相关的dll引用(在NuGet里搜索并安装即可)

目录

 

语音合成

语音听写

完整工程代码


语音合成

using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using WebSocket4Net;

namespace 语音合成
{
    class Program
    {
        private const String hostUrl = "https://tts-api.xfyun.cn/v2/tts"; //http url 不支持解析 ws/wss schema
        private const String appid = "xxxxx";//到控制台-语音合成页面获取
        private const String apiSecret = "xxxxxxxxxxxxxxx";//到控制台-语音合成页面获取
        private const String apiKey = "xxxxxxxxxxxxxxxxxxx";//到控制台-语音合成页面获取
        private const String text = "白皮书说,党的十八大以来,中国的核安全事业进入安全高效发展的新时期。";

        private static WebSocket webSocket;
        static MemoryStream pcmStream = new MemoryStream();

        static void Main(string[] args)
        {
            string uri = GetAuthUrl(hostUrl, apiKey, apiSecret);
            webSocket = new WebSocket(uri);
            webSocket.Opened += OnOpened;
            webSocket.Closed += OnClosed;
            webSocket.Error += OnError;
            webSocket.MessageReceived += OnMessageReceived;
            webSocket.Open();
            Console.Read();
        }

        private static void OnError(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
        }

        private static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            Console.WriteLine("OnMessageReceived");
            dynamic msg = JsonConvert.DeserializeObject(e.Message);
            if (msg.code != 0)
            {
                Console.WriteLine($"error => {msg.message},sid => {msg.sid}");
                return;
            }
            byte[] audio = Convert.FromBase64String(msg.data.audio.Value.ToString());
            pcmStream.Write(audio, 0, audio.Length);
            if (msg.data.status == 2)
            {
                Play();
            }
        }

        private static void OnClosed(object sender, EventArgs e)
        {
            Console.WriteLine("OnClosed");
        }

        private static void OnOpened(object sender, EventArgs e)
        {
            Console.WriteLine("OnOpened");
            dynamic frame = new JObject();
            frame.common = new JObject
            {
                {"app_id" ,appid }
            };
            frame.business = new JObject
            {
                { "aue","raw" },
                //{ "sfl",1 },
                { "tte","UTF8" },
                { "vcn","xiaoyan"},
                { "pitch",50},
                { "speed",50}
            };
            frame.data = new JObject
            {
                { "status",2 },
                { "text",Convert.ToBase64String(Encoding.UTF8.GetBytes(text))}
            };
            webSocket.Send(frame.ToString());
        }

        private static String GetAuthUrl(String hostUrl, String apiKey, String apiSecret)
        {
            Uri url = new Uri(hostUrl);
            string date = DateTime.Now.ToString("R");
            string request_line = $"GET {url.AbsolutePath} HTTP/1.1";
            string signature_origin = $"host: {url.Host}\ndate: {date}\n{request_line}";
            HMAC hmac = HMAC.Create("System.Security.Cryptography.HMACSHA256");
            hmac.Key = Encoding.UTF8.GetBytes(apiSecret);
            var signature_sha = hmac.ComputeHash(Encoding.UTF8.GetBytes(signature_origin));
            string signature = Convert.ToBase64String(signature_sha);
            string authorization_origin = $@"hmac username=""{apiKey}"", algorithm=""hmac-sha256"", headers=""host date request-line"", signature=""{signature}""";
            string authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization_origin));
            UriBuilder builder = new UriBuilder()
            {
                Scheme = "wss",
                Host = url.Host,
                Path = url.AbsolutePath,
                Query = $"authorization={authorization}&date={date}&host={url.Host}",
            };
            return builder.ToString();
        }

        private static void Play()
        {
            pcmStream.Seek(0, SeekOrigin.Begin);
/*
            using (var fs = File.Create("test.pcm"))
            {
                pcmStream.WriteTo(fs);//保存为语音文件
            }*/
            WaveOutEvent waveOutEvent = new WaveOutEvent();
            waveOutEvent.Init(new RawSourceWaveStream(pcmStream, new WaveFormat(16000, 1)));
            waveOutEvent.Play();
            Console.WriteLine("正在播放,按回车键停止");
            Console.ReadLine();
            waveOutEvent.Stop();
            pcmStream.Close();
        }
    }
}

语音听写

using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using WebSocket4Net;

namespace 语音听写
{
    class Program
    {
        private const String hostUrl = "https://iat-api.xfyun.cn/v2/iat"; //中英文,http url 不支持解析 ws/wss schema
        private const String appid = "5ad2acd8";//到控制台-语音合成页面获取
        private const String apiSecret = "de00a26b74125b7dfe7d2160da509ff7";//到控制台-语音合成页面获取
        private const String apiKey = "7dca9a5f788a074f59fbc32b729bed99";//到控制台-语音合成页面获取
        //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)
        {

            //初始化录音机
            recorder = new WaveInEvent { WaveFormat = new WaveFormat(16000, 1) };
            recorder.DataAvailable += OnDataAvailable;
            recorder.RecordingStopped += OnRecordingStopped;
            
            string uri = GetAuthUrl(hostUrl, apiKey, apiSecret);
            webSocket = new WebSocket(uri);
            webSocket.Opened += OnOpened;
            webSocket.DataReceived += OnDataReceived;
            webSocket.Closed += OnClosed;
            webSocket.Error += OnError;
            webSocket.MessageReceived += OnMessageReceived;
            webSocket.Open();
            Console.Read();
            status = Status.LastFrame;
            //fs.Close();
        }

        private static void OnRecordingStopped(object sender, StoppedEventArgs e)
        {
            Console.WriteLine("OnRecordingStopped");
            Console.WriteLine(e.Exception?.Message);
        }

        private static void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            //Console.WriteLine("OnDataAvailable");
            switch (status)
            {
                case Status.FirstFrame:
                    {
                        dynamic frame = new JObject();
                        frame.common = new JObject
                        {
                            {"app_id" ,appid }
                        };
                        frame.business = new JObject
                        {
                            { "language","zh_cn" },
                            { "domain","iat" },
                            { "accent","mandarin"},
                            { "dwa","wpgs"}
                        };
                        frame.data = new JObject
                        {
                            { "status",(int)Status.FirstFrame },
                            { "format","audio/L16;rate=16000"},
                            { "encoding","raw" },
                            { "audio",Convert.ToBase64String(e.Buffer)}
                        };
                        webSocket.Send(frame.ToString());
                        status = Status.ContinueFrame;
                    }
                    break;
                case Status.ContinueFrame:
                    {
                        dynamic frame = new JObject();
                        frame.data = new JObject
                        {
                            { "status",(int)Status.ContinueFrame },
                            { "format","audio/L16;rate=16000"},
                            { "encoding","raw" },
                            { "audio",Convert.ToBase64String(e.Buffer)}
                        };
                        webSocket.Send(frame.ToString());
                    }
                    break;
                case Status.LastFrame:
                    {
                        dynamic frame = new JObject();
                        frame.data = new JObject
                        {
                            { "status",(int)Status.LastFrame },
                            { "format","audio/L16;rate=16000"},
                            { "encoding","raw" },
                            { "audio",Convert.ToBase64String(e.Buffer)}
                        };
                        webSocket.Send(frame.ToString());
                        recorder.StopRecording();
                    }
                    break;
                default:
                    break;
            }
        }

        private static void OnError(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
        {
            Console.WriteLine("OnError");
            Console.WriteLine(e.Exception.Message);
        }

        private static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            Console.WriteLine("OnMessageReceived");
            Console.WriteLine(e.Message);
            dynamic msg = JsonConvert.DeserializeObject(e.Message);
            if (msg.code != 0)
            {
                Console.WriteLine($"error => {msg.message},sid => {msg.sid}");
                return;
            }
            var ws = msg.data.result.ws;
            if (ws == null)
            {
                return;
            }
            foreach (var item in ws)
            {
                Console.Write(item.cw[0].w);
            }
            Console.WriteLine();
            if (msg.data.status == 2)
            {
                Console.WriteLine("识别结束");
                webSocket.Close();
            }
        }

        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 OnOpened(object sender, EventArgs e)
        {
            Console.WriteLine("OnOpened");
            ///从音频文件进行语音识别
            /*int buffer_size = 2048;
            byte[] buffer = new byte[buffer_size];
            int len = 0;
            Task.Run(() =>
            {
                while (true)
                {
                    len = fs.Read(buffer, 0, buffer_size);
                    if (len == 0)
                    {
                        status = Status.LastFrame;
                    }
                    OnDataAvailable(null, new WaveInEventArgs(buffer, len));
                    System.Threading.Thread.Sleep(40);
                    if (status == Status.LastFrame)
                    {
                        return;
                    }
                }
            });*/
            //从录音机进行语音识别
            recorder.StartRecording();

        }

        private static String GetAuthUrl(String hostUrl, String apiKey, String apiSecret)
        {
            Uri url = new Uri(hostUrl);
            string date = DateTime.Now.ToString("R");
            string request_line = $"GET {url.AbsolutePath} HTTP/1.1";
            string signature_origin = $"host: {url.Host}\ndate: {date}\n{request_line}";
            HMAC hmac = HMAC.Create("System.Security.Cryptography.HMACSHA256");
            hmac.Key = Encoding.UTF8.GetBytes(apiSecret);
            var signature_sha = hmac.ComputeHash(Encoding.UTF8.GetBytes(signature_origin));
            string signature = Convert.ToBase64String(signature_sha);
            string authorization_origin = $@"hmac username=""{apiKey}"", algorithm=""hmac-sha256"", headers=""host date request-line"", signature=""{signature}""";
            string authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization_origin));
            UriBuilder builder = new UriBuilder()
            {
                Scheme = "wss",
                Host = url.Host,
                Path = url.AbsolutePath,
                Query = $"authorization={authorization}&date={date}&host={url.Host}",
            };
            return builder.ToString();
        }
    }
}

完整工程代码

https://wwa.lanzous.com/iH7HLfl6w9i

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

DoraemonHC

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值