System.Speech.Synthesis 是 Windows 桌面首选基础 TTS 方案,依赖本地语音引擎且仅限 Windows;Azure SDK 适合高音质云 TTS,需注意配额与网络容错;WebView2 调用 Web Speech API 为轻量替代方案,受限于 Edge 语音支持与系统权限。

用 System.Speech.Synthesis 实现基础 TTS(Windows 桌面首选)
这是 .NET Framework 和 .NET 5+(Windows)上最直接、无需第三方依赖的方案,底层调用 Windows Speech API,语音自然度尚可,适合本地桌面应用。
常见错误:在 .NET Core / .NET 5+ 跨平台项目中直接引用该命名空间却未确认运行环境——System.Speech 仅支持 Windows,Linux/macOS 下会抛出 PlatformNotSupportedException。
- 必须确保目标机器已安装对应语言的 Windows TTS 引擎(如中文需“微软张凯”或“晓晓”等语音包,可通过「设置 → 时间和语言 → 语音」检查)
- 初始化后建议先调用
synth.GetInstalledVoices()列出可用语音,避免硬编码voice.Name导致找不到语音时静音 - 若需暂停/继续,用
synth.Pause()/synth.Resume();但注意它不支持精确到毫秒的中断,仅适用于粗粒度控制 - 示例关键片段:
var synth = new SpeechSynthesizer(); synth.SelectVoice("Microsoft Server Speech Text to Speech Voice (zh-CN, XiaoxiaoNeural)"); // 注意名称需与 GetInstalledVoices() 返回一致 synth.Speak("你好,世界");
用 Azure Cognitive Services Speech SDK 做云 TTS(高音质、多语种、需联网)
当需要更自然的神经语音(如 Xiaoxiao-Neural)、实时流式合成、SSML 控制停顿/语速/情感,或跨平台部署时,这是实际项目中最推荐的路径。
容易踩的坑:误以为免费额度永久有效——Azure 免费层限每月 0.5 百万字符,超量后请求直接返回 403 Forbidden 或 429 Too Many Requests,且错误信息不直观。
- 必须显式设置
SpeechConfig.SpeechSynthesisVoiceName,例如"zh-CN-XiaoxiaoNeural",不能只靠区域(zh-CN)自动匹配 - 合成结果默认为 WAV,若需 MP3,得用
AudioConfig.FromStreamOutput()+ 手动编码,SDK 不内置 MP3 封装 - 离线不可用,网络抖动会导致
SpeechSynthesisResult.Status == CancellationReason.Error,务必检查result.Reason和result.ErrorDetails - 初始化时传入的是订阅密钥 + 区域(如
"eastasia"),不是 endpoint URL;endpoint 错误会导致InvalidRegion类似错误
用 Microsoft Edge WebView2 调用 Web Speech API(轻量、免部署引擎)
适用于 WinForms/WPF 应用中不想引入大 SDK、又需要比 System.Speech 更现代语音的场景。本质是嵌入浏览器,调用 window.speechSynthesis。
关键限制:语音质量取决于系统 Edge 浏览器支持的语音列表,Win10/11 默认只有基础语音,高级神经语音需手动安装语言包并重启 Edge 进程才生效。
- WebView2 必须加载完成(
CoreWebView2InitializationCompleted事件触发后)才能执行 JS 注入,否则speechSynthesis.getVoices()返回空数组 - JS 中调用
speechSynthesis.speak()后无法直接 await 完成,需通过onend事件回调通知 C# 层 - 不支持 SSML,仅能传纯文本;中文需确保页面
,否则可能发音生硬 - 首次调用前,用户必须已在系统设置中开启「语音识别」权限(设置 → 隐私 → 语音),否则静音无报错
为什么不用 NAudio + 手动拼接 WAV?
有开发者试图用 NAudio 生成 PCM 数据再合成语音,这条路几乎走不通——TTS 不是音频拼接,而是从文本经声学模型生成波形。强行拆解会陷入音素对齐、韵律建模、频谱转换等底层问题,远超一般业务需求范围。
真正需要自定义音频流的场景(如边合成边播放、低延迟播控),应优先选 Azure SDK 的 SpeechSynthesizer.StartSpeakingToStreamAsync(),它返回 AudioDataStream 可逐块读取,而非自己造轮子。
神经语音的 WaveNet 模型输出对采样率、位深、声道数有严格要求,随便改 WaveFormat 参数会导致破音或无声,这类细节在公开文档里藏得很深,调试成本远高于换方案。


















