.net core 对接科大讯飞语音转写

89 阅读2分钟

(需要先注册服务)www.xfyun.cn/doc/asr/rta…

建立链接

//连接WebSocket服务器
public async void ConnectWebSocket()
{
    try
    { 
        webSocket = new WebSocket(GetAuthUrl(hostUrl, appKey));
        webSocket.Opened += OnOpened;
        webSocket.Closed += OnClosed;
        webSocket.Error += OnError;
        webSocket.MessageReceived += receiveMessage; 
        webSocket.Open();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

获取ws地址

  • signa生成

    1.获取baseString,baseString由appid和当前时间戳ts拼接而成,假如appid为595f23df,ts为1512041814,则baseString为 595f23df1512041814

    2.对baseString进行MD5,假如baseString为上一步生成的595f23df1512041814,MD5之后则为 0829d4012497c14a30e7e72aeebe565e

    3.以apiKey为key对MD5之后的baseString进行HmacSHA1加密,然后再对加密后的字符串进行base64编码。 假如apiKey为d9f4aa7ea6d94faca62cd88a28fd5234,MD5之后的baseString为上一步生成的0829d4012497c14a30e7e72aeebe565e,
    则加密之后再进行base64编码得到的signa为IrrzsJeOFk1NGfJHW6SkHUoN9CU=

  • 备注:

    apiKey:接口密钥,在应用中添加实时语音转写服务时自动生成,调用方注意保管;

    signa的生成公式:HmacSHA1(MD5(appid + ts), api_key),具体的生成方法详见

private string GetAuthUrl(string hostUrl, string apiKey)
{
    Uri url = new Uri(hostUrl);
    TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
    string tsStr = Convert.ToInt64(ts.TotalSeconds).ToString(); 

    string tt = new EncryptHelper().MD5Hash(appId + tsStr);
    var tt5 = MD5Hash(appId + tsStr);

    string signa = ToBase64hmac(tt5, apiKey); 
    UriBuilder builder = new UriBuilder()
    {
        Scheme = "wss",
        Host = url.Host,
        Path = url.AbsolutePath,
        Query = $"?appid={appId}&ts={tsStr}&signa={signa}",
    };
    return builder.ToString();
}  

地址加密处理

 public string MD5Hash(string source)
 {
     using (MD5 md5 = MD5.Create())
     {
         byte[] data = md5.ComputeHash(Encoding.UTF8.GetBytes(source));

         StringBuilder stringBuilder = new StringBuilder();
         for (int i = 0; i < data.Length; i++)
         {
             stringBuilder.Append(data[i].ToString("x2"));
         }
         return stringBuilder.ToString();
     }
 }

 public string ToBase64hmac(string strText, string strKey)
 { 
     HMACSHA1 myHMACSHA1 = new HMACSHA1(Encoding.UTF8.GetBytes(strKey)); 
     byte[] byteText = myHMACSHA1.ComputeHash(Encoding.UTF8.GetBytes(strText)); 
     return System.Convert.ToBase64String(byteText); 
 } 

发送语音byte

 private void OnOpened(object sender, EventArgs e)
 {
     Console.WriteLine("OnOpened");
     var filestream = File.Open(fileurl, FileMode.Open);
     while (true)
     {
         byte[] buffer = new byte[receiveChunkSize];//一次读取5M内容
         int r = filestream.Read(buffer, 0, buffer.Length);//实际读取的有效字节数

     if (r == 0)//读到最后内容
     {
         break;
     } 
     _logger.LogInformation("讯飞开始发送数据");
     webSocket.Send(bytes, 0, bytes.Length);
     }  
     webSocket.Send("{\"end\": true}");  
 }  

接收解析后的内容 并处理

public async void receiveMessage(object sender, MessageReceivedEventArgs e)
{ 
    Console.WriteLine("OnMessageReceived"); 
    dynamic msg = JsonConvert.DeserializeObject(e.Message); 
    if (msg.action == "result")
    { 
        var jsonObject = JsonConvert.DeserializeObject<Root>(JObject.Parse(e.Message).SelectToken("data").ToString()); 
        foreach (var item in jsonObject.cn.st.rt)
        {
            foreach (var item1 in item.ws)
            { 
                foreach (var item3 in item1.cw)
                {
                    retsb.Append(item3.w);
                }
            }
            await _countHub.Clients.All.SendAsync("ReceivePublicMsgXunFei", retsb);
        }
        if (jsonObject.ls == "true")
        {
            //识别结果
            result = retsb.ToString();
        }
    } 
    Console.WriteLine("识别结果:" + retsb);
} 

解析语音转写后的实体model

  public class Cw
  {
      /// <summary>
      ///
      /// </summary>
      public string w { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public string wp { get; set; }
  }

  public class Ws
  {
      /// <summary>
      /// 
      /// </summary>
      public List<Cw> cw { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public int wb { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public int we { get; set; }
  }

  public class Rt
  {
      /// <summary>
      /// 
      /// </summary>
      public List<Ws> ws { get; set; }
  }

  public class St
  {
      /// <summary>
      /// 
      /// </summary>
      public string bg { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public string ed { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public List<Rt> rt { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public string type { get; set; }
  }

  public class Cn
  {
      /// <summary>
      /// 
      /// </summary>
      public St st { get; set; }
  }

  public class Root
  {
      /// <summary>
      /// 
      /// </summary>
      public Cn cn { get; set; }
      /// <summary>
      /// 
      /// </summary>
      public int seg_id { get; set; }
      public string ls { get; set; }
  }