吐槽一下,讯飞官方webapi,没有提供.NET版本案例,只有python,java,只好自己摸索,代码不太简洁,这里复习总结一下,权当作做笔记摘抄一样总结一番,也给第一天尝试其他小伙伴一点参考。
检查每个参数名,根据官网提供的api
https://www.xfyun.cn/doc/asr/lfasr/API.html
关于生成分片文件名称,本质是生成类似aaaaaaaa字符串
分片文件本质是,将流一节节发送过去,
有图有真相
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;
namespace audio
{
/**
* 生成slice_id的工具类
* 每个转写任务都新建一个SliceIdGenerator来按照分片顺序依次生成slice_id
*
* @author white
*
*/
public class SliceIdGenerator
{
private const String INIT_STR = "aaaaaaaaa`";
private int length = 0;
private char[] ch;
public SliceIdGenerator()
{
this.length = INIT_STR.Length;
this.ch = INIT_STR.ToCharArray();
}
/**
* 获取sliceId
*
* @return
*/
public String getNextSliceId()
{
for (int i = 0, j = length - 1; i < length && j >= 0; i++)
{
if (ch[j] != 'z')
{
ch[j]++;
break;
}
else
{
ch[j] = 'a';
j--;
continue;
}
}
return new String(ch);
}
}
//{"data":"ec13805cb5e642649027f797ab7e9e31","err_no":0,"failed":null,"ok":0}
public class iFlyResult
{
public int ok { get; set; }
public int err_no { get; set; }
public string failed { get; set; }
public string data { get; set; }
//public string task_id { get; set; }
}
//{\"bg\":\"310\",\"ed\":\"1980\",\"onebest\":\"1801. \",\"speaker\":\"0\"}
public class StatusResult
{
public string desc { get; set; }
public int status { get; set; }
}
public class getResult
{
public string bg { get; set; }
public string ed { get; set; }
public string onebest { get; set; }
public string speaker { get; set; }
}
// RequestApi api = new RequestApi("88888888", "888888888888888888888888", "");
public class ifly
{
public string task_id="";
string detail = "";
public void testSigna(){
string signa = getSigna("37982798", "1512041814", "888888888888888888888888");
}
//byte[] buffer,
public string BuildParam_prepare(string app_id, string ts, string signa, string filepath,int slice_num)
{
FileInfo fileInfo = new FileInfo(filepath);//file完整文件路径
string file_len = fileInfo.Length.ToString();//kb
string file_name = fileInfo.Name;
//string lfasr_type = "0";
//string has_participle = "false";
//string max_alternatives = "0";
//.....其他非必选
return "&app_id=" + app_id + "&signa=" + signa + "&ts=" + ts + "&file_len=" + file_len + "&file_name=" + file_name + "&slice_num=" + slice_num;
}
public string getSigna(string appid,string ts,string key) {
string baseString = appid + ts;
string targetbase = GenerateMD5(baseString);
string signa = HmacSha1Sign(key,targetbase);
return signa;
}
public string GenerateMD5(string txt)
{
using (MD5 mi = MD5.Create())
{
byte[] buffer = Encoding.Default.GetBytes(txt);
//开始加密
byte[] newBuffer = mi.ComputeHash(buffer);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < newBuffer.Length; i++)
{
sb.Append(newBuffer[i].ToString("x2"));
}
return sb.ToString();
}
}
public string HmacSha1Sign(string secret, string strOrgData)
{
var hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(secret));
var dataBuffer = Encoding.UTF8.GetBytes(strOrgData);
var hashBytes = hmacsha1.ComputeHash(dataBuffer);
return Convert.ToBase64String(hashBytes);
}
//第一步:获取taskid
public string voice2txt(string app_id,string ts,string signa,string filepath,int slice_num)
{
detail = "";
HttpWebRequest request = null;
HttpWebResponse response = null;
Stream reqStream = null;
request = (HttpWebRequest)WebRequest.Create("https://raasr.xfyun.cn/api/prepare");
request.Method = "post"; //设置为post请求
request.ReadWriteTimeout = 5000;
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
byte[] postData = Encoding.UTF8.GetBytes(BuildParam_prepare(app_id,ts,signa,filepath,slice_num)); //使用utf-8格式组装post参数
reqStream = request.GetRequestStream();
reqStream.Write(postData, 0, postData.Length);
response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string ret = myStreamReader.ReadToEnd();
iFlyResult prepareresult = new JavaScriptSerializer().Deserialize(ret);
return prepareresult.data;
}
//第二步:上传数据,
RequestApi api = new RequestApi("5e3950f1", "098d577bb69023d205ffaeba2bcf17e6", "");
public string uploadSlice(string filepath,bool iszimu)
{
//确保所有分片上传成功,再进行合并
SliceIdGenerator sg = new SliceIdGenerator();
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] content_s = br.ReadBytes((int)fs.Length);
int SLICE_SICE = 10485760;
//正好几片
bool iszhen = false;
int slice_num = (content_s.Length / SLICE_SICE);
if (content_s.Length % SLICE_SICE != 0)
{
slice_num += 1;
}
else {
iszhen = true;
}
string result = "";
string app_id = "88888888";
string ts = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds).ToString();
string signa = getSigna(app_id, ts, "098d577bb69023d205ffaeba2bcf17e6");
//计算出片的数量
task_id = voice2txt(app_id, ts, signa, filepath, slice_num);
//循环上传每片的流
int len = iszhen ? SLICE_SICE : (content_s.Length % SLICE_SICE);
byte[] content = null;
for (int i = 0; i < slice_num; i++)
{
//如果是最后一个那么取余
if (i == slice_num - 1)
{
content = new byte[len];
Array.Copy(content_s, (i) * SLICE_SICE, content, 0, len);
}
else {
content = new byte[SLICE_SICE];
Array.Copy(content_s, (i) * SLICE_SICE, content, 0, SLICE_SICE);
}
string BuildParam_uploadSlide = "&app_id=" + app_id + "&signa=" + signa + "&ts=" + ts + "&task_id=" + task_id + "&slice_id=" + sg.getNextSliceId();
string rett = HttpPostMulti("https://raasr.xfyun.cn/api/upload?" + BuildParam_uploadSlide, null, content, new FileInfo(filepath).Name);
}
//iFlyResult uploadresult = new JavaScriptSerializer().Deserialize(rett);
//int ok = uploadresult.ok;
//if (ok==0)
//{
int o=merge(app_id,ts,signa);
if (o==0)
{
result=getProgress(app_id, ts, signa,iszimu);
}
//}
return result;
}
//第三步:合并
//byte[] buffer,
public int merge(string app_id,string ts,string signa)
{
string ret = commonHttpHandle(app_id, ts, signa, "merge");
iFlyResult prepareresult = new JavaScriptSerializer().Deserialize(ret);
return prepareresult.ok;
}
//获取结果
//第四步:获取结果
//byte[] buffer,
public string getProgress(string app_id, string ts, string signa, bool iszimu)
{
//{"data":"{\"status\":2,\"desc\":\"音频合并完成\"}","err_no":0,"failed":null,"ok":0}
string ret = commonHttpHandle(app_id, ts, signa, "getProgress");
iFlyResult prepareresult = new JavaScriptSerializer().Deserialize(ret);
StatusResult sr = new JavaScriptSerializer().Deserialize(prepareresult.data);
while (sr.status != 9)
{
Thread.Sleep(6000);
ret = commonHttpHandle(app_id, ts, signa, "getProgress");
prepareresult = new JavaScriptSerializer().Deserialize(ret);
sr = new JavaScriptSerializer().Deserialize(prepareresult.data);
}
string rett = commonHttpHandle(app_id, ts, signa, "getResult");
iFlyResult r = new JavaScriptSerializer().Deserialize(rett);
List listresult = new JavaScriptSerializer().Deserialize>(r.data);
foreach (getResult item in listresult)
{
if (iszimu)
{
detail += Environment.NewLine + "【" + second2hh_mm_ss(item.bg) + "--" + second2hh_mm_ss(item.ed) + "】" + item.onebest + Environment.NewLine;
}
else
{
detail += item.onebest;
}
//detail += item.onebest;
}
return detail;
//if (sr.status == 9)
//{
// //{"data":"[{\"bg\":\"310\",\"ed\":\"1980\",\"onebest\":\"1801. \",\"speaker\":\"0\"},{\"bg\":\"1990\",\"ed\":\"4310\",\"onebest\":\"12345678! \",\"speaker\":\"0\"}]","err_no":0,"failed":null,"ok":0}
// string rett = commonHttpHandle(app_id, ts, signa, "getResult");
// iFlyResult r = new JavaScriptSerializer().Deserialize(rett);
// List listresult = new JavaScriptSerializer().Deserialize>(r.data);
// foreach (getResult item in listresult)
// {
// if (iszimu)
// {
// detail += Environment.NewLine + "【" + second2hh_mm_ss(item.bg) + "--" + second2hh_mm_ss(item.ed) + "】" + item.onebest + Environment.NewLine;
// }
// else {
// detail += item.onebest;
// }
// //detail += item.onebest;
// }
// return detail;
//}
//else {
// Thread.Sleep(60000);
// getProgress(app_id, ts, signa,iszimu);
//}
//return detail;
//return prepareresult.data;
}
//
public string second2hh_mm_ss(string time){
int ranlsecond = int.Parse((int.Parse(time) / 1000).ToString());
int hh = ranlsecond / 3600;
int mm = (ranlsecond-hh*3600)/60;
int ss = ranlsecond - hh * 3600-mm*60;
string result = "";
if (hh < 10)
{
result += "0";
}
result += hh+":";
if (mm < 10)
{
result += "0";
}
result += mm + ":";
if (ss < 10)
{
result += "0";
}
result +=ss ;
return result;
}
public string commonHttpHandle(string app_id, string ts, string signa,string urltype)
{
string BuildParam_merge = "&app_id=" + app_id + "&signa=" + signa + "&ts=" + ts + "&task_id=" + task_id;
HttpWebRequest request = null;
HttpWebResponse response = null;
Stream reqStream = null;
request = (HttpWebRequest)WebRequest.Create("https://raasr.xfyun.cn/api/"+urltype);
request.Method = "post"; //设置为post请求
request.ReadWriteTimeout = 5000;
request.KeepAlive = false;
request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
byte[] postData = Encoding.UTF8.GetBytes(BuildParam_merge); //使用utf-8格式组装post参数
reqStream = request.GetRequestStream();
reqStream.Write(postData, 0, postData.Length);
response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
return myStreamReader.ReadToEnd();
}
public string HttpPostMulti(string url, Dictionary postData, byte[] body, string fileName, Dictionary headers = null, string contentType = null, int timeout = 60, Encoding encoding = null)
{
string result = string.Empty;
HttpWebRequest request = null;
HttpWebResponse response = null;
Stream requestStream = null;
Stream responseStream = null;
//int SLICE_SICE = 10485760;
//byte[] slide = new byte[SLICE_SICE];
//Array.Copy(body, slide, body.Length);
//Array.Copy(body, slide, slide.Length);
try
{
request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Timeout = -1;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
//对发送的数据不使用缓存【重要、关键】
request.AllowWriteStreamBuffering = false;
request.SendChunked = true;//支持分块上传
string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
//请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"content\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
//request.AddRange(body.Length);
requestStream = request.GetRequestStream();
requestStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
requestStream.Write(body, 0, body.Length);
//requestStream.Write(slide, 0, slide.Length);
//发送其他参数
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
response = (HttpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
result = streamReader.ReadToEnd();//返回信息
streamReader.Close();
requestStream.Dispose();
responseStream.Dispose();
//Dispose(null, request, response, requestStream, responseStream);
}
catch (Exception ex)
{
return "";
}
finally
{
requestStream.Dispose();
responseStream.Dispose();
//Dispose(null, request, response, requestStream, responseStream);
}
return result;
}
}
}
调用:
var ifly = new ifly();
string result = ifly.uploadSlice(filePath, true);
string txtpath = filePath.Substring(0, filePath.Length - 3) + "txt";
translate(result, txtpath);
替换里面API涉及的关于申请用户的关键参数值