在WPF或Silverlight中使用MediaElement控件可以方便的制作一个视频音频播放器。

首先制作一个UserControl:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
<DockPanel Height="387">
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom">
<Button Height="23" HorizontalAlignment="Left" Margin="16,0,0,10" x:Name="btnPlay" VerticalAlignment="Bottom" Width="75" Click="btnPlay_Click">播放</Button>
<Button Height="23" HorizontalAlignment="Left" Margin="16,0,0,10" x:Name="btnPause" VerticalAlignment="Bottom" Width="75" Click="btnPause_Click">暂停</Button>
<Label Content="音量:"/>
<Slider x:Name="sldVolumn" Value="{Binding Volume, ElementName=mePlayer, Mode=TwoWay, UpdateSourceTrigger=Default}" Maximum="1" LargeChange="0.1" SmallChange="0.01" Width="124" />
<Label Content="进度:"/>
<Slider x:Name="sldProgress" Minimum="0" Value="{Binding ElementName=mePlayer, Path=Position, Mode=TwoWay, Converter={StaticResource PrgConverter}}" LargeChange="10" Width="192" />
</StackPanel>
<MediaElement DockPanel.Dock="Top" Margin="16,23,12,39" x:Name="mePlayer" LoadedBehavior="Manual" MediaOpened="mePlayer_MediaOpened" />
</DockPanel>

这里音量控制使用Slider并Binding到MediaElement上,同时要设置最大值Maximum为1

接下来需要制作一个进度条,通过拖动进度条可以控制视频播放进度。

进度条也是用Slider,我们需要把它的Value和MediaElement的Position属性关联起来,所以需要一个Converter。

1
2
3
4
5
6
7
8
9
10
11
12
public class ProgressConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((TimeSpan)value).TotalSeconds;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return TimeSpan.FromSeconds((double)value);
}
}

在这个Converter中,我们把Slider和播放视频的总时间做对应,所以还需要将视频的总时间赋值给Slider的Maximum属性。由于每个视频的时间是不同的,所以必须要通过动态的方法赋值,在MediaElement的MediaOpened事件中可以完成这一操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void btnPlay_Click(object sender, RoutedEventArgs e)
{
mePlayer.Play();
}
private void btnPause_Click(object sender, RoutedEventArgs e)
{
mePlayer.Pause();
}
private void mePlayer_MediaOpened(object sender, RoutedEventArgs e)
{
sldProgress.Maximum = mePlayer.NaturalDuration.TimeSpan.TotalSeconds;
}

需要注意的是MSDN中有对NaturalDuration的备注:在引发 MediaOpened 事件之前,NaturalDuration 是不正确的。

所以mePlayer.NaturalDuration.TimeSpan.TotalSeconds不能在构造函数或者其他在MediaOpened事件前的方法中调用。