Silverlight本身提供了多媒体播放控件,但并没有封装好,可以直接使用的控件。在网上搜索了一些,都不是很适用,有些过于复杂要引用一大堆dll,感觉很臃肿,有些样式风格不适合。silverlight只提供了MediaElement,并不像以前html那样现成的直接使用那么方便,所以就自己封装一下,做一个满足基本功能的简单播放器。通过本篇随笔认识一下Blend强大的修改控件样式魔力,和实现一个简单的播放器。

功能点:

1、播放、暂停及显示当前播放状态

2、实时显示已播放时间

3、播放进度条,并能拖动播放位置

4、全屏按钮及双击播放画面入或退出全屏

5、调整音量

6、播放列表

  播放器的基本功能点就是需求,将需求分解,罗列出实现难点和功能要点,评估工作量及风险。

一、认识MediaElement控件

使用到的重要属性:

public MediaElementState CurrentState { get; }  MediaElement 的当前状态。状态可以为下列值之一(如在 MediaElementState 枚举中所定义):Buffering、Closed、Opening、Paused、Playing 或 Stopped。默认值为 Closed。
public bool AutoPlay { get; set; }  如果自动播放,则为 true;否则为 false。默认值为 true。如果设置 Source 属性前将此属性设置为 true,则设置Source属性时自动播放视频。
public Uri Source { get; set; }  获取或设置 MediaElement 上的媒体来源。即指定一个视频的统一资源标识符 (URI) 字符串。
public double Volume { get; set; }  获取或设置媒体的音量大小。

使用到的重要事件(非运行代码):

重要事件

//当媒体流已被验证和打开且已读取文件头时发生。在该自定义控件中主要通过该事件获取视频的总时长。public event RoutedEventHandler MediaOpenedvoid mediaElement_MediaOpened(object sender, RoutedEventArgs e){this.playTools.TotaPlayTime = (int)this.mediaElement.NaturalDuration.TimeSpan.TotalSeconds;}//当 MediaElement 不再播放音频或视频时发生。在该自定义控件中主要通过该事件设置MediaElement为Stop,并判断是否循环播放而进行继续循环播放。public event RoutedEventHandler MediaEndedvoid mediaElement_MediaEnded(object sender, RoutedEventArgs e){this.mediaElement.Stop();if (this.IsReplay){this.mediaElement.Play();}}//当 CurrentState 属性的值更改时发生。在该自定义控件中主要通过该事件显示当前视频播放状态信息。public event RoutedEventHandler CurrentStateChangedif (this.mediaElement.CurrentState == MediaElementState.Buffering){this.playTools.CurrentMessage = this.mediaElement.CurrentState + " " + Math.Round(this.mediaElement.BufferingProgress * 100, 0).ToString() + "%";}//在存在与媒体 Source 关联的错误时发生。MediaFailed 事件可在下列条件下发生:1、未找到文件。2、无效的(无法识别的或不支持的)媒体格式。3、播放期间未知的媒体错误。//在该自定义控件中主要通过该事件显示错误信息。public event EventHandler<ExceptionRoutedEventArgs> MediaFailedvoid mediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e){this.playTools.CurrentMessage = e.ErrorException.Message;}//该事件是播放时发生,用于获取当前已播放时间CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);void CompositionTarget_Rendering(object sender, EventArgs e){int currentTime = (int)this.mediaElement.Position.TotalSeconds;this.playTools.CurrentPlayTime = currentTime;}

其他支持的媒体格式、协议和日志字段,请查看帮助文档,更详细更清楚。

