深度优先

这个家伙好懒,除了文章什么都没留下

0%

【DIY】调用微软语音服务

自定义语音合成 可 参考:https://mp.weixin.qq.com/s/THFmz4uNpb0lNYWshaZ2qQ

合成微软语音晓晓 可 参考:https://www.cnblogs.com/viter/p/10685402.html

图灵聊天机器人API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class TulingHelper
{
private const string HOST = "http://openapi.tuling123.com/openapi/api/v2";
private static readonly Logger logger = LogManager.GetCurrentClassLogger();

public static async Task<string> RequestTuling(string text)
{
try
{
using (var httpClient = new HttpClient())
{
var body = "{'reqType':0,'perception': {'inputText': {'text': '" + text + "'}},'userInfo': {'apiKey': '*****','userId': '267842'}}";
var request = new HttpRequestMessage()
{
Method = HttpMethod.Post,
RequestUri = new Uri(HOST),
Content = new StringContent(body, Encoding.UTF8)
};

var response = await httpClient.SendAsync(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
Console.WriteLine("The Response {0}", response.StatusCode);
return null;
}
var responseString = await response.Content.ReadAsStringAsync();
var obj = JObject.Parse(responseString);
return (string)obj["results"][0]["values"]["text"];
}
}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
return "出错了";
}
}
}

微软语音合成API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class VoicesHelper
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();

private const string TOKEN_URI = "https://southeastasia.api.cognitive.microsoft.com/sts/v1.0/issuetoken";
private const string SUB_KEY = "*****";
private const string HOST = "https://southeastasia.voice.speech.microsoft.com/cognitiveservices/v1?deploymentId=***";
private const string RESOURCE_NAME = "SpeechSerivce";

public static async Task<string> GetTokenAsync()
{
try
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", SUB_KEY);
var builder = new UriBuilder(TOKEN_URI);
var result = await httpClient.PostAsync(builder.Uri.AbsoluteUri, null);
return await result.Content.ReadAsStringAsync();
}

}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
return "出错了";
}
}

public static async Task RequestSSML(string authToken, string text, string fileName)
{
try
{
using (var httpClient = new HttpClient())
{
var body = "<speak xmlns=\"http://www.w3.org/2001/10/synthesis\" xmlns:mstts=\"http://www.w3.org/2001/mstts\" version=\"1.0\" xml:lang=\"zh-CN\"><voice name=\"xixi\">" + text + "</voice></speak>";
var request = new HttpRequestMessage()
{
Method = HttpMethod.Post,
RequestUri = new Uri(HOST),
Content = new StringContent(body, Encoding.UTF8, "application/ssml+xml")
};
request.Headers.Add("Authorization", "Bearer " + authToken);
request.Headers.Add("Connection", "Keep-Alive");
request.Headers.Add("User-Agent", RESOURCE_NAME);
request.Headers.Add("X-Microsoft-OutputFormat", "riff-24khz-16bit-mono-pcm");

var response = await httpClient.SendAsync(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
Console.WriteLine("The Response {0}", response.StatusCode);
return;
}
using (var stream = await response.Content.ReadAsStreamAsync())
{
stream.Position = 0;
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
await stream.CopyToAsync(fs);
fs.Close();
}
}
}
}
catch (Exception ex)
{
logger.Error(ex, ex.Message);
}
}
}

调用这两个API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[HttpPost]
public IActionResult Voices(Context context)
{
logger.LogError(520, $"问:{ context.body}");
var text = TulingHelper.RequestTuling(context.body).ConfigureAwait(false).GetAwaiter().GetResult();
logger.LogError(521, $"答:{text}");

var result = VoicesHelper.GetTokenAsync().ConfigureAwait(false).GetAwaiter();
string token = result.GetResult();

string fileName = $"/voiceswav/{Guid.NewGuid().ToString()}.wav";
var task1 = VoicesHelper.RequestSSML(token, text, $"./wwwroot{fileName}");
task1.ConfigureAwait(false).GetAwaiter().GetResult();
return Ok(fileName);
}