zoukankan      html  css  js  c++  java
  • WPF,Silverlight与XAML读书笔记第二十八 控件之十 – 媒体控件

    Image(WPF/Silverlight2.0)

    顾名思义这个控件用来显示各种格式的图片。

    属性

    • Source:指定图像文件的路径及名称,文件需要被设置为资源。该属性类行为System.Windows.Media.ImageSource。
    • Height:图像控件的高度
    • Width:图像控件的宽度
    • Clip:该属性可以对图像进行剪切,Clip属性中,可以设定几何图形,WPF按照几何图像进行剪切。关于几何图形可以参见2D图形一文中Geometry的介绍。由于几何图像是复杂的元素,所以常以属性元素来设置Image的Clip值。

    这里给一个Clip的示例:

    1 <Image Source="res.jpg" Width="300" Height="200">
    2     <Image.Clip>
    3         <EllipseGeometry Center="150,150" RadiusX="100" RadiusY="100"/>
    4     </Image.Clip>
    5 </Image>

    Strech:当图片大小与控件大小不同时,可以使用这个属性定义如何对图片进行拉伸,以使图片适应控件,有如下几种拉伸模式。

    • None:图像不拉伸;图像小于容器,周围以白色填充。如果大于容器,图像将被剪切。
    • Fill:图像被拉伸到容器的Height和Width定义的值,图片可能发生变形。
    • Uniform:图像按原先的外观比例被缩放到最佳大小,如果无法填充满容器,那些区域被白色填充。
    • UniformToFill:图像按原有比例放缩并拉伸填充容器。超出容器的部分将被剪切。

      如果希望在运行时设置Iamge控件中的图片(Source属性的值),可以使用下面这样的代码:

    该代码段适用于Silverlight:

    1 Uri uri = new Uri("mm.png", UriKind.Relative); 
    2 image.Source = new BitmapImage(uri); 

    这段代码很易懂,不再赘述。

    MediaElement(WPF/Silverlight2.0)

    MediaElement控件定义于System.Windows.Control,类似于Image控件,使用Source属性设定要播放的媒体文件(声音或视频)。MediaElement支持的媒体文件格式主要为wma,mp3类型的音频及vc1编码的wmv的视频,具体列表可以参见MSDN网站,另外MediaElement也支持asx格式的播放列表文件。在协议方面MediaElement控件支持mms,http与https三种协议。对于这三种协议MediaElement控件采用了不同的访问方式,对于mms协议的Url,首先启用数据流方式播放,当这种方式遇到问题时则采用边下边播的方式,即首先下载数据填充满缓冲区然后播放。而对于http与https协议,这种尝试想法,首先MediaElement会尝试边下边播,在无法下载时将尝试数据流方式播放。

    外观方面,如果指定了控件的宽高两个属性(Height与Width),则视频会被切成这个大小(原始视频大小大于控件大小时,如果控件尺寸大于视频则视频显示在控件中央周围填充黑边),如果只指定其中一个属性,则视频会被按比例拉伸或缩小到适应控件的大小,否则两个属性都不指定视频会按原始大小进行展现,但如果此时视频超出了MediaElement的可视范围(受其它元素所限),超出部分会被切掉。

    属性:

    • Strech:这个属性对视频拉伸的方式与前文介绍的Image控件的同名属性及布局-内容溢出处理部分介绍的Strech属性的使用完全一致,此处不再赘述。
    • Clip:同样在Image部分我们介绍的同名属性,可以原样照搬到MediaElement元素中。
    • Opacity:这个属性用来控制视频的透明度,0表示完全不透明而1表示完全透明,当视频透明时可以看到后面的内容。
    • RenderTransform:Element中当然也支持使用RenderTransform进行变形

    下面的例子我们使用SkewTransform进行演示:

    1 <MediaElement x:Name="mes" Source="balls.wmv" Height="200" Width="200" Stretch="Fill">
    2     <MediaElement.RenderTransform>
    3         <SkewTransform AngleX="45"/>
    4     </MediaElement.RenderTransform>
    5 </MediaElement>
    • LayoutTransform(WPF only):设定单独的转换类型或一组转换类型对多媒体元素进行转换。有关转换的详细信息参见《转换》一文。LayoutTransform也常用属性元素设置,同样LayoutTransform属性中设置TransformGroup的方法前文也有描述。

    LayoutTransform示例:

    1 <MediaElement x:Name="mes" Source="balls.wmv" Height="200" Width="200" Stretch="Fill">
    2     <MediaElement.LayoutTransform>
    3         <ScaleTransform ScaleX="2" />
    4     </MediaElement.LayoutTransform>
    5 </MediaElement>

    LoadedBehavior:

    • AutoPlay:该属性默认值为true,这样当Source属性被设置了视频后MeidaElement会自动播放,如将此属性设置为false,需要手动调用MeidaElement的Play方法来播放。

    下面的几个属性与音频相关:

    • IsMuted:布尔值,当设置为true时,不会播放声音。
    • Volume:这个属性用来控制音量,其值是一个相对数值,当为0时没有音量,1时为最大音量。
    • Balance:这个属性控制音频的平衡,此属性取值为-1到1,在由-1到1变化的过程中左声道声音逐渐减小,右声道声音逐渐增大。为0时两个声道音量平衡。如当此值设置为0.8时,左边扬声器按20%音量来播,右边扬声器按80%音量来播。

    方法:

    Play,Pause和Stop:这三个方法提供所有媒体播放类软件中最常见的3种功能 – 播放,暂停与停止。特别的,对于 Silverlight,这三个方法不但可以在托管环境下由C#中直接调用,还暴露给Silverlight控件的JavaScript环境,这样在JavaScript环境中获得MediaElement对象的引用(具体方法在Silverlight与JavaScript交互一节有详细介绍)后,可以直接调用这三个方法。

    与缓冲有关的属性与事件:

    • BufferingProgress属性,通过这个属性可以监控缓冲的情况,如当缓冲百分比始终达不到50%时,可以提示用户当前网络环境比较差。这个属性的值在0到1间浮动,0表示缓冲区还没有数据,1表示缓冲区已慢,每当缓冲区变化超过5%时,就会触发下面的事件。
    • BufferingProgressChanged事件:通过这个事件的处理函数我们真正有机会将缓冲状态反馈给用户。

    我们通过下面的代码进行分析:

    首先是给事件订阅处理函数,我们放在XAML中完成:

    1 <MediaElement x:Name="vid" Source="balls.wmv" BufferingProgressChanged="doBuff" 
    2 DownloadProgressChanged="doDown" 
    3 CurrentStateChanged="doState" 
    4 MarkerReached="handleMarker" 
    5 MediaOpened="handleOpened">
    6 </MediaElement>

    接下来我们可以选择在JavaScript中或是C#中来实现这个事件处理函数,首先是JavaScript的代码:

    1 function doBuff(sender, args) {
    2     var theText = sender.findName("txtBuff");
    3     var meVid = sender.findName("vid");
    4     var prog = meVid.BufferingProgress * 100;
    5     prog = "Buffering % " + prog;
    6     theText.Text = prog;
    7 }

    (以上JavaScript部分仅适用于Silverlight,下同)

    C#版本如下:

    1 private void doBuff(object sender, RoutedEventArgs e)
    2 {
    3     double prog = vid.BufferingProgress * 100;
    4     txtBuff.Text = "Buffering % " + prog;
    5 }
    • BufferingTime属性:这个属性接收一个时间段作为参数,如0:0:10,表示需要缓冲区的内容足够播放10秒时才开始播放,并始终维持一个10秒的缓冲,以避免在网络较差情况下播放不连续。

        当遇到服务端不支持流式播放,只能下载完后开始播放这样情况时,可以使用DownloadProgressChanged和DownloadProgress来监控下载状态。这两个对象的使用类似Silverlight控件的Downloader对象中类似的2个成员。稍有不同的是此处的事件和属性分别支持在C#环境下处理与访问。

    视频状态相关的属性

    CurrentState属性:表示当前多媒体的状态,可能的值有如下:

    • Buffering 缓冲区未满(媒体处于暂停状态)
    • Closed 媒体被关闭
    • Error 媒体下载,缓冲或播放中出现错误
    • Opening 媒体已找到,缓冲或下载即将开始
    • Paused 媒体播放暂停
    • Playing 媒体播放中
    • Stopped 媒体播放停止

    当这个属性变化时,会触发下面这个事件

    CurrentStateChanged事件,订阅这个事件的代码见上文XAML,下面是C#版的事件处理函数:

    1 private void doState(object sender, RoutedEventArgs e)
    2 {
    3     txtBuff.Text = vid.CurrentState;
    4 }

    同样在Silverlight中我们还可以使用JavaScript来实现回调函数:

    1 function doState(sender, args) {
    2     var meVid = sender.findName("vid");
    3     alert(meVid.CurrentState);
    4 }

    控制播放位置的成员

    • NaturalDuration属性:在媒体的CurrentState属性为Opened的状态下,这个属性被设置,NaturalDuration.Seconds属性表示视频长度,单位为秒。
    • Position属性:返回视频当前播放的位置。

    与前面的例子相同,我们可以使用C#或JavaScript(限Silverlight)中处理CurrentStateChanged事件并展示这两个属性的值。

    处理媒体的时间线标记

        使用Expression Media等软件加工媒体时可以给视频添加时间线标记,其是位于某一时间点的元数据。这个标记可以用来表示视频章节的分隔点。MediaElement播放视频过程中遇到时间线标记时会触发MakerReached事件。这个事件的参数 – TimeLineMarkerRountedEventArgs类型的e有一个Marker属性,这其中有3个比较有用的属性:

    • Time属性:TimeSpan类型,表示起点到此标记的时间跨度。
    • Type属性:字符串,返回用户编码的类型
    • Text属性:字符串,用于添加一些描述。

    下面的代码处理上述事件,并展示3个属性:

    1 private void handleMarker(object sender, TimelineMarkerRoutedEventArgs e)
    2 {
    3     string strMarkerStatus = e.Marker.Time.ToString();
    4     strMarkerStatus += "  :  ";
    5     strMarkerStatus += e.Marker.Type;
    6     strMarkerStatus += "  :  ";
    7     strMarkerStatus += e.Marker.Text;
    8 }

    同样Silverlight中可使用的JavaScript实现如下:

    1 function handleMarker(sender, args) 
    2 { 
    3    var strMarkerStatus = args.marker.time.seconds.toString(); 
    4    strMarkerStatus += "  :  "; 
    5    strMarkerStatus += args.marker.type; 
    6    strMarkerStatus += "  :  "; 
    7    strMarkerStatus += args.marker.text; 
    8    alert(strMarkerStatus); 
    9 }

        我们也可以添加时间线标记到媒体文件中,当然这段数据不会被永久保存的视频中,只是在会话过程中有效。时间线标记由TimeLineMarker类表示,只需要创建一个该类对象并设置3个属性并将其添加到MediaElement的Makers属性就可以了,我们不需要保证多个添加的标记时间按前后顺序排列,MediaElement会自动按顺序触发这些事件。比如我们可以在MediaOpened事件的处理函数中完成这个操作:

    1 private void handleOpened(object sender, RoutedEventArgs e)
    2 {
    3     TimelineMarker t = new TimelineMarker();
    4     t.Time = new TimeSpan(0, 0, 0, 10);
    5     t.Type = "My Temp Marker";
    6     t.Text = "Dynamically Added Marker";
    7     vid.Markers.Add(t);
    8 }

    同样下面给出Silverlight中JavaScript的实现:

    1 function handleOpened(sender, args) 
    2 { 
    3    var marker = 
    4    sender.getHost().content.createFromXaml(
    5       "<TimelineMarker Time='0:0:10'" + 
    6       " Type='My Temp Marker' Text='Dynamically Added Marker Marker' />"); 
    7    sender.markers.add(marker); 
    8 }

    在视频上叠加内容

        像其它XMAL元素可以相互叠加一样,可以把想要的元素,如一些文本叠加到MediaElement上,这样就变相的在视频之上的层中添加的内容,实现了一种叠加效果。

  • 相关阅读:
    python入学代码
    python安装和pycharm安装与笔记
    python预习day1
    python-tyoira基本
    Typora基础
    学习一下saltstack 服务器批量管理
    消息队列与kafka
    消息队列rabbitmq
    redis数据库在linux上的学习
    蓝绿部署、滚动发布、灰度发布的介绍以及最佳实践
  • 原文地址:https://www.cnblogs.com/lsxqw2004/p/4627642.html
Copyright © 2011-2022 走看看