-
音频与视频:

播放音频

WPF具有出色的内置音频和视频支持,您将在本教程的下几章中看到。 在本章中,我们将讨论播放来自音频文件的音频能力,例如: 在MP3格式,但首先让我们看看几种更简单的方法。

系统声音和SoundPlayer

WPF有一个SoundPlayer类,它将为您播放基于WAV格式的音频内容。 WAV今天不是一种非常广泛使用的格式,主要是因为它没有压缩,占用了大量的空间。

因此,虽然SoundPlayer类易于使用,但它并不是很有用。 我们将专注于MediaPlayerMediaElement类,它们能播放MP3文件,我们先来看看在WPF应用程序中播放声音的最简单方法 - SystemSounds类。

SystemSounds类提供了几种不同的声音,这些声音对应于Windows中用户为此事件定义的声音,如Exclamation和Question。 您可以用一行代码播放它们:

SystemSounds.Beep.Play();

这是一个完整的例子,我们使用所有当前可用的声音:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.SystemSoundsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SystemSoundsSample" Height="200" Width="150">
    <StackPanel Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button Name="btnAsterisk" Click="btnAsterisk_Click">Asterisk</Button>
        <Button Name="btnBeep" Margin="0,5" Click="btnBeep_Click">Beep</Button>
        <Button Name="btnExclamation" Click="btnExclamation_Click">Exclamation</Button>
        <Button Name="btnHand" Margin="0,5" Click="btnHand_Click">Hand</Button>
        <Button Name="btnQuestion" Click="btnQuestion_Click">Question</Button>
    </StackPanel>
</Window>
using System;
using System.Media;
using System.Windows;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class SystemSoundsSample : Window
	{
		public SystemSoundsSample()
		{
			InitializeComponent();
		}

		private void btnAsterisk_Click(object sender, RoutedEventArgs e)
		{
			SystemSounds.Asterisk.Play();
		}

		private void btnBeep_Click(object sender, RoutedEventArgs e)
		{
			SystemSounds.Beep.Play();
		}

		private void btnExclamation_Click(object sender, RoutedEventArgs e)
		{
			SystemSounds.Exclamation.Play();
		}

		private void btnHand_Click(object sender, RoutedEventArgs e)
		{
			SystemSounds.Hand.Play();
		}

		private void btnQuestion_Click(object sender, RoutedEventArgs e)
		{
			SystemSounds.Question.Play();
		}
	}
}

使用这种方法有一些限制。 首先您只能访问这五种声音,其次用户可能已在Windows中禁用它们,在这种情况下,预期的声音将被静音取代。 另一方面,如果您只想以与Windows相同的方式使用这些声音,那么就可以非常轻松地为警告,问题等产生声音。在这种情况下,您的应用程序尊重用户是一件好事。

MediaPlayer类

MediaPlayer类使用Windows Media Player技术以几种现代格式播放音频和视频,例如: MP3和MPEG。 在本文中,我们将使用它来播放音频,然后在下一章中关注视频。

使用MediaPlayer类播放MP3文件非常简单,我们将在下个示例看到:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerAudioSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MediaPlayerAudioSample" Height="100" Width="200">
    <Grid VerticalAlignment="Center" HorizontalAlignment="Center">
        <Button Name="btnOpenAudioFile" Click="btnOpenAudioFile_Click">Open Audio file</Button>
    </Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Media;
using Microsoft.Win32;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class MediaPlayerAudioSample : Window
	{
		private MediaPlayer mediaPlayer = new MediaPlayer();

		public MediaPlayerAudioSample()
		{
			InitializeComponent();
		}

		private void btnOpenAudioFile_Click(object sender, RoutedEventArgs e)
		{
			OpenFileDialog openFileDialog = new OpenFileDialog();
			openFileDialog.Filter = "MP3 files (*.mp3)|*.mp3|All files (*.*)|*.*";
			if(openFileDialog.ShowDialog() == true)
			{
				mediaPlayer.Open(new Uri(openFileDialog.FileName));
				mediaPlayer.Play();
			}
		}
	}
}

