导读:本期聚焦于小伙伴创作的《C#如何实现TTS功能?详解文本转语音的几种方法与实战》,敬请观看详情。想把一段文字直接念出来,C#里其实不需要引入笨重的第三方引擎。系统自带的语音接口就能完成基本的朗读任务,但在中文发音、异步控制和多音字处理上仍有不少细节容易被忽略。本文先说清楚System.Speech命名空间下SpeechSynthesizer的工作机制,再对比使用Windows.Media.SpeechSynthesis适配UWP与现代桌面的差异。你会看到如何切换发音人、调节语速音量,以及如何把语音流保存成wav文件。面对长时间文本合成时的线程阻塞问题,也会给出基于Task的改写方案,帮助桌面程序保持界面响应。

在C#开发中,文本转语音(TTS)是一项非常实用的功能,无论是做无障碍辅助、语音播报系统,还是游戏内的旁白生成,都可以通过几行代码快速实现。最基础的实现方式是借助.NET Framework自带的System.Speech.Synthesis命名空间,它封装了Windows操作系统的语音接口,开发者无需安装额外的语音引擎即可完成朗读。

C#如何实现TTS功能?详解文本转语音的几种方法与实战

使用SpeechSynthesizer实现基础朗读

SpeechSynthesizer是.NET中处理文本转语音的核心类,位于System.Speech.Synthesis程序集内。使用前需要在项目中添加对System.Speech的引用,如果是.NET Core或.NET 5以上版本,则需要通过NuGet安装System.Speech包。该类的实例创建后,直接调用Speak方法即可同步朗读文本,调用SpeakAsync则可异步朗读而不阻塞当前线程。

在底层,SpeechSynthesizer会调用Windows的SAPI(Speech Application Programming Interface)引擎,将输入的字符串进行分词、注音和音频合成。中文文本会被送至系统安装的中文语音包处理,如果系统未安装中文发音人,则可能出现朗读失败或乱读现象。因此部署程序时应确认目标机器已启用对应的语言包。

下面的示例展示了最简单的同步朗读与发音人切换:

using System;
using System.Speech.Synthesis;

class Program
{
    static void Main()
    {
        // 创建语音合成器实例
        using (SpeechSynthesizer synth = new SpeechSynthesizer())
        {
            // 设置音量(0-100)和语速(-10到10)
            synth.Volume = 80;
            synth.Rate = 0;

            // 列出所有已安装的发音人
            foreach (InstalledVoice voice in synth.GetInstalledVoices())
            {
                Console.WriteLine(voice.VoiceInfo.Name);
            }

            // 尝试切换为中文发音人
            synth.SelectVoice("Microsoft Huihui Desktop");

            // 同步朗读
            synth.Speak("欢迎使用C#文本转语音功能");
        }
    }
}

上述代码在控制台程序中运行时会直接通过默认音频设备播放声音。若目标系统没有名为“Microsoft Huihui Desktop”的发音人,SelectVoice会抛出ArgumentException,所以生产环境应先判断GetInstalledVoices的返回结果。同步Speak方法会卡住主线程,在WinForms或WPF中应改用SpeakAsync避免界面假死。

将语音保存为音频文件与异步控制

除了实时播放,很多场景需要把文本转成的语音保存下来,例如生成有声书片段或语音提示文件。SpeechSynthesizer提供了SetOutputToWaveFile方法,可以将合成结果直接写入WAV文件,而不会产生声音外放。这种方式特别适合批量生成静态语音资源的后台服务。

在长时间文本合成时,即便使用SpeakAsync,也希望能在UI上显示进度或允许取消。我们可以借助SpeakStartedSpeakProgressSpeakCompleted事件来监控状态。SpeakProgress事件的CharacterPosition属性能够告知当前朗读到了原文的哪个字符位置,方便做高亮联动。

以下代码演示了输出到文件并监听完成事件:

using System;
using System.Speech.Synthesis;

class TtsToFile
{
    static void Run()
    {
        SpeechSynthesizer synth = new SpeechSynthesizer();
        synth.SetOutputToWaveFile(@"C:ASRoutput.wav");
        synth.SpeakCompleted += (s, e) =>
        {
            Console.WriteLine("语音文件生成完毕");
            synth.Dispose();
        };
        synth.SpeakAsync("这是一段将被保存为Wave文件的测试语音");
    }
}

注意SetOutputToWaveFile的路径如果包含不存在的目录(如示例中的C:ASR),运行时会报错,因此写文件前应确保目录已用Directory.CreateDirectory创建。若需要MP3而非WAV,由于System.Speech不支持直接编码MP3,通常要借助NAudio等库对WAV做二次转换。

现代.NET下的UWP与Windows.Media方案

在UWP或希望脱离System.Speech依赖的现代桌面应用中,可以使用Windows.Media.SpeechSynthesis命名空间下的SpeechSynthesizer类。该接口属于Windows Runtime API,在.NET 6及以上通过Microsoft.Windows.SDK或项目启用Windows App SDK后即可使用。它的优势是能更好地适配触摸设备、后台任务,并且发音人列表与系统设置中的“语音”面板完全统一。

与旧方案不同,Windows.Media.SpeechSynthesis.SpeechSynthesizerSynthesizeTextToStreamAsync方法返回的是SpeechSynthesisStream,开发者需要自己用MediaPlayerAudioGraph播放,这种解耦设计让语音合成和播放控制更加灵活,也更容易接入混音或音效处理管道。

示例展示如何在新模型中合成并保存为文件:

using System;
using System.IO;
using System.Threading.Tasks;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;

class ModernTts
{
    public static async Task SaveAsync()
    {
        var synth = new SpeechSynthesizer();
        var stream = await synth.SynthesizeTextToStreamAsync("现代Windows接口下的语音合成");
        var file = await KnownFolders.MusicLibrary.CreateFileAsync("modern.wav");
        using (var fs = await file.OpenStreamForWriteAsync())
        {
            stream.Seek(0);
            await stream.AsStreamForRead().CopyToAsync(fs);
        }
    }
}

选用哪种方案取决于项目类型。如果是传统WinForms且只跑在内网工控机,System.Speech最省事;若是跨设备商店应用,则应优先评估Windows.Media。另外在服务器环境(如Windows Server核心版)往往没有桌面体验组件,两种方案都可能因缺少语音包而无法工作,此时要考虑云端TTS API作为补充。

C#TTSSpeechSynthesizer修改时间:2026-08-15 19:02:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。