win10 uwp 选择文本转语音的机器人

在 UWP 里,可以非常方便将某个文本转换为音频语音,转换时,将会根据输入的内容以及本机所安装的语言库选择一位机器人帮忙将输入的文本转换为语音。本文来告诉大家如何切换文本转语音的机器人,例如从默认的女声转换为男声,如选择 Kangkang 或 Huihui 等特定机器人帮助转换语音

刚好从卢老师那里接了一个任务,录制 dotnet 的 20 周年的祝贺视频。然而过年生活太好的我嗓子沙哑了,于是本来普通话就说得不标准的我开始寻求起代码之神的帮助,好在翻到了自己的博客,找到了 win10 uwp 字符文本转语音声音文件方法 这篇博客,开始按照此方式录制,却发现了默认语音不是 Kangkang 机器人的。在 UWP 里的 SpeechSynthesizer 的 Voice 属性可以让咱设置所采用的机器人,但是此 VoiceInformation 对象却不能创建,不得不赞叹一下 API 设计者的强大

按照我也不知道哪学到的知识,文本转语音所采用的 TTS 需要依靠本机所安装的语言库,可以在注册表的 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech_OneCore\Voices\Tokens\ 路径下获取到当前本机所安装的语言库。也就是说即使自己开发了此功能,在用户端能否使用,完全需要取决于用户端是否安装了对应的语言包

在 UWP 下,不提供 VoiceInformation 对象的创建方法,必须通过 SpeechSynthesizer 的 AllVoices 属性获取本机已安装的机器人,从里面挑选一个用来设置。例如以下代码就是挑选 Kangkang 机器人用来帮忙转文本

using Windows.Media.SpeechSynthesis;

            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                VoiceInformation voice = SpeechSynthesizer.AllVoices.FirstOrDefault(v => v.Id.Contains("zhCN_KangkangM"));
                synthesizer.Voice = voice;
            }

以上的 AllVoices 属性是静态属性,获取时,即可拿到本机所有的已安装的机器人,可以自己遍历。但是由于这是一个 COM 对象,在 VS 调试使用相对不方便,推荐大家自己写一次循环获取一下

接下来的转换文本为语音的方法就之前博客的差不多,代码如下

        private async void Button_OnClick(object sender, RoutedEventArgs e)
        {
            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                VoiceInformation voice = SpeechSynthesizer.AllVoices.FirstOrDefault(v => v.Id.Contains("zhCN_KangkangM"));
                synthesizer.Voice = voice;
                var text = InputTextBox.Text;
                try
                {
                    SpeechSynthesisStream stream = await synthesizer.SynthesizeTextToStreamAsync(text);
                    using (stream)
                    {
                        FileSavePicker savePicker = new FileSavePicker();
                        savePicker.FileTypeChoices.Add("音频", new[] { ".wav" });

                        var result = await savePicker.PickSaveFileAsync();
                        var wordFile = result;

                        using (var wordFileStream = await wordFile.OpenStreamForWriteAsync())
                        {
                            await stream.AsStreamForRead().CopyToAsync(wordFileStream);
                        }
                    }
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception);
                }
            }
        }

界面代码如下

    <Grid>
        <TextBox x:Name="InputTextBox" Margin="10,10,10,100" HorizontalTextAlignment="Left" HorizontalAlignment="Left" TextWrapping="Wrap"/>
        <Button Margin="10,10,10,10" VerticalAlignment="Bottom" Content="文字转语音" Click="Button_OnClick"></Button>
    </Grid>

本文代码放在 github 欢迎小伙伴访问

更多请看 SpeechSynthesizer 类 (System.Speech.Synthesis) Microsoft Docs

posted @ 2022-03-03 08:30  lindexi  阅读(427)  评论(0编辑  收藏  举报