在这个例子中,只有一个按钮,它将显示一个OpenFileDialog并让你选择一个MP3文件。 完成后它将使用已创建的MediaPlayer实例打开并播放此文件。 请注意,MediaPlayer对象是在事件处理程序之外创建的。 这确保了对象不会过早地被垃圾收集,因为一旦事件处理程序完成,它就会超出范围,这将导致播放停止。

还请注意,此示例没有进行异常处理,通常是为了使示例尽可能紧凑,这样做也是因为Open()和Play()方法实际上不会抛出任何异常。 相反,您可以使用MediaOpened和MediaFailed事件在正确或错误时采取相应动作。

控制MediaPlayer

在我们的第一个MediaPlayer示例中,我们打开并自动开始播放文件,而不会让用户有机会控制播放过程,但很明显,MediaPlayer控件可让您完全控制播放。 这是一个展示最重要功能的示例:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.MediaPlayerAudioControlSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MediaPlayerAudioControlSample" Height="120" Width="300">
    <StackPanel Margin="10">
        <Label Name="lblStatus" Content="Not playing..." HorizontalContentAlignment="Center" Margin="5" />
        <WrapPanel HorizontalAlignment="Center">
            <Button Name="btnPlay" Click="btnPlay_Click">Play</Button>
            <Button Name="btnPause" Margin="5,0" Click="btnPause_Click">Pause</Button>
            <Button Name="btnStop" Click="btnStop_Click">Stop</Button>
        </WrapPanel>
    </StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Microsoft.Win32;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class MediaPlayerAudioControlSample : Window
	{
		private MediaPlayer mediaPlayer = new MediaPlayer();

		public MediaPlayerAudioControlSample()
		{
			InitializeComponent();

			OpenFileDialog openFileDialog = new OpenFileDialog();
			openFileDialog.Filter = "MP3 files (*.mp3)|*.mp3|All files (*.*)|*.*";
			if(openFileDialog.ShowDialog() == true)
				mediaPlayer.Open(new Uri(openFileDialog.FileName));

			DispatcherTimer timer = new DispatcherTimer();
			timer.Interval = TimeSpan.FromSeconds(1);
			timer.Tick += timer_Tick;
			timer.Start();
		}

		void timer_Tick(object sender, EventArgs e)
		{
			if(mediaPlayer.Source != null)
				lblStatus.Content = String.Format("{0} / {1}", mediaPlayer.Position.ToString(@"mm\:ss"), mediaPlayer.NaturalDuration.TimeSpan.ToString(@"mm\:ss"));
			else
				lblStatus.Content = "No file selected...";
		}

		private void btnPlay_Click(object sender, RoutedEventArgs e)
		{
			mediaPlayer.Play();
		}

		private void btnPause_Click(object sender, RoutedEventArgs e)
		{
			mediaPlayer.Pause();
		}

		private void btnStop_Click(object sender, RoutedEventArgs e)
		{
			mediaPlayer.Stop();
		}
	}
}

在这个例子中,我们稍微扩展了我们的播放器,它现在包含播放,暂停和停止按钮,以及用于显示当前播放状态的标签。 要播放的MP3文件以相同的方式加载,但我们会在应用程序启动时立即加载,以保持示例简单。

MP3加载后,我们启动一个计时器,每秒钟触发一次。 我们使用此事件来更新状态标签,该标签将显示当前进度以及加载文件的整个长度。

这三个按钮各自只调用MediaPlayer对象上的相应方法 - 播放,暂停和停止。

小结

还有更多的选项可以让用户控制,但为了节省时间,我将在我们讨论MediaPlayer类的视频方面时再来介绍 - 到那时,我将做一个更完整的媒体播放器示例,该播放器能够播放音频和视频文件,并提供更多选项。