Azure文本转语音REST API处理日文/俄文时返回HTTP 400错误求助
问题描述
我是一名学生,正在用Python调用Azure认知服务的文本转语音(TTS)REST API。测试Azure在线音频内容创建工具生成的日文文本「テキスト読み上げを試すのが楽しみです」(对应英文“I’m excited to try text to speech”),对应的SSML如下:
<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 xml:lang="ja-JP" xml:gender="Female" name="ja-JP-NanamiNeural">テキスト読み上げを試すのが楽しみです</voice></speak>
这段SSML在在线工具里能正常运行,但通过REST API调用时返回HTTP 400错误。不过把日文汉字替换成假名「Kisuto yomiage o tamesu no ga tanoshimidesu」后,API调用就能正常工作。
我使用的代码片段如下:
def send_text2(token,endpoint,uuid,ssml): headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/ssml+xml', 'X-Microsoft-OutputFormat': 'audio-48khz-96kbitrate-mono-mp3', 'User-Agent': 'Application for Final', 'X-ClientTraceId': uuid } vocalize_request = requests.post(endpoint, headers=headers, data=ssml) print(vocalize_request.status_code) # Retrieve mp3 data and write to file with open(f"vocalized_file-{uuid}.mp3", "wb") as binary_file: #Write bytes to file binary_file.write(vocalize_request.content)
代码处理英文、德文、意大利文都正常,所以端点和令牌没问题。俄文翻译同样会返回HTTP 400错误。
已尝试的方案:
- 将所有
xml:lang设置为“ja-JP” - 确保内容格式为UTF-8
- 移除
mstts和emo命名空间 - 不设置
Content-Length头部 - 将文本包裹在
<![CDATA[]]>中
以上尝试均无效,想知道问题原因和解决办法,我认为这不是TTS的bug,因为类似问题似乎已被解决,但我这边不设置Content-Length也没用,希望得到帮助。
可能的原因及解决方法
1. 请求体编码未明确指定UTF-8
当传递包含非欧洲语言字符(日文汉字、俄文西里尔字母)的SSML时,requests默认的字符串编码处理可能未被服务器正确识别,导致解析失败返回400。
解决办法:
- 在
Content-Type头部明确指定UTF-8编码; - 将SSML字符串编码为UTF-8字节后再传递。
修改后的代码片段:
def send_text2(token,endpoint,uuid,ssml): headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/ssml+xml; charset=utf-8', # 明确指定编码 'X-Microsoft-OutputFormat': 'audio-48khz-96kbitrate-mono-mp3', 'User-Agent': 'Application for Final', 'X-ClientTraceId': uuid } # 将SSML编码为UTF-8字节流 vocalize_request = requests.post(endpoint, headers=headers, data=ssml.encode('utf-8')) print(vocalize_request.status_code) with open(f"vocalized_file-{uuid}.mp3", "wb") as binary_file: binary_file.write(vocalize_request.content)
2. 端点与语音模型的区域不匹配
确认你使用的API端点区域支持所选的语音模型(如ja-JP-NanamiNeural、俄文语音),部分区域可能未开放特定语言模型的支持,即使在线工具正常,跨区域调用也会返回400错误。可以核对Azure认知服务语音区域支持列表,确保端点和语音模型的区域一致。
3. SSML字符转义问题
虽然你的SSML看起来无特殊字符,但某些场景下非ASCII字符在字符串传递中可能被错误转义。可以尝试直接读取本地保存的SSML文件(确保文件为UTF-8编码),以字节流形式传递给API:
with open("your_ssml_file.xml", "rb") as f: vocalize_request = requests.post(endpoint, headers=headers, data=f)
内容的提问来源于stack exchange,提问作者ekcaiki