二、分解播放器元素

  

  可以将播放器分为视频显示区和控制条两部分。

  视频显示区比较简单,就只有一个MediaElement控件就可以了。

  控制条部分较为复杂,我们再进一步分解,并分析各个按钮的功能特性,选择合适的控件修改其样式。

  1、实时播放进度条。获取视频总时长和当前播放时长,可以计算出进度百分比,在silverlight控件中,ProgressBar可以通过设置Value属性显示进度,所以ProgressBar 控件很适合作为播放进度的显示,只需要修改一下样式就可以了,不需要编写其他代码来实现;

  2、播放、暂停按钮。这是一个互斥的操作,同一时间只有一种状态,在silverlight控件中CheckBox和ToggleButton都有这样的特性,每点击一次都切换一种状态,所以选择其中一个控件都可以。本人更倾向于ToggleButton,可能是因为比CheckBox的名字更容易于理解,不过都无所谓。

  3、停止按钮。只有一种状态,所以用Button控件就可以了,不作多解释。

  4、当前时间、总时长、播放状态、视频名称 。使用TextBlock就可以了,不作多解释。

  5、播放列表按钮。点击显示视频列表,再点击隐藏,有两个状态进行切换,所以选择ToggleButton控件。

  6、全屏按钮。点击全屏,再点击退出全屏,两个状态进行切换,所以选择ToggleButton控件。

  7、音量调整按钮。是最复杂的一个按钮,点击小喇叭图标,弹出调整阀值条,点击播放器的其他地方,弹出消失。在silverlight中,点击应用的其他地方,会触发事件的控件,可以想一下有哪些,其中ComboBox就是在下拉下来的时候,点击界面其他地方,会自动收起。可以上下来回拖动调整音量大小,silverlight中Silder控件具有上下拖动的特性,使用它只需要调整样式就可以了。所以使用ComboBox和Silder组合成音量调整按钮。

三、设计控件样式

  修改控件原本的样式,改变成符合实际需求的样式,是silverlight的强大优势之一。

  下面看看ProcessBar怎么样从传统的样子改变成实时播放进度条

  

  从工具箱将ProcessBar拖入工作区,创建一个新的样式,选择Eidt a Copy ,输入progressBarStyle键名;

  1、修改ProgressBarRootGradient红色框选中属性值,如下图

  

  效果如下:

  

  2、编辑ProgressBarIndicator,将其类型改为Border类型,接着添加Grid,再添加Rectangle和Ellipse元素。将Grid分成两列,第一列自适应,第二列固定宽度为10px。Rectangle放在第一列,作用高亮显示已播放进度,Ellipse放在第二列,作用是显示为当前播放的进度点。如下图

  

  设置DeterminateRoot属性:

  

  设置ProgressBarIndicator属性:

  

  设置Grid属性:

  

  设置Rectangle属性:

  

  设置Ellipse属性:

  

  效果图:

  

  3、修改ProgressBarTrack属性,如下图所示:

  

  效果图:

  

  整个播放实时进度条的样式已经完成,其中最关键的就是第2步骤,巧妙地运用ProcessBar控件通过改变ProgressBarIndicator的Width属性,显示进度变化,所以利用这个原理添加Grid、Rectangle、Ellipse元素,乔装成符合自己实际需要的控件。

  

  接下来设计播放、暂停按钮的样式,看看ToggleButton按钮如何转变的。

  

  从工具箱将ToggleButton拖入工作区,创建一个新的样式,选择Create Empty ,输入PlayPuseTemplate键名;

  我们创建的是一个空的模板,所以里面什么元素都没有,那么添加我们所需要的元素,如下图:

  

  设置第一个Rectangle属性:

  

  设置borderPlay属性(<Border x:Name="borderPlay" CornerRadius="3">),使用钢笔工具绘制IconPlay形状

  

  设置borderPause属性,和borderPlay大同小异,不多作说明了。唯一不同的是默认是隐藏的。

  设置第二个Rectangle属性:

  

  效果图:

  

  接下来还需要添加鼠标进入时的过度效果,修改在MouseOver状态的样式(高亮按钮颜色)和Checked选中状态时的样式(暂停按钮显示,播放按钮隐藏)。

                                     

  整个播放、暂停按钮的样式就完成了。播放列表按钮、全屏按钮、停止按钮都可以依葫芦画瓢,就不一步一步写出来了。

  

  接下来设计最复杂的音量调整按钮的样式。看看怎样从传统的ComboBox+Silder 转变成符合实际需要的样式。

  

  从工具箱将Slider拖入工作区,调整高度固定为80px,设置Orientation="Vertical".如图所示:

  

  创建一个新的样式,选择Edit a Copy ,输入SliderStyle键名。确定后,如下图所示:

  有HorizontalTemplate和VerticalTemplate两种类型,我们这里只需修改VerticalTemplate。将Rectangle宽度设为4;右键-》Edit Template -》Edit a Copy;确定后,将除Background元素外,其他元素删除,如下图所示:

  

  整个调整声音的滑块样式就完成了,接着设计音量按钮的样式。

  从工具箱将ComboBox拖入工作区,调整宽高固定为22px,创建一个新的样式,选择Edit a Copy ,输入CmbVolmeStyle键名。确定后,如下图所示:

  

  注意框框里的元素,接下来我们要对DropDownToggle进行修改,右键-》Edit Template -》Edit Current,将Grid包含的元素contentPresenter外,其他全部删除。结果如下图所示:

  

  接着将BtnArrow删除,添加Canvas 命名为 IconVolume ,在其里面再添加Canvas,用于绘制小喇叭的样式,使用钢笔工具绘制(画图需要耐性和反复修改);如图所示:

  

  接着将ContentPresenter元素删除,因为我们不需要设置选中的内容。跟着添加两个Rectangle,目的是作美化用。如图所示:

  

  紧接着删除DisabledVisualElement、FocusVisualElement、ScrollViewer。清空PopupBorder的边框色和背景色。如下图所示:

  

  从工具箱将Slider拖入到PopupBorder,调整高度固定为80px,设置Orientation="Vertical",Value="5", Margin="0,0,0,-6",并应用SliderStyle样式。如图所示:

  

  整个音量调整按钮的完成了,其他按钮的样式依葫芦画瓢就可以了。是否有点像周星驰电影007里面说的,它表面上是一个吹风机,其实它是一个刮胡刀。

