当你需要在应用中快速集成自然流畅的语音输出时,微软Azure的文本转语音(TTS)服务是个不错的选择。但很多开发者在实际调用过程中,常常被官方文档的复杂性和网上零散的代码示例困扰。本文将提供一个开箱即用的Python解决方案,让你在5分钟内完成从配置到语音生成的全流程。
在开始编写代码前,我们需要先完成Azure语音服务的资源创建。登录Azure门户后:
eastus、westus等提示:建议将密钥保存在环境变量中,避免硬编码在脚本里。可以通过命令
export SPEECH_SERVICE_KEY='你的密钥'设置。
下面是一个封装好的Python类,包含了语音合成的核心功能:
python复制import os
import requests
import time
from xml.etree import ElementTree
class AzureTTS:
def __init__(self, subscription_key, region='eastus'):
self.subscription_key = subscription_key
self.region = region
self.access_token = None
def _get_token(self):
"""获取10分钟有效的访问令牌"""
token_url = f"https://{self.region}.api.cognitive.microsoft.com/sts/v1.0/issueToken"
headers = {'Ocp-Apim-Subscription-Key': self.subscription_key}
response = requests.post(token_url, headers=headers)
self.access_token = response.text
def synthesize(self, text, voice_name='en-US-JennyNeural', output_format='riff-24khz-16bit-mono-pcm'):
"""合成语音并保存为WAV文件"""
if not self.access_token:
self._get_token()
endpoint = f"https://{self.region}.tts.speech.microsoft.com/cognitiveservices/v1"
headers = {
'Authorization': f'Bearer {self.access_token}',
'Content-Type': 'application/ssml+xml',
'X-Microsoft-OutputFormat': output_format,
'User-Agent': 'python-tts-client'
}
ssml = f"""
<speak version='1.0' xml:lang='en-US'>
<voice name='{voice_name}'>
{text}
</voice>
</speak>
"""
response = requests.post(endpoint, headers=headers, data=ssml)
if response.status_code == 200:
timestamp = time.strftime("%Y%m%d-%H%M%S")
filename = f"output_{timestamp}.wav"
with open(filename, 'wb') as f:
f.write(response.content)
return filename
else:
raise Exception(f"请求失败: {response.status_code} - {response.text}")
# 使用示例
if __name__ == "__main__":
# 从环境变量获取密钥
key = os.getenv('SPEECH_SERVICE_KEY')
if not key:
raise ValueError("请设置SPEECH_SERVICE_KEY环境变量")
tts = AzureTTS(key)
result_file = tts.synthesize("Hello, this is a test of Azure Text-to-Speech service.")
print(f"语音文件已生成: {result_file}")
Azure提供了多种语言的多种声音,可以通过以下方式查询可用语音列表:
python复制def list_voices(self):
"""获取可用语音列表"""
self._get_token()
endpoint = f"https://{self.region}.tts.speech.microsoft.com/cognitiveservices/voices/list"
headers = {'Authorization': f'Bearer {self.access_token}'}
response = requests.get(endpoint, headers=headers)
return response.json()
常见的中文语音包括:
zh-CN-YunxiNeural(男声)zh-CN-XiaoxiaoNeural(女声)Azure支持多种音频输出格式,以下是常见格式的对比:
| 格式名称 | 采样率 | 位深 | 声道 | 适用场景 |
|---|---|---|---|---|
| riff-16khz-16bit-mono-pcm | 16kHz | 16bit | 单声道 | 普通质量,文件较小 |
| riff-24khz-16bit-mono-pcm | 24kHz | 16bit | 单声道 | 推荐质量,平衡大小与音质 |
| audio-16khz-128kbitrate-mono-mp3 | 16kHz | - | 单声道 | MP3格式,适合网页使用 |
| webm-24khz-16bit-mono-opus | 24kHz | 16bit | 单声道 | WebM格式,高效压缩 |
当遇到401错误时,按以下步骤检查:
Authorization格式是否正确asyncio和aiohttppython复制import asyncio
import aiohttp
async def async_synthesize(text):
async with aiohttp.ClientSession() as session:
# 异步获取令牌
token_url = f"https://{self.region}.api.cognitive.microsoft.com/sts/v1.0/issueToken"
async with session.post(token_url, headers=headers) as resp:
token = await resp.text()
# 异步合成语音
endpoint = f"https://{self.region}.tts.speech.microsoft.com/cognitiveservices/v1"
async with session.post(endpoint, headers=headers, data=ssml) as resp:
return await resp.read()
Azure的神经语音支持多种情感表达,只需在SSML中添加style参数:
xml复制<voice name='zh-CN-XiaoxiaoNeural' style='cheerful'>
今天天气真好,我们出去玩吧!
</voice>
可用风格包括:cheerful、sad、angry等。
Azure TTS支持在同一段SSML中混合多种语言:
xml复制<speak version='1.0' xml:lang='en-US'>
<voice name='en-US-JennyNeural'>
Hello, 你好吗?
</voice>
</speak>
在实际项目中,我发现最实用的技巧是创建一个语音配置的JSON文件,方便快速切换不同场景下的语音参数:
json复制{
"greeting": {
"voice": "zh-CN-YunxiNeural",
"style": "friendly",
"rate": "medium"
},
"warning": {
"voice": "zh-CN-YunyangNeural",
"style": "serious",
"rate": "slow"
}
}