zoukankan      html  css  js  c++  java
  • WPF,Silverlight与XAML读书笔记第四十二 多媒体支持之音、视频和语音

    说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

    音频

    在WPF中播放音频有以下几种方式:

    • SoundPlayer
    • MediaPlayer
    • SoundPlayerAction
    • MediaElement和MediaLine

    SoundPlayer

        SoundPlayer是随.NET Framework 2.0一起发布的类,其实对Win32 PlaySound API的一个封装,这是在WPF中播放声音最简单的方式,所以其也有一系列限制。

    • 仅支持wave格式音频文件
    • 不支持同时播放多个音频
    • 无法控制音量

    下面是一段简单的示例:

    1 SoundPlayer player = new SoundPlayer("lily.wav"); 
    2 player.Play();

        SoundPlayer构造函数接受一个文件名或一个URL。上面代码中调用的Play方法将会在另一个线程上异步播放声音。另一个方法PlaySync在当前线程上播放该声音,PlayLooping会实现循环异步播放声音,直至显式调用Stop方法停止为止。

        默认情况下,SoundPlayer会在第一次调用Play相关方法时才加载文件,但由于文件可能存在于网络上,由于缓冲文件等原因可能造成播放前的停顿。解决这个问题,我们可以手动调用Load或LoadAsync方法提前加载文件。

        使用位于System.Media下的SystemSounds类可以播放一些系统声音。SystemSounds包含很多类,如Beep,Exclamation,Question等表示不同的系统声音,这些属性都是SystemSound类型,可以直接调用它们的Play方法异步非循环的播放声音。

    SoundPlayerAction

        这个类最大的作用就是可以将SoundPlayer无缝的融入XAML,在不用编写C#代码的情况下播放声音。SoundPlayerAction派生自TriggerAction,我们可以直接使用它来设置Trigger的Actions属性。下面的例子中我们给按钮添加一个事件触发器,实现在点击按钮时播放一段声音。

     1 <Button>A Button With Sounds
     2     <Button.Triggers>
     3         <EventTrigger RoutedEvent="Button.Click">
     4             <EventTrigger.Actions>
     5                 <SoundPlayerAction Source="click.wav"/>
     6             </EventTrigger.Actions>
     7         </EventTrigger>
     8         <EventTrigger RoutedEvent="Button.MouseEnter">
     9             <EventTrigger.Actions>
    10                 <SoundPlayerAction Source="hover.wav"/>
    11             </EventTrigger.Actions>
    12         </EventTrigger>
    13     </Button.Triggers>
    14 </Button>

    同样使用这个类有更多的限制,你甚至不能循环播放或预先加载声音。

    MediaPlayer

        这个类位于System.Windows.Media命名空间,它是WPF中一个可选的较高级的音频播放功能工具。这个类基于Windows Media Player构建,支持Windows Media Player所支持的多种音频格式(当然其也支持视频,在介绍WPF中视频一节还会再次深入讲述这个类)。通过多个Media Player的实例,可以实现音频同时播放(一个实例同一时间只能播放一个文件)。float类型的Volumn属性用于调整音量,范围由0到1,默认值是0.5。下面列举更多的音频控制方式:

    • 当CanPause属性为true时,可以通过Pause方法停止音频。
    • 设置IsMuted为true可以将音频静音
    • 通过设置Balance来调整左右扬声器平衡
    • 通过设置SpeedRatio来改变支持变速的音频格式的音频的速度,这个值即表示速度变化的倍数,默认值为1.0
    • 通过NaturalDuration属性可以得到音频文件的长度,Position属性可以得到当前播放的位置。

    照例给出一段简单的示例代码:

    1 MediaPlayer player = new MediaPlayer();
    2 player.Open(new Uri("moon.wma", UriKind.Relative));
    3 player.Play();

    如代码所示,我们用Open打开文件,Play播放文件。相应的还有Pause,Stop和Close来控制文件播放。

    视频

        WPF对视频的支持也是通过前面介绍的Media Player,MediaElement级MediaTimeLine来实现。所以Windows Media Player所支持的视频格式如wmv,avi,mpg都可以在WPF中使用。但在程序中使用MediaPlayer类时,要保证最终运行的系统中安装有Windows Media Player 10或更高版本。有关Media Element的话题同样见多媒体控件部分。

    语音

    .NET Framework中新增了一系列语音相关的API,位于System.Speech命名空间下,这些类主要支持语音识别语音合成,这套API并没有为WPF做特殊处理,即没有添加依赖属性,路由事件等特性,所以我们只能在C#代码中使用这些类。

    语言合成由Microsoft SAPI SDK来支持。SAPI SDK中包含了几套不同的语音,使合成语音有不同的效果。仍然通过一段代码来展示语音合成。

    1 SpeechSynthesizer synthesizer = new SpeechSynthesizer();
    2 synthesizer.Speak("测试语音合成");

    要使这段代码工作,需要引用System.Speech.dll,并引用System.Speech.Synthesis命名空间。合成语音的声音、速度和音量可以在控制面板语音合成项中设置。

    使用SpeakAsync方法可以异步播放合成语言,此时也可以通过设置SpeechSynthesizer的Rate和Volumn属性来改变声音的速度和音量。Rate的范围是-10到10,而Volumn的范围是0到100。通过调用SpeakAsyncCancelAll取消处于等待状态的语音合成。

    调用SelectVoice方法可以改变合成语音使用的声音,如代码:

    1 synthesizer.SelectVoice("Microsoft Sam");

    或者通过指定性别和年龄来选择一个声音,如:

    1 synthesizer.SelectVoiceByHints(VoiceGender.Female,VoiceAge.Senior);

    上面介绍的所有例子,转换后的语音会默认输出到扬声器,通过以下代码你可以将其输出到一个.wav文件:

    1 synthesizer.SetOutputToWaveFile(@"C:\mySpeech.wav");

    而如下的代码可以将输出恢复到扬声器:

    1 synthesizer.SetOutputToDefaultAudioDevice();

        新的Speech API支持W3C标准 – 语言合成标记语言SSML。通过SSML,可以将复杂的语言封装在一个单独的模块中。通过调用SpeakSsml和SpeakSsmlAsync方法可以向SpeechSynthesizer传入SSML内容,SSML是标准的XML格式文件,我们可以通过PromptBuilder以编程方式轻松的构件SSML。下面是一段PromptBuilder的使用示例:

     1 //构造PromptBuilder
     2 PromptBuilder promptBuilder = new PromptBuilder();
     3 //普通文本
     4 promptBuilder.AppendText("A common text Line");
     5 //逐字读出每一个字母
     6 promptBuilder.AppendTextWithHint("WPF", SayAs.SpellOut);
     7 //如下可以更好的阅读一个时间
     8 promptBuilder.AppendTextWithHint(DateTime.Now.ToString("hh:mm"), SayAs.Time);
     9 //停顿
    10 promptBuilder.AppendBreak(new TimeSpan(0, 0, 2));
    11 //单独设置一段文本的语音效果,也可使文本形成段落效果
    12 promptBuilder.StartVoice("Microsoft Sam");
    13 promptBuilder.StartStyle(new PromptStyle(PromptRate.ExtraFast));
    14 promptBuilder.AppendText("A special text line");
    15 promptBuilder.EndStyle();
    16 promptBuilder.EndVoice();
    17 //甚至可以这样播放一段SSML
    18 promptBuilder.AppendAudio("sample.wav");
    19 //传入SpeechSynthesizer
    20 SpeechSynthesizer synthesizer = new SpeechSynthesizer();
    21 synthesizer.SpeakAsync(promptBuilder);

    如代码,我们将PromptBuilder对象直接传给Speak/SpeakAsync中接受PromptBuilder的重载。通过PromptBuilder的ToXml()方法,我们可以得到以xml表示的SSML。作为一个W3C标准XML格式的SSML可以很方便的用于.NET以外的平台。

    Speak与SpeakAsync还有一个接受FilePrompt的重载,通过这个重载我们可以方便的将多种格式的文件传入SpeechSynthesizer,下面代码展示了部分FilePrompt的构建:

    1 synthesizer.SpeakAsync(new FilePrompt("text.txt", SynthesisMediaType.Text)); 
    2 synthesizer.SpeakAsync(new FilePrompt("content.ssml", SynthesisMediaType.Ssml)); 
    3 synthesizer.SpeakAsync(new FilePrompt("sound.wav", SynthesisMediaType.WaveAudio));

    这里我们看到了第二种实现在文本转语言中播放wav的方法。

    语音识别

    语音识别与上文语言合成进行恰好相反的工作,其由音频中提取语言,并将其转换为文本,要使用语音识别需要计算机中安装有语音识别引擎,Windows Vista自带了一个语音识别引擎,Office Xp之后的版本也带有一个语音识别引擎。

    要在代码中实现语音识别也要先添加对System.Speech.dll引用,不同的是这里要引用System.Speech.Recognition命名空间。下面代码给出一个最基本的使用的范例:

    1 SpeechRecognizer recognizer = new SpeechRecognizer(); 
    2 recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);

    当语音被识别后,事件被触发,回调函数被调用,在其中可以处理识别到的文本:

    1 void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    2 {
    3     textBox.Text += e.Result.Text;
    4 }

    提示:在一个系统上第一次使用语音识别时要先完成一个语音识别向导,另外,在Windows Vista以上版本中,语音识别被集成到任何一个可以获取输入的文本框(WPF或WinForm等程序中的)中,只需要对着麦克风讲话系统就会将识别结果填入文本框中。

     

    使用SRGS

        语音识别规范(SRGS – Speech Recognition Grammar Specification)是W3C标准,你可以定义一个SRGS语法,通过其方便SpeechRecognizer捕获一些有效的输入,并忽略无意义的结果。SRGS也被定义成标准的XML格式,在.NET中使用SRGS,我们需要先构造一个SrgsDocument对象(所有SRGS相关的对象都定义于System.Speech.Recognition.SrgsGrammar命名空间中),下面的代码中我们定义了一个SrgsDocument并将其传入SpeechRecognizer:

    1 SpeechRecognizer recognizer = new SpeechRecognizer(); 
    2 SrgsDocument doc = new SrgsDocument("grammar.xml"); 
    3 recognizer.LoadGrammar(new Grammar(doc));

    上面的例子中,Srgs来自xml文件,我们也可以在内存中定义并使用SRGS。下面的代码中我们定义了一个SrgsDocument,这个文档表示由输入音频中匹配stop和go两条命令。

    1 SpeechRecognizer recognizer = new SpeechRecognizer();
    2 SrgsDocument doc = new SrgsDocument();
    3 SrgsRule command = new SrgsRule("command",new SrgsOneOf("stop","go"));
    4 doc.Rules.Add(command);
    5 doc.Root = command;
    6 recognizer.LoadGrammar(new Grammar(doc));

    使用GrammarBuilder

        如同我们可以使用PromptBuilder方便的构建SSML,.NET中也提供了一个GrammarBuilder对象来定义SRGS;以解决手工编写SRGS xml或使用SrgsGrammar API定义SRGS都很麻烦的问题,下面的代码使用GrammerBuilder实现了与上面代码等价的功能:

    1 SpeechRecognizer recognizer = new SpeechRecognizer();
    2 GrammarBuilder builder = new GrammarBuilder(new Choices("stop","go"));
    3 recognizer.LoadGrammar(new Grammar(builder));

    VideoBrush

    通过使用视频刷可以对一个区域使用视频进行填充,这个画刷SourceName的值需要设置为一个MediaElement控件的x:Name属性。这个MediaElement用来加载视频,我们需要其隐藏并不响应任何鼠标事件,这可以通过将MediaElement的透明度设置为0并将IsHitTestVisible属性设置为false来做到。在加载视频后我们可以通过Stretch等属性控制视频刷的效果。

    下面的示例中,我们通过视频刷绘制文本框的前景色

    1 <TextBlock FontFamily="Courier New" FontSize="72" FontWeight="Bold" TextWrapping="Wrap" Text="Hello">
    2     <TextBlock.Foreground>
    3         <VideoBrush SourceName="vid" />
    4     </TextBlock.Foreground>
    5 </TextBlock>

    关于MediaElement,其对音频及视频的支持统一放到控件之多媒体控件一节介绍

    本文完

    参考:

    《WPF揭秘》

  • 相关阅读:
    用Python完成一个汇率转换器
    鸿蒙如何用JS开发智能手表App
    鸿蒙如何用JS开发智能手表App
    SAP Spartacus SplitViewComponent Migration 的一个具体例子
    SAP Spartacus B2B 页面 Popover Component 的条件显示逻辑
    SAP Spartacus 升级时关于 schematics 的更新
    SAP Spartacus B2B 页面 Disable 按钮的显示原理
    SAP Spartacus B2B 页面 Disable Confirmation 对话框的显示原理
    通过 Feature Level 动态控制 SAP Spartacus 的页面显示
    SAP Commerce Cloud Build Manifest Components
  • 原文地址:https://www.cnblogs.com/lsxqw2004/p/4632188.html
Copyright © 2011-2022 走看看