四、组合成播放器界面

  新建PlayTools用户控件,将实时播放进度条(ProgressBar)、播放、暂停按钮(ToggleButton)、停止按钮(Button)\当前时间、总时长、播放状态、视频名称 (TextBlock)、播放列表按钮(ToggleButton)、全屏按钮(ToggleButton)、音量调整按钮(ComboBox)添加到Grid里,并应用样式,结果如下图所示:

  

  新建Player用户控件,将MediaElement、PlayTools、PlayListBox(没有详细说明,有需要请看源代码) 添加到Grid里,结果如下图所示:

  

五、关键代码及注意点

  MediaElement控件本身没提供实时播放进度的事件,所以是通过注册CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);来实时获取当前已播放时间

当前播放进度

CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);void CompositionTarget_Rendering(object sender, EventArgs e){int currentTime = (int)this.mediaElement.Position.TotalSeconds;this.playTools.CurrentPlayTime = currentTime;}

六、特别处理及说明

  双击全屏,由于silverlight4.0版本还没有鼠标双击的事件,所以需要模拟实现双击操作,原理是记录连续点击的两次时间差为300毫秒内,则判定为双击。

  

双击实现

     void mediaElement_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e){if (mouseClickList.Count == 0){mouseClickList.Add(DateTime.Now);}else{if (mouseClickList.Count == 1){if (DateTime.Now.Subtract(mouseClickList[0]).TotalMilliseconds <= 300){this.playTools.IsScreenFull = true;playTools_ClickFullScreenButton(true);}mouseClickList.Clear();}}}

  全屏效果的实现,这里的实现使用了VideoBrush来渲染,就是所看到的全屏,其实是视频笔刷,后面才是真正的视频播放,只是把它投影到全屏控件上了。

全屏效果实现

    this.FullPopup = new Popup();double width = Application.Current.Host.Content.ActualWidth;double height = Application.Current.Host.Content.ActualHeight;VideoFullPlayer videoFullPlayer = new VideoFullPlayer();videoFullPlayer.FullScreenChange += new Action<bool>(videoFullPlayer_FullScreenChange);videoFullPlayer.Width = width;videoFullPlayer.Height = height;videoFullPlayer.SetVideoBrush(this.mediaElement);PlayTools playTools = this.playTools;this.LayoutRoot.Children.Remove(this.playTools);videoFullPlayer.CurrentPlayTools = playTools;FullPopup.Child = videoFullPlayer;FullPopup.IsOpen = true;    

七、演示示例

八、源码下载

如需源代码,请猛点击下载

准备放假咯,明年再见!!

转载于:https://www.cnblogs.com/lijie198871/archive/2012/12/28/2831699.html

