来自列表框 (c#') 的 UWP 文本到语音转换

本文关键字:UWP 文本 转换 语音 列表 | 更新日期: 2023-09-27 18:35:07

我正在尝试实现文本到语音转换以按顺序从列表框中读取项目。最初,程序将同时读出彼此重叠的所有项目。经过研究,我添加了一个 MediaEnd 处理程序,但我只能设法读出第一项,只有实现了这一点。我将不胜感激任何帮助。

    private async void ToSpeechButton_Click(object sender, RoutedEventArgs e)
    {
            MediaElement mediaElement = new MediaElement();
            var tsc = new TaskCompletionSource<bool>();
            mediaElement.MediaEnded += (o, f) => { tsc.TrySetResult(true); };
            mediaElement.Play();
        foreach (var item in ListBox.Items)
        {   
            readText(item.ToString());
            await tsc.Task;
        }                
    }

    private async void readText(string mytext)
    {
        MediaElement mediaplayer = new MediaElement();
        using (var speech = new SpeechSynthesizer())
        {
            speech.Voice = SpeechSynthesizer.AllVoices.First(gender => gender.Gender == VoiceGender.Female);
            SpeechSynthesisStream stream = await speech.SynthesizeTextToStreamAsync(mytext);
            mediaplayer.SetSource(stream, stream.ContentType);
            mediaplayer.Play();
        }
    } 

来自列表框 (c#') 的 UWP 文本到语音转换

如果您阅读SpeechSynthesizer类的文档,您会发现有两种方法可以将文本转换为语音。一个是你已经使用的,合成文本到流异步方法,此方法从字符串异步生成语音输出。

另一个是 SynthesizeSsmlToStreamAsync 方法,此方法从包含语音合成标记语言 (SSML) 的字符串异步生成语音输出。

在这种情况下,我们可以使用SynthesizeSsmlToStreamAsync方法在每个项目之间暂停语音,例如:

private string allitem;
private void ToSpeechButton_Click(object sender, RoutedEventArgs e)
{
    foreach (var item in listBox.Items)
    {
        var txt = item as ListBoxItem;
        allitem += txt.Content.ToString() + "<break time='500ms'/>";
    }
    readText(allitem);
}
private async void readText(string mytext)
{
    MediaElement mediaplayer = new MediaElement();
    using (var speech = new SpeechSynthesizer())
    {
        speech.Voice = SpeechSynthesizer.AllVoices.First(gender => gender.Gender == VoiceGender.Female);
        string ssml = @"<speak version='1.0' " + "xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'>" + allitem + "</speak>";
        SpeechSynthesisStream stream = await speech.SynthesizeSsmlToStreamAsync(ssml);
        mediaplayer.SetSource(stream, stream.ContentType);
        mediaplayer.Play();
    }
}

在每个项目之后将此<break time='500ms'/>字符串组合在一起,语音将在每个项目后暂停 500 毫秒。