【问题标题】:SpeakProgress event handler for UWP?UWP 的 SpeakProgress 事件处理程序?
【发布时间】:2018-07-07 17:47:19
【问题描述】:

如何在 UWP 下使用 SpeechSynthesis 类实现等效的 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

【问题讨论】:

    标签: c# uwp


    【解决方案1】:

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

    你可以做什么:

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

    synth = new SpeechSynthesizer
    {
        Options = { IncludeWordBoundaryMetadata = true, IncludeSentenceBoundaryMetadata = true }
    };
    

    注意synth.SynthesizeTextToStreamAsync(...)创建的流不是普通的IRandomAccessStream,而是SpeechSynthesisStream,它提供了一些额外的属性。例如,分析流的TimedMetadataTracks:通常,这将包含两个项目,一个包含单词边界元数据的轨道,一个包含句子边界元数据的轨道。

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

    1. 字符位置(检查提示的StartPositionInInputEndPositionInInput 属性)
    2. 音频位置(参见StartTime 属性)

    这意味着:

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

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      我假设您正在尝试从流中获取发音嘴型信息以动画角色嘴巴。

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

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

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

      【讨论】:

        猜你喜欢
        • 2018-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2018-01-25
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多