一、WPF中,最简单最容易播放音频的方式是使用SoundPlayer类。它是.NET Framework 2.0的一部分,是对Win32 PlaySound API的封装。
它具有以下限制:
1)仅支持.wav音频文件;
2)不支持同时播放多个音频(任何新播放的操作将终止当前正在播放的);
3)无法控制声音的音量;
下面的代码展示了如何使用SoundPlayer播放声音:
SoundPlayer player = new SoundPlayer("BLOW.WAV");
player.Play();
传递给SoundPlayer构造函数的字符串可以是本地的一个文件名,也可以是网络上的文件。调用Play方法将异步播放声音。如果想同步播放声音,可以使用PlaySync方法。当然,想异步循环播放,可以使用PlayLooping方法,直到你调用Stop或重新播放一个新的声音为止。
需要说明的是,声音文件直到第一次播放时才会被加载。如果声音文件的加载需要很长的时间,例如从网络来,使用同步播放,会导致UI死掉。出于这个原因考虑,SoundPlayer类也定义了Load和LoadAsync方法以便在第一次播放之前提前加载声音文件。
如果你想播放系统声音,但记不住他们的文件名,可以用SystemSounds类中的一些静态属性:Asterisk,Beep,Exclamation,Hand,Question。每个类型都有自己的Play方法,用来异步播放系统声音。
二、使用WPF专用的MediaPlayer类。它是基于Windows Media Player构建起来的,因此,只要是Windows Media Player支持的格式,它都能播放(包括视频)。
MediaPlayer具有以下特性供你使用:
1)可以同时播放多个声音(创建多个MediaPlayer对象);
2)可以调整音量(Volume属性);
3)可以使用Play,Pause,Stop等方法进行控制;
4)可以设置IsMuted属性为True来实现静音;
5)可以用Balance属性来调整左右扬声器的平衡;
6)可以通过SpeedRatio属性控制音频播放的速度;
7)可以通过NaturalDuration属性得到音频的长度,通过Position属性得到当前播放进度;
8)可以通过Position属性进行Seek;
使用MediaPlayer播放音频文件如下:
MediaPlayer player = new MediaPlayer ();
player.Open(new Uri("BLOW.WAV", UriKind.Relative));
player.Play();
一个MediaPlayer对象一次只能播放一个文件。而且该文件是异步播放的,你也可以调用Close来释放文件。
三、 MediaPlayer比起SoundPlayer来说,有很大的灵活性,但它仍然是为程序代码设计的。为了方便在XAML中能使用它,WPF提供了一个MediaElement类,它封装了MediaPlayer类,如同SoundPlayerAction封装了SoundPlayer一样。
MediaElement继承自FrameworkElement,因此,它可以嵌入用户界面参与布局。通过为MediaElement的Source属性赋一个音频文件的Uri,它就能在加载之后进行播放。且MediaElement提供了MediaPlayer的许多属性和事件,方便用户在XAML中进行设置。
如果你想控制MediaElement的播放,那么,你应该试着用MediaTimeline的动画来设置MediaElement的Source属性。当MediaTimeline的TargetName是MediaElement时,将依据设置的媒体源自动创建一个MediaClock并将其分配给MediaElement关联的播放器(MediaPlayer)。MediaElement关联的播放器得到MediaClock后,会工作在时钟模式,自动进行媒体的播放。另外,通过MediaTimeline设置的Duration和BeginTime等属性,都能关联到MediaElement上,从而控制媒体源播放的时间和开始时间等。
使用MediaElement和MediaTimeline来播放音频文件的代码如下:
<MediaElement Name="audio"/>
<Button Content="Play">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<MediaTimeline Source="BLOW.WAV" Storyboard.TargetName="audio"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
除了BeginStoryboard外,可以对同一个Storyboard使用PauseStoryboard、ResumeStoryboard、SeekStoryboard和StopStoryboard动作分别来暂停、继续、Seek、停止一段音频。
如果想循环听一段背景音乐,可以设置MediaTimeline的RepeatBehavior为Forever或“3x”等。
如果不想在XAML中完成音频的控制动作,想挪到后台代码中,那么,你首先需要设置MediaElement的LoadedBehavior属性为Manual(且MediaElement不是MediaTimeline的动画目标,否则它的行为始终受MediaClock的Clock影响,无法交互式控制),才能使用Play、Pause和Stop方法交互式控制媒体。