用WPF实现媒体播放器

星辰月·雪传说 发表于 2008-07-03 15:17:10

基本的视频、音频播放

视频和音频的播放采用MediaElement类。在声明时即设定其Source属性,在一组按钮的Click事件处理函数中设定其播放、暂停与停止行为。

视频播放器及对应一组按钮(用StackPanel控制其布局)在XAML中的声明如下:

 

<MediaElement x:Name="myVideoElement" Source="F:\CapVideos\Test.avi" MediaOpened="Element_VideoOpened" MediaEnded="Element_VideoEnded" LoadedBehavior="Manual" UnloadedBehavior="Stop" />

<StackPanel x:Name="VideoCtrlPanel" Orientation="Horizontal" Height="24" VerticalAlignment="Bottom" Margin="0,0,0,0" HorizontalAlignment="Center">

          <Button x:Name="Start" Background="#55FFFFFF"

            Click="StartPreview" Content="Play" Height="30" Width="100" Cursor="Hand"/>

          <Button x:Name="Stop" Background="#55FFFFFF"

            Click="PausePreview" Content="Pause" Height="30" Width="100" Cursor="Hand"/>

          <Button x:Name="Finish" Background="#55FFFFFF"

            Click="EndPreview" Content="Stop" Height ="30" Width="100" Cursor="Hand"/>

</StackPanel>

 

C#文件中只需完成Element_VideoOpenedElement_VideoEndedStartPreviewPausePreviewEndPreview几个函数的定义,一个基本的视频播放器便可以工作了。

音频播放器同样采用MediaElement类,因为音频与视频同步播放,因此不需要再增加控制按钮。

自主选择播放文件的媒体播放器

以上完成的播放器只能播放特定的媒体文件。如果要能够让用户自主选择播放文件,首先需要增加一个列表框列出当前可选文件。在此采用了TreeView类。

当程序启动时,初始化此类,枚举出所有可选的视频文件,将文件名列出:

 

foreach (string s in Directory.GetFiles(VideoPath, "*.avi"))//枚举特定路径下的所有avi文件

{

        TreeViewItem item = new TreeViewItem();             //创建Item

    item.Header = s.Substring(s.LastIndexOf("\") + 1); //从完整路径中取出文件名

    item.Tag = s;

    item.FontWeight = FontWeights.Bold;                 //设定字体等显示属性

    item.FontSize = 22;

    item.Foreground = Brushes.Silver;

    VideoList.Items.Add(item);                          //Item添加到TreeView

}

 

当列表框中被选中的条目发生变化时,重新设定媒体播放器的播放来源:

 

private void VideoList_SelectedItemChanged(object sender, EventArgs e)

//此函数当VideoList中被选中条目发生变化时被调用

{

    TreeView tree = (TreeView)sender;

    TreeViewItem temp = ((TreeViewItem)tree.SelectedItem);  //获取被选中条目

    if (temp == null)

        return;

    string s = temp.Header.ToString();      //从被选中条目中获取文件名

    s = VideoPath + s;                      //构造完整的文件路径

    System.Uri PlayVideoUri = new Uri(s);   //从路径字符串构造Uri

    myVideoElement.Source = PlayVideoUri;   //设定视频播放器的播放来源

}

 

进度条、播放时间和音量调节

MediaElement下方增加了四个元素:进度条(Slider类)、播放时间文本框(TextBlock类)、总时长文本框(TextBlock类)和音量调节拖动条(Slider类)。其中音量调节拖动条只需要在ValueChanged事件发生时更新音频播放器的音量即可,总时长文本框也只需要在媒体文件加载时取出其长度信息进行显示。进度条和播放时间框稍复杂,因为MediaElement类本身并没有在播放时间刷新时触发的事件,而且其Position属性也不支持数据绑定,思考再三只能在开始播放时手工定义一个计数器(DispatcherTimer),设定它每500ms触发一个事件,在相应的事件处理函数中取出音频文件的当前播放位置,用它来刷新进度条和时间框的值。

支持进度条拖动

由于无法将播放器的播放位置属性和进度条的值绑定,所以双向交互只能手动进行。最初如音量调节拖动条一样,在播放进度条的ValueChanged事件发生时更新媒体播放器的播放位置。但实践证明这是一个没有价值的方案,因为在用户拖动进度条滑块的过程中,用于刷新进度条位置的计数器一旦触发刷新事件(这每隔0.5s就会发生一次),进度条滑块就回到了它本该在的位置,不再听从鼠标指挥。解决方法也很简单,就是在鼠标按下时让计数器暂停。所以必须手工处理关于鼠标的一系列细化的事件。最终采用的方法如下:

 

事件

处理方式

PreviewMouseLeftButtonDown

刷新计数器停止运行

PreviewMouseMove

根据进度条滑块当前位置更新播放时间文本框中显示的时间

PreviewMouseLeftButtonUp

根据进度条滑块当前位置更新媒体播放位置;重新启动刷新计数器

关键词(Tag): 播放器 wpf


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定