[原作]阿里云语音识别(闲时版)SDK Lite版本(不用包含阿里云的SDK了)
分享阿里云语音识别(闲时版)SDK Lite版本(不用包含阿里云的SDK了^_^);使用起来也更简单了!
其他版本可以相应的去更改预置参数就行了;或者根据你的需求改进!
闲话不多说,看代码:
1 //阿里云 语音识别(闲时板) 2 services.AddHttpClient("AliAsrLite", c => { 3 c.BaseAddress = new Uri("http://speechfiletranscriberlite.cn-shanghai.aliyuncs.com/"); 4 c.DefaultRequestHeaders.Add("Accept", "application/json"); 5 c.DefaultRequestHeaders.Add("User-Agent", "Alibaba Cloud (Microsoft Windows 10.0.19045 ) netcoreapp/2.2.6 Core/1.6.2.0"); 6 c.DefaultRequestHeaders.Add("x-sdk-client", "Net/2.0.0"); 7 c.DefaultRequestHeaders.Add("x-sdk-invoke-type", "common"); 8 c.DefaultRequestHeaders.Add("x-acs-version", "2021-12-21"); 9 });
上面设置一个 HttpClientFactory 的 Client 模板。

1 using System; 2 using System.Collections.Generic; 3 using System.Globalization; 4 using System.IO; 5 using System.Net; 6 using System.Net.Http; 7 using System.Security.Cryptography; 8 using System.Text; 9 using System.Web; 10 11 namespace Net.Http { 12 public class ReqHelperAliyunAsrLite { 13 14 private readonly IHttpClientFactory httpClientFactory; 15 /// <summary> 16 /// 语音识别(闲时版) 17 /// </summary> 18 private const string AliAsrLite = "AliAsrLite"; 19 20 21 public ReqHelperAliyunAsrLite(IHttpClientFactory _httpClientFactory) { 22 httpClientFactory = _httpClientFactory; 23 } 24 25 public CommonResponse Get(string action, string url, bool blog = false) { 26 var http = httpClientFactory.CreateClient(AliAsrLite); 27 if (!string.IsNullOrEmpty(action)) 28 http.DefaultRequestHeaders.Add("x-acs-action", action); 29 30 var response = http.GetAsync(url); 31 32 var resp = new CommonResponse() { 33 StatusCode = (int)response.Result.StatusCode, 34 Data = response.Result.Content.ReadAsStringAsync().Result // Encoding.UTF8.GetString 35 }; 36 if (blog) 37 Util.LogS("ww", "AliAsrLite", $"Get {url}\r\n-->> {resp.Data}\r\n"); 38 return resp; 39 } 40 41 //// http.DefaultRequestHeaders.Add("Content-MD5","") // 抛异常!!!! TMD 42 //public CommonResponse Post(string action, string url, string data, string contentType = "application/json", Dictionary<string, string> headers = null, bool blog = false) { 43 // var http = httpClientFactory.CreateClient(AliAsrLite); 44 // if (!string.IsNullOrEmpty(action)) 45 // http.DefaultRequestHeaders.Add("x-acs-action", action); 46 // if (headers != null && headers.Count > 0) { 47 // foreach (var p in headers) { 48 // //if (p.Key.Equals("Authorization")) { 49 // // http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(p.Value); 50 // // continue; 51 // //} 52 // //if (http.DefaultRequestHeaders.Contains(p.Key)) 53 // // http.DefaultRequestHeaders.Remove(p.Key); 54 // http.DefaultRequestHeaders.Add(new customHeader) 55 // http.DefaultRequestHeaders.TryAddWithoutValidation(p.Key, p.Value); 56 // } 57 // } 58 59 // var content = new StringContent(data, Encoding.UTF8, contentType); 60 61 // var response = http.PostAsync(url, content); 62 // var resp = new CommonResponse() { 63 // HttpStatus = (int)response.Result.StatusCode, 64 // Data = response.Result.Content.ReadAsStringAsync().Result // Encoding.UTF8.GetString 65 // }; 66 // if (blog) 67 // Util.LogS("ww", "AliAsrLite", $"Post {url}\r\n-->> {resp.Data}\r\n"); 68 // return resp; 69 //} 70 71 //public CommonResponse SubmitTask(string task, bool blog = false) { 72 // var body=new Dictionary<string, string>{ { "Task",task } }; 73 // string data = ConcatQueryString(body); 74 // var bodyData = System.Text.Encoding.UTF8.GetBytes(data); 75 76 // var strMd5 = Md5SumAndBase64(bodyData); 77 // var headers =new Dictionary<string, string> { 78 // {"Content-MD5", strMd5 }, 79 // {"Content-Type", "application/x-www-form-urlencoded"} 80 // }; 81 82 // var parms = GetParams("Task", task); 83 // string signStr = ParseSign(parms); 84 // string sign = SignString(signStr, CurrentContext.audioAsr.AccessKeySecret + "&"); 85 // parms.Add("Signature", sign); 86 87 // string url = "?" + ConcatQueryString(parms); 88 // return Post("SubmitTask", url, bodyData.ToString(), "application/x-www-form-urlencoded", headers, blog); 89 //} 90 91 public CommonResponse SubmitTask(string task, bool blog = false) { 92 93 var body = new Dictionary<string, string> { { "Task", task } }; 94 string data = ConcatQueryString(body); 95 var bodyData = System.Text.Encoding.UTF8.GetBytes(data); 96 97 var strMd5 = Md5SumAndBase64(bodyData); 98 //var headers = new Dictionary<string, string> { 99 // {"Content-MD5", strMd5 }, 100 // {"Content-Type", "application/x-www-form-urlencoded"} 101 //}; 102 103 var parms = GetParams("SubmitTask", "Task", task); 104 string signStr = ParseSign(parms); 105 string sign = SignString(signStr, CurrentContext.audioAsr.AccessKeySecret + "&"); 106 parms.Remove("Task"); 107 parms.Add("Signature", sign); 108 109 string url = "http://speechfiletranscriberlite.cn-shanghai.aliyuncs.com/?debug=1&" + ConcatQueryString(parms); 110 111 var uri = new Uri(url); 112 var httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); 113 114 httpWebRequest.Method = "POST"; 115 httpWebRequest.KeepAlive = true; 116 117 httpWebRequest.ServerCertificateValidationCallback = (s, cert, chains, sslPolicyError) => true; 118 119 //httpWebRequest.Accept = "application/json"; 120 httpWebRequest.Headers.Add("x-sdk-client", "Net/2.0.0"); 121 httpWebRequest.Headers.Add("x-sdk-invoke-type", "common"); 122 //httpWebRequest.Headers.Add("x-acs-version", "2021-12-21"); 123 httpWebRequest.ContentType = "application/x-www-form-urlencoded"; 124 httpWebRequest.UserAgent = "Alibaba Cloud (Microsoft Windows 10.0.19045 ) netcoreapp/2.2.6 Core/1.6.2.0"; 125 httpWebRequest.Headers.Add("Content-MD5", strMd5); 126 127 128 using (var stream = httpWebRequest.GetRequestStream()) { 129 stream.Write(bodyData, 0, bodyData.Length); 130 } 131 CommonResponse response; 132 try { 133 using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse()) { 134 response = ParseHttpResponse(httpWebResponse); 135 } 136 } 137 catch (WebException ex) { 138 if (ex.Response != null) { 139 using (HttpWebResponse httpWebResponse = ex.Response as HttpWebResponse) { 140 response = ParseHttpResponse(httpWebResponse); 141 } 142 } 143 else 144 throw new Exception("SDK.WebException" + 145 string.Format("HttpWebRequest WebException occured, the request url is {0} {1}", 146 httpWebRequest.RequestUri == null ? "empty" : httpWebRequest.RequestUri.Host, ex)); 147 } 148 catch (IOException ex) { 149 throw new Exception("SDK.ServerUnreachable:" + 150 string.Format("Server unreachable: connection to url: {0} failed. {1}", 151 httpWebRequest.RequestUri == null ? "empty" : httpWebRequest.RequestUri.Host, ex)); 152 } 153 catch (Exception ex) { 154 throw new Exception("SDK.Exception" + 155 string.Format("The request url is {0} {1}", 156 httpWebRequest.RequestUri == null ? "empty" : httpWebRequest.RequestUri.Host, ex)); 157 } 158 if (blog) 159 Util.LogS("ww", "AliAsrLite", $"Get {url}\r\n-->> {response.Data}\r\n"); 160 return response; 161 } 162 private static CommonResponse ParseHttpResponse(HttpWebResponse httpWebResponse) { 163 var content = ReadContent(httpWebResponse); 164 var statusCode = (int)httpWebResponse.StatusCode; 165 var contentType = httpWebResponse.ContentType; 166 167 return new CommonResponse { 168 StatusCode = (int)statusCode, 169 ContentType = contentType, 170 Data = Encoding.UTF8.GetString(content) 171 }; 172 } 173 public static byte[] ReadContent(HttpWebResponse rsp) { 174 using (var ms = new MemoryStream()) 175 using (var stream = rsp.GetResponseStream()) { 176 { 177 var buffer = new byte[1024]; 178 while (true) { 179 var length = stream.Read(buffer, 0, 1024); 180 if (length == 0) { 181 break; 182 } 183 184 ms.Write(buffer, 0, length); 185 } 186 187 ms.Seek(0, SeekOrigin.Begin); 188 var bytes = new byte[ms.Length]; 189 ms.Read(bytes, 0, bytes.Length); 190 return bytes; 191 } 192 } 193 } 194 195 public CommonResponse GetTaskResult(string taskid, bool blog = false) { 196 var parms = GetParams("GetTaskResult", "TaskId", taskid); 197 string signStr = ParseSign(parms); 198 string sign = SignString(signStr, CurrentContext.audioAsr.AccessKeySecret + "&"); 199 parms.Add("Signature", sign); 200 201 string url = "?" + ConcatQueryString(parms); 202 return Get("GetTaskResult", url, blog); 203 } 204 205 public string SignString(string stringToSign, string accessKeySecret) { 206 using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(accessKeySecret))) { 207 var hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)); 208 return Convert.ToBase64String(hashValue); 209 } 210 } 211 212 213 public Dictionary<string, string> GetParams(string action, string key, string value) { 214 return new Dictionary<string, string> { 215 { "Format", "JSON" }, 216 { "Version", "2021-12-21" }, 217 { "Action", action }, 218 { "Timestamp", FormatIso8601Date(DateTime.UtcNow) }, 219 { "SignatureMethod", "HMAC-SHA1" }, 220 { "SignatureVersion", "1.0" }, 221 { "SignatureNonce", Guid.NewGuid().ToString() }, 222 { "AccessKeyId", CurrentContext.audioAsr.AccessKeyID }, 223 { "RegionId", "cn-shanghai" }, 224 { key, value } 225 }; 226 } 227 228 public string ParseSign(Dictionary<string, string> parms) { 229 IDictionary<string, string> sortedDictionary = new SortedDictionary<string, string>(parms, StringComparer.Ordinal); 230 var canonicalizedQueryString = new StringBuilder(); 231 foreach (var p in sortedDictionary) { 232 canonicalizedQueryString.Append("&") 233 .Append(PercentEncode(p.Key)).Append("=") 234 .Append(PercentEncode(p.Value)); 235 } 236 var stringToSign = new StringBuilder(); 237 stringToSign.Append("GET"); 238 stringToSign.Append("&"); 239 stringToSign.Append(PercentEncode("/")); 240 stringToSign.Append("&"); 241 stringToSign.Append(PercentEncode(canonicalizedQueryString.ToString().Substring(1))); 242 243 return stringToSign.ToString(); 244 } 245 246 public static string ConcatQueryString(Dictionary<string, string> parameters) { 247 if (null == parameters) { 248 return null; 249 } 250 251 var sb = new StringBuilder(); 252 253 foreach (var p in parameters) { 254 sb.Append(Encode(p.Key)); 255 if (p.Value != null) { 256 sb.Append("=").Append(Encode(p.Value)); 257 } 258 sb.Append("&"); 259 } 260 261 var strIndex = sb.Length; 262 if (parameters.Count > 0) { 263 sb.Remove(strIndex - 1, 1); 264 } 265 266 return sb.ToString(); 267 } 268 public static string Encode(string value) { 269 return HttpUtility.UrlEncode(value, Encoding.UTF8); 270 } 271 272 public static string PercentEncode(string value) { 273 var stringBuilder = new StringBuilder(); 274 var text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"; 275 var bytes = Encoding.UTF8.GetBytes(value); 276 foreach (char c in bytes) { 277 if (text.IndexOf(c) >= 0) { 278 stringBuilder.Append(c); 279 } 280 else { 281 stringBuilder.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)c)); 282 } 283 } 284 285 return stringBuilder.ToString(); 286 } 287 288 public static string Md5SumAndBase64(byte[] buff) { 289 using (MD5 md5 = new MD5CryptoServiceProvider()) { 290 var output = md5.ComputeHash(buff); 291 return Convert.ToBase64String(output, 0, output.Length); 292 } 293 } 294 295 private const string ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 296 public static string FormatIso8601Date(DateTime date) //DateTime.UtcNow 297 { 298 return date.ToUniversalTime() 299 .ToString(ISO8601_DATE_FORMAT, CultureInfo.CreateSpecificCulture("en-US")); 300 } 301 302 303 public class CommonResponse { 304 public int StatusCode; 305 public string ContentType; 306 public string Data; 307 } 308 } 309 }
使用方法:
相应的配置,都在 CurrentContext.audioAsr 中。
在实例化的时候,传入一个 IHttpClientFactory接口参数即可。
然后使用:
1 private readonly ReqHelperAliyunAsrLite reqHelperAliLite; 2 3 public ClassConstructor(IHttpClientFactory httpClientFactory) { 4 reqHelperAliLite = new ReqHelperAliyunAsrLite(httpClientFactory); 5 } 6 7 //=========== Test DO =========== 8 9 // 设置 task,以 JSON 字符串形式设置到请求 Body 中。 10 JObject obj = new JObject { 11 ["appkey"] = CurrentContext.audioAsr.Appkey, // Appkey 12 ["file_link"] = CurrentContext.audioAsr.AudioFileDomain + task.path + "?token=" + task.token, // 存放录音文件的地址,需要使用域名而不是IP地址 13 ["enable_words"] = false, // 设置是否输出词信息,默认为false 14 ["enable_semantic_sentence_detection"] = true, // 是否启⽤语义断句 15 ["enable_punctuation_prediction"] = true, // 是否给句子加标点。默认值true(加标点) 16 ["auto_split"] = true, // 是否开启智能分轨,声道channel0和channel1就是音轨编号 17 ["supervise_type"] = 2, // 说话人分离的确定人数方式(2:算法决定人数) 18 ["enable_inverse_text_normalization"] = true, // 中文数字将转为阿拉伯数字输出 19 20 }; 21 if (!string.IsNullOrWhiteSpace(CurrentContext.audioAsr.CallBackDomain)) { 22 obj["enable_callback"] = true; // 是否启用回调功能,默认值为false 23 // 回调服务的地址,enable_callback取值为true时,本字段必选 24 obj["callback_url"] = $"{CurrentContext.audioAsr.CallBackDomain}/api/Callback/aliyunAsr?msgid={task.msgid}"; 25 } 26 string tsk = obj.ToString(); 27 var resp = reqHelperAliLite.SubmitTask(tsk); // 提交识别任务 28 29 var tr = reqHelperAliLite.GetTaskResult("64ac59d8931b4a3d996c68e3336XXXX"); // 查询识别结果 (参数: 请求返回的 taskid)
欢迎修改优化!^_^
--- auth:lzpong
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!