C# UWP的SpeakProgress事件处理程序?

C# UWP的SpeakProgress事件处理程序?,c#,uwp,C#,Uwp,如何使用SpeechSynthesis类在UWP下实现SpeakProgressEvent的等效功能?WPF/.NET有一个我可以钩住的事件,但是,我不知道他们在UWP框架中把这个特性隐藏在哪里?.NET SpeakProgressEvent是否以某种方式映射到UWP的MediaElement事件 // NOTE: This is a windows 10 UWP Application (Not WPF/.NET) using Windows.Media.SpeechSynthesis; us

如何使用SpeechSynthesis类在UWP下实现SpeakProgressEvent的等效功能?WPF/.NET有一个我可以钩住的事件,但是,我不知道他们在UWP框架中把这个特性隐藏在哪里?.NET SpeakProgressEvent是否以某种方式映射到UWP的MediaElement事件

// NOTE: This is a windows 10 UWP Application (Not WPF/.NET)
using Windows.Media.SpeechSynthesis;
using System.Threading.Tasks;

//XAML: <MediaElement Name="mediaElement"/>

namespace App1
{
    public sealed partial class MainPage : Page
    {
        SpeechSynthesizer            synth;

        public MainPage()
        {
            this.InitializeComponent();
            synth = new SpeechSynthesizer();

           // Doesn't Exist for UWP
            synth.SpeakProgress 
                 += new EventHandler<SpeakProgressEventArgs>
                    (synthesizer_SpeakProgress);

           // Doesn't Exist for UWP
            synth.SpeakStarted 
                 += new EventHandler<SpeakStartedEventArgs>
                    (synthesizer_SpeakStarted);

           // Doesn't Exist for UWP
            synth.SpeakCompleted 
                 += new EventHandler<SpeakCompletedEventArgs>
                    (synthesizer_SpeakCompleted);
        } //MainPage

        async Task Speak(string text)
        {
             SpeechSynthesisStream speech;
             speech = await synth.SynthesizeTextToStreamAsync(text);
             mediaElement.SetSource(speech, speech.ContentType);
        }

        void synthesizer_SpeakProgress(
               object sender, SpeakProgressEventArgs e)
        {
            //show the synthesizer's current progress 
            //labelProgress.Content = e.Text;
            //SolidColorBrush highlightColor 
            //   = new SolidColorBrush(Colors.Yellow);
            //HighlightWordInRichTextBox(
            //    richTextBox1, e.Text, highlightColor);
        }


    } //class
} //namespace
//注意:这是一个windows 10 UWP应用程序(不是WPF/.NET)
使用Windows.Media.SpeechSynthesis;
使用System.Threading.Tasks;
//XAML:
名称空间App1
{
公共密封部分类主页面:第页
{
语音合成器;
公共主页()
{
this.InitializeComponent();
synth=新的语音合成器();
//UWP不存在
合成语音进展
+=新事件处理程序
(合成器_SpeakProgress);
//UWP不存在
synth.SpeakStarted
+=新事件处理程序
(合成器_已启动);
//UWP不存在
合成器已完成
+=新事件处理程序
(合成器_已完成);
}//主页
异步任务发言(字符串文本)
{
语音合成流语音;
speech=等待合成。SynthezeTextToStreamAsync(文本);
SetSource(speech,speech.ContentType);
}
空洞合成器(
对象发送方,SpeakProgressEventArgs(e)
{
//显示合成器的当前进度
//labelProgress.Content=e.Text;
//SolidColorBrush highlightColor
//=新的SolidColorBrush(颜色为黄色);
//HighlightWordInRichTextBox(
//richTextBox1,e.文本,高亮颜色);
}
}//类
}//名称空间

这里的困难在于,当WPF
System.Speech.Synthesis.SpeechSynthesis
处理音频输出时,UWP
Windows.Media.SpeechSynthesis.SpeechSynthesis
将其结果呈现为流,然后可由
MediaElement
播放。在这种情况下,大部分元数据都会丢失,
MediaElement
不知道当前正在说哪个单词,因此它无法提供类似于
SpeakProgress
的事件

你能做什么:

首先,通过设置以下
SpeechSynthesizer
选项,确保在流合成期间维护所有元数据:

synth = new SpeechSynthesizer
{
    Options = { IncludeWordBoundaryMetadata = true, IncludeSentenceBoundaryMetadata = true }
};
请注意,
synth.synthezettexttostreamasync(…)
创建的流不是常见的
irandomaccesstream
,而是
SpeechSynthesisStream
,它提供了一些附加属性。例如,分析流的
TimedMetadataTracks
:通常,这将包含两项,一项包含单词边界元数据,另一项包含句子边界元数据

这些
TimedMetadataTrack
对象最有趣的属性可能是
Cues
:这是一个包含
Windows.Media.Core.SpeechCue
类型元素的集合,其中每个项目对应于原始文本中的一个句子/单词。每个项目包括以下信息:

  • 字符位置(检查提示的
    startpositioninput
    endpositioninput
    属性)
  • 音频位置(请参见
    StartTime
    属性)
  • 这意味着:


    遗憾的是,如前所述,没有方便的事件通知您进度,但您应该能够通过这些元数据属性检索有关当前状态/位置的必要信息。

    答案在Microsoft提供的示例文件中:


    我假设您正在尝试从流中获取viseme信息,以设置角色嘴巴的动画

    一种可能的方法是使用语音合成流线索来创建媒体标记。然后连接到媒体播放器标记到达事件

    使用CMU字典获取音素信息,然后查找与音素关联的视位

    播放媒体流时,将到达标记,然后您可以更改角色的嘴形状