Microsoft TTS 和 Apache HttpRequest

问题描述

我正在使用 Microsoft 认知服务并通过 Rest API 提交一些 TTS。如果我通过邮递员将下面列出的 xml 直接提交给服务,它工作正常,如果我通过我的 java 代码提交下面的 xml,我得到:

HttpResponseProxy{HTTP/1.1 400 合成失败。 StatusCode:FailedPrecondition,详细信息:SSML 解析错误:8004507A。 [服务器:openresty/1.15.8.2,日期:2021 年 6 月 7 日星期一 20:48:40 GMT,内容类型:text/xml,传输编码:分块,连接:保持活动,严格传输安全:最大-年龄=15724800; includeSubDomains] ResponseEntityProxy{[Content-Type: text/xml,Chunked: true]}}

如果我不注入 SSML,java 代码可以完美运行

<phoneme alphabet="ipa" ph="təˈmeɪtoʊ"> tomato </phoneme>

我唯一能想到的错误是身体的实体。对于邮递员,这是一个原始的身体。我还应该为 java 中的 body 做些什么吗?

HttpPost httpPost = new HttpPost("https://eastus.tts.speech.microsoft.com/cognitiveservices/v1");
httpPost.setEntity(new StringEntity(xml));
httpPost.addHeader("Content-Type","application/ssml+xml");
httpPost.addHeader("Ocp-Apim-Subscription-Key",key);
httpPost.addHeader("X-Microsoft-OutputFormat","audio-48khz-192kbitrate-mono-mp3");
org.apache.http.HttpResponse resp = httpclient.execute(httpPost);
<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US"><voice name="en-US-JennyNeural"><mstts:express-as style="assistant"><prosody rate="5%" pitch="13%">
we can totally get a <phoneme alphabet="ipa" ph="təˈmeɪtoʊ"> tomato </phoneme> made for you right Now!</prosody></mstts:express-as></voice></speak>

解决方法

尽量使用官方推荐的示例代码,使用HttpsURLConnection发送http请求。

Sample code in github.

HttpsURLConnection webRequest = HttpsConnection.getHttpsConnection(ttsServiceUri);
webRequest.setDoInput(true);
webRequest.setDoOutput(true);
webRequest.setConnectTimeout(5000);
webRequest.setReadTimeout(15000);
webRequest.setRequestMethod("POST");

webRequest.setRequestProperty("Content-Type","application/ssml+xml");
webRequest.setRequestProperty("X-Microsoft-OutputFormat",outputFormat);
webRequest.setRequestProperty("Authorization","Bearer " + accessToken);
webRequest.setRequestProperty("X-Search-AppId","07D3234E49CE426DAA29772419F436CA");
webRequest.setRequestProperty("X-Search-ClientID","1ECFAE91408841A480F00935DC390960");
webRequest.setRequestProperty("User-Agent","TTSAndroid");
webRequest.setRequestProperty("Accept","*/*");

String body = XmlDom.createDom(locale,genderName,voiceName,textToSynthesize);
byte[] bytes = body.getBytes();
webRequest.setRequestProperty("content-length",String.valueOf(bytes.length));
webRequest.connect();
......