silverlight自定义控件之多媒体视频播放器相关推荐

  1. 幻影影音 - 免费的多媒体视频播放器

    软件简介 幻影影音是一款免费的多媒体视频播放器,自带视频和音频解码器,不需要再安装第三方的解码器. 幻影影音能播放所有的视频格式,比如AVI, DAT, MPEG, DivX, XviD, WMV, ...

  2. VLC Media Player for Mac(VLC多媒体视频播放器)

    VLC Media Player多媒体播放器是VideoLAN计划的多媒体播放器,mac版VLC多媒体视频播放器VLC Media Player如何使用.一款高度便携的多媒体播放器,适用于各种音频和视 ...

  3. QT开发笔记(多媒体实例之视频播放器)

    多媒体 视频播放器 与音乐播放器一样使用 QMediaPlayer 类,不同的是需要使用 setVideoOutput(QVideoWidget*) 设置一个视频输出窗口,好让视频在此窗口显示,其他步 ...

  4. html5多媒体播放器,走进HTML5-学习多媒体,带你实现视频播放器、音乐播放器功能(*^▽^*)...

    欢迎关注个人我的博客分享一些前端技术.面试题.面试技巧等html Web 中的音频和视频 自 21 世纪初以来,咱们的带宽开始可以支持任意类型的视频在早些时候,传统的 web 技术(如 HTML )不 ...

  5. 《android多媒体api》之MediaPlayer自定义视频播放器

    <android多媒体api>系列是整合梳理android开发中经常用到的媒体相关api:多媒体开发主要内容有音频.视频录制播放.摄像头操作.录制操作.流媒体.直播.推流.拉流等方面:最近 ...

  6. android多媒体视频,android多媒体(视频播放器)

    ##视频处理 一丶VideoView控件 点击创建一个播放器并播放视频 /** * 播放视频 * @param view */ public void play(View view){ vv.setV ...

  7. HTML5+CSS3+JQuery打造自定义视频播放器

    简介 HTML5的<video>标签已经被目前大多数主流浏览器所支持,包括还未正式发布的IE9也声明将支持<video>标签,利用浏览器原生特性嵌入视频有很多好处,所以很多开发 ...

  8. 使用CSS3+JQuery打造自定义视频播放器

    简介HTML5的<video>标签已经被目前大多数主流浏览器所支持,包括还未正式发布的IE9也声明将支持<video>标签,利用浏览器原生特性嵌入视频有很多好处,所以很多开发者 ...

  9. python开发视频播放器_python视频播放器

    广告关闭 100GB直播流量包仅需9.9元,10TB点播流量包仅需999元,参与活动还赠移动直播SDK,短视频SDK,小程序插件等,大促100%中奖率 最近研究了python的两个gui包,tkint ...

最新文章

  1. 数学问题的解题方法(模板)
  2. 九种破解Xp登录密码方法
  3. SQL计算宝宝吃奶的时间间隔(二)
  4. iOS常用的第三方类库
  5. Linux内核分析——操作系统是如何工作的
  6. c# 调用Minitab18.1实现直方图、质量正态图
  7. 论项目整体管理-软考论文整理一
  8. 全国、省、地级市、区县乡镇级矢量地图2021年(最新)
  9. TTL 电路 COMS 电路 区别
  10. Excel创建堆积柱形混合折线图
  11. JavaScript中throw的错误异常处理
  12. 微信开发者工具最新版本无法上传腾讯云代码(找不到腾讯云图标)
  13. 【略有料】JDBC Statements, PreparedStatement和CallableStatement语句
  14. 粒径测量中的D10 D50 D90的含义
  15. Fabric架构及基本原理
  16. Android studio 解决运行按钮灰色/禁用状态
  17. Linux时间一直跳回原始时间,Linux时间同步
  18. Win10删除或移动文件进度卡在99%->系统资源管理器cpu占用率及电源使用情况非常高的解决方法
  19. Spring Cloud 电子招标采购系统源码
  20. 文献综述计算机辅助药物设计,科普小文:计算机辅助药物设计之“分子对接技术”...

热门文章

  1. Linux中的8个ldd命令示例
  2. 计算机界面没磁盘驱动器,win10弹出驱动器中没有磁盘请在驱动器怎么办
  3. Dell服务器硬盘活动指示灯常亮、不亮、闪黄灯诊断
  4. 出行大数据绘制的“城市星云图”是怎样的?我们还总结出了5种城市结构
  5. 为什么谷歌的开发人员认为敏捷开发是无稽之谈?
  6. 社交平台Uki遭Soul恶意举报:损失500万新用户、运营停顿
  7. vf计算机二级培训,计算机二级VF考试培训班PPT第4章.pptx
  8. 码易应用商城入驻流程
  9. cocos creator 打包 后屏闪、闪烁问题
  10. 一部优秀的影片《零下八度》观后感