Silverlight视频播放器

Silverlight视频播放器,第1张

概述播放服务器端的视频      图2-4 自定义的Silverlight视频播放器        这个实例设计了1个自定义的Silverlight视频播放器(视频源文件放在服务器端),如图2-4所示,这个示例完全在Expression Blend 4中设计,视频放在服务器端的文件夹中,网上调试成功。示例设计的复杂一点,当然功能也强,如果减少功能程序也会简单。图2-4上方是视频播放控件MediaEle

播放服务器端的视频

    

图2-4 自定义的Silverlight视频播放器

       这个实例设计了1个自定义的Silverlight视频播放器(视频源文件放在服务器端),如图2-4所示,这个示例完全在Expression Blend 4中设计,视频放在服务器端的文件夹中,网上调试成功。示例设计的复杂一点,当然功能也强,如果减少功能程序也会简单。图2-4上方是视频播放控件MediaElement(me);下方是需要播放的视频图片,点击可以选择视频源;中间有1个视频播放控制面板,Silverlight视频控件MediaElement有边下载边播放的功能,图2-5中间有个播放进度条,同时显示下载进度和播放进度;进度条上方的2个文本分别显示下载缓冲比例和播放器的当前状态,进度条下方的文本框显示视频播放的时间进度值;进度条上方右侧有1个三角形音量控制图标,点击就可以选择音量,喇叭图标是“静音”控制图标,点击1次变化1次,静音时喇叭图标上出现1个红色“×”;

 

图2-5 自定义的Silverlight视频播放器控制板

    当鼠标悬浮在进度条上时,先出现文本(Callout控件)显示,显示进度条当前值对应的视频时间,只要鼠标悬浮不动就会出现1个视频预览窗口(也是MediaElement控件,名为prevIEw),可以看到此时对应的视频画面(反复播放当前画面2秒,仅几帧);进度条下方有“暂停”、“播放”、“停止”、“重播”和“全屏”等控制图标。下面说明设计过程。

1、界面设计

    新建1个“Silverlight应用程序+网站”项目,名称为SilverlightmediaPlayer,设置界面对中:改变“LayoutRoot”的布局类型为“ScrollVIEwer”,放入Canvas(canvas1),设置其背景和大小,设置“UserControl”的WIDth和Height属性为自动。

2、me控件属性设置

    “布局”中WIDth:448   Height:252,相当于16:9。

    “媒体”中Stretch:UniformToFill。me控件放置在Canvas布局控件canvas1中,这对me的位置和尺寸变化很重要。

3、音量控制设置

    图2-5右侧的音量控制图标表面看是三角形的,实际上它是1个矩形Progressbar控件(命名为volume),但其左上角部分用1个和背景颜色(黑色)一致的Path(用钢笔工具手绘)覆盖,看到的是三角形。volume和Path组合在grID3中。

    volume控件属性设置(“公共属性”栏目中):

    Maximum:1             Minimum:0

    volume控件的Value属性(默认值改设为0.6,原来是0.5)采用数据绑定设置:在【属性】面板的“公共属性”栏中选Value属性—鼠标左键点击右侧的白色方块(高级选项),在d出的菜单中选择“数据绑定”,这时出现“创建数据绑定”窗口,选择“元素属性”页面,左侧场景元素中选“me”控件,右侧属性中选Value,点“确定”键完成设置。me控件的音量将跟随volume控件的Value变化。

    喇叭图标由图形组合而成,最后组合在GrID控件(mute)中,构成静音/播音反复控制,如果处于静音喇叭图标上又多出红色“×”(组合在grID5中),程序如下。

 

  //音量控制                private voID volume_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    //获取Progressbar控件对应的音量值           this.me.Volume=e.Getposition(this.volume).X/this.volume.ActualWIDth;                          }               //静音控制                private voID mute_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.IsMuted=!this.me.IsMuted;                    if (this.me.IsMuted)                         //如果是静音,显示红色×                         this.grID5.Visibility=Visibility.Visible;                    else                         this.grID5.Visibility=Visibility.Collapsed;                }         

4、进度条设置和预览窗口

    MediaElement控件本身有边下载边播放的功能,这里使用图图2-5中间的进度条控件Progressbar(名为progressbar)的进度值显示视频下载进度,同时又在其中附加了1个矩形控件(名为vernIEr,红色)作为游标用于显示播放进度,这2个控件组合放置在Canvas中(名为canvas2),canvas2的大小和progressbar一致,这样方便游标vernIEr的位置设置。当点击进度条时视频就会选择从点击处对应的视频位置开始播放。另外有3个文本框分别显示下载的缓冲进度(textblock1)、播放器当前状态(textblock2)和视频播放时的时间进度(textblock3)。

    关于缓冲进度:当me控件的属性Source被赋值后,自动产生下载缓冲过程,下载缓冲时间属性BufferingTime默认值是00:00:05(5秒,在“媒体”属性栏目中),此值的大小会影响视频播放的平滑程度,当然和网络速度也有关,本实例中设置500ms:

    this.me.BufferingTime=TimeSpan.FromMilliseconds(500);

    但实际的缓冲值在0-1之间变化,乘以100后相当于百分比,1个100%应当对应1个下载缓冲时间,1个视频的下载可能要经过若干个这样的过程。而且当1个缓冲完成时自动产生BufferProgressChanged事件,缓冲的显示正是在此事件的程序中设计的。

    缓冲变化会使视频文件下载进度变化,而此变化也会产生DownloadProgressChanged事件,可以在其中编写程序显示下载进度属性DownloadProgress的变化值(0-1之间)。

    关于播放器状态,MedaIElement控件在视频下载和播放时有如下状态:

    Buffering、Closed、opening、Paused、Playing 或 Stopped。默认值为 Closed,这些状态根据英文就能理解它的含义,不再解释。状态的显示也是在此BufferProgressChanged事件程序中设计的。

    图2-4下方有5个图形图标,代表5个视频,当点击时就会产生下载播放过程,下面以点击左边的图标“机场”为例,看如何编写程序的。

 

  //播放"机场"视频                private voID image1_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {           //定时器停止,定时器的作用后面介绍                    timer.Stop();           //下载进度值回0                    this.progressbar.Value=0;                    //获取当前浏览位置定位(含网页文件名称),如:http://localhost:2277/Default.HTML                    uri=System.windows.browser.HTMLPage.document.documentUri.ToString();                    //LastIndexOf("/"):搜寻定位中右边最后1个"/"的位置,其左侧是不含网页文件的定位                //形成服务器视频文件的位置信息                    vIDeoname=uri.Substring(0,uri.LastIndexOf("/")+1)+"vIDeo/vIDeo1.wmv";                    //设置视频播放控件的视频源                    this.me.source=new Uri(vIDeoname,UriKind.relativeOrabsolute);           //设置预览视频源,后面会介绍视频预览                    thisthis.prevIEw.source=this.me.source;                    this.prevIEw.Stop();                    //设置视频文件打开后的事件                    this.me.MediaOpened+=new RoutedEventHandler(meOpened);                    //设置下载进度变化事件                    this.me.DownloadProgressChanged+=new RoutedEventHandler(meDownload);           //设置下载缓冲时间                    this.me.BufferingTime=TimeSpan.FromMilliseconds(500);                    //设置下载缓冲变化的事件                this.me.BufferingProgressChanged+=new RoutedEventHandler(me_BufferingProgressChanged);                }           //下载进度显示                private voID meDownload(object sender, System.windows.RoutedEventArgs e)                {                    //DownloadProgress是下载进度,变化范围0-1                    thisthis.progressbar.Value=this.me.DownloadProgress*this.progressbar.Maximum;                }                //下载缓冲变化显示                double bp=0;                private voID me_BufferingProgressChanged(object sender,RoutedEventArgs e){                    //BufferingProgress:缓冲变化值0-1                    bp=this.me.BufferingProgress*100;                    this.textblock1.Text="下载缓冲进度:"+bp.ToString()+"%";                     this.textblock2.Text="播放器当前状态:"+me.CurrentState.ToString();                }           //文件打开后定时器启动                private voID meOpened(object sender, System.windows.RoutedEventArgs e)                {                    timer.Start();                }           //当点击进度条时,选择视频播放位置                private voID progressbar_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.Pause();                    this.me.position=TimeSpan.FromSeconds(currentlength);                    this.me.Play();                }               在本机实际调试时,可能看不到缓冲变化和播放状态,但是如果放到服务器上调试就会很明显,本实例已经在网络服务器上调试验证。               以上的程序大多数代码在前面已经有了解释,还有视频预览prevIEw和定时器timer没有涉及到。               PrevIEw也是1个MediaElement控件(和边框矩形设计一起组合在canvas2的grID4中),当视频已经下载并播放时,如果鼠标悬停在进度条上立刻显示视频对应的时间,如果鼠标停止不动一段时间(比如2秒),会自动d出视频预览窗口,看到的是鼠标悬停处对应的视频,此预览只反复播放悬停处的几帧视频图像。鼠标离开或变化位置自动停止,这点和目前网上看到的有的视频播放器的效果是一样的。           这里用到时间控制,由定时器来完成,程序如下:           private dispatcherTimer timer=new  dispatcherTimer();           //定义变量,用于视频源地址和文件位置信息变量                string uri,vIDeoname;                public MainPage()                {                    InitializeComponent();           //Esc键提示关闭                    this.Esctext.Visibility=Visibility.Collapsed;           //进度条当前位置显示文本框关闭                    this.cp.Visibility=Visibility.Collapsed;           //预览窗口关闭                    this.grID4.Visibility=Visibility.Collapsed;                    timer.Interval=TimeSpan.FromMilliseconds(500);                    timer.Tick+=new EventHandler(timerarrive);           //设置视频播放进度游标初始位置                    Canvas.Setleft(this.vernIEr,0);                    Canvas.Settop(this.vernIEr,0);                           }                //定时器定时访问程序           //视频时间总长度和视频进度条当前值变量                double melength=0,currentvalue;           //记忆鼠标悬停位置                double movevalue=0;           //悬停不动时间计数和预览时间计数                double times=0,prevIEwtimes=0;           //鼠标移动                bool move=false;                private voID timerarrive(object sender,EventArgs e){           //获取视频时间总长度                    memelength=me.NaturalDuration.TimeSpan.TotalSeconds;                    //视频进度条当前值=视频进度条最大值*视频当前位置时间/视频时间总长度                    currentvalue=this.progressbar.ActualWIDth*me.position.TotalSeconds/melength;           //设置视频进度游标位置                    Canvas.Setleft(this.vernIEr,currentvalue);           //获取视频当前位置时间小时值、分值、秒值                     int h=me.position.Hours;                    int m=me.position.Minutes;                    int s=me.position.Seconds;           //下面使用了C#的条件运算符<条件>?<满足条件时>:<不满足条件时>                   this.textblock3.Text="播放时间进度:"+(h<10? "0"+h.ToString():h.ToString())+":"                                 +(m<10? "0"+m.ToString():m.ToString())+":"                                 +(s<10? "0"+s.ToString():s.ToString());                    //预览视频处理                    if (times<4)           //计数控制+1(位置不变的次数)                        times++;                         if (times==1){                             //取当前鼠标X位置                             movevalue=progressbarX;           }           //如果鼠标滑动在进度条且X坐标没有变化,且计数达4次                         if (move && movevalue==progressbarX){                              if (times==4){           //开启预览窗口                                  this.grID4.Visibility=Visibility.Visible;                                  //如果预览窗口当前处于播放状态                                  if (this.prevIEw.CurrentState==MediaElementState.Playing){           //预览时间控制计数                                       prevIEwtimes++;           //达到预览时间                                       if (prevIEwtimes==4)           //暂停预览                                            this.prevIEw.Pause();                                                      }else{           //设置预览视频位置                                   this.prevIEw.position=current;           //启动视频预览,且设置预览时间控制计数回0                                  this.prevIEw.Play();                                  prevIEwtimes=0;           }                              }                    }else{                         //关闭预览窗口,同时位置不变的次数计数回0                         this.grID4.Visibility=Visibility.Collapsed;                         times=0;           }                             }               定时访问程序中用到的一些变量,如progressbarX、move等,和下列程序有关:           //定义变量,用于当前位置时间值和鼠标X坐标                double currentlength,progressbarX;           //进度条鼠标悬停处的时间                TimeSpan current;           //鼠标悬停在进度条上方,进度条当前位置时间显示                private voID progressbar_MouseMove(object sender, System.windows.input.MouseEventArgs e)                {                     //事件引发者是Progressbar控件                    Progressbar pb=sender as Progressbar;           //视频时间总长度                    memelength=me.NaturalDuration.TimeSpan.TotalSeconds;                    //进度条当前位置时间值      currentlength=melength*e.Getposition(this.progressbar).X/this.progressbar.ActualWIDth;                    int h=(int)currentlength/3600;                    int m=(int)((currentlength600)/60);                    int s=(int)((currentlength600)`);           //设置视频进度游标位置                    Canvas.Setleft(this.cp,e.Getposition(this.progressbar).X-30);                     Canvas.Setleft(this.grID4,e.Getposition(this.progressbar).X-54);                     //当前位置显示使用Callout(cp)控件                    this.cp.Visibility=Visibility.Visible;                    this.cp.Content=(h<10? "0"+h.ToString():h.ToString())+":"                                    +(m<10? "0"+m.ToString():m.ToString())+":"                                   +(s<10? "0"+s.ToString():s.ToString());                    current=TimeSpan.Parse(this.cp.Content.ToString());                    move=true;                    progressbarX=e.Getposition(this.progressbar).X;                           }                //鼠标离开进度条                private voID progressbar_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                     //关闭预览,关闭进度条当前位置时间显示                    this.grID4.Visibility=Visibility.Collapsed;                    this.cp.Visibility=Visibility.Collapsed;           //停止鼠标移动                    move=false;           //鼠标悬停不动时间计数置0,鼠标悬停位置回0                    times=0;                    movevalue=0;           //预览播放停止,预览计数回0                    this.prevIEw.Stop();                    prevIEwtimes=0;           }           5、播放控制               对视频的“暂停”、“播放”、“停止”、“重播”等控制图标采用了故事板动画,当鼠标悬停在这些图标上时颜色发生变化(本例变为绿色),程序比较简单:           //暂停按钮控制                private voID pause_MouseEnter(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard1.Begin();                }                private voID pause_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard1.Stop();                }                private voID pause_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.Pause();                }                //播放按钮控制                private voID play_MouseEnter(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard2.Begin();                }                private voID play_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard2.Stop();                }                private voID play_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.Play();                }                //停止按钮控制                private voID stop_MouseEnter(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard3.Begin();                }                private voID stop_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard3.Stop();                }                private voID stop_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.Stop();                }                //重播按钮控制                private voID replay_MouseEnter(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard4.Begin();                }                private voID replay_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard4.Stop();                }                private voID replay_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    this.me.Stop();                    this.me.Play();           }           6、全屏播放控制               Silverlight本身有全屏播放的控制语句:           Application.Current.Host.Content.IsFullScreen=!Application.Current.Host.Content.IsFullScreen;           但是,此语句控制的是当前显示界面的全屏显示,而我们只希望视频部分全屏播放,本实例中编程先将视频放到浏览器的“全屏”(浏览器菜单和工具条保留)大小(程序设计指定按Esc键恢复原始大小),然后再使用上述语句放大到全屏,此语句默认并提示按Esc取消全屏,这样当程序运行时第一次按Esc键实际恢复到浏览器“全屏”,第二次再按Esc键恢复到原始大小,程序如下。           //全屏控制                private voID fullscreen_MouseEnter(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard5.Begin();                }                private voID fullscreen_MouseLeave(object sender, System.windows.input.MouseEventArgs e)                {                    this.Storyboard5.Stop();                }                //定义变量,记忆初始值                double canvas1W,canvas1H,meW,meH,meleft,metop;                private voID fullscreen_MouseleftbuttonDown(object sender, System.windows.input.MousebuttonEventArgs e)                {                    //视频播放时才能使用全屏 *** 作                    if (this.me.CurrentState==MediaElementState.Playing){           //记忆Canvas(me控件的容器)的原始大小                    canvas1W=this.canvas1.ActualWIDth;                    canvas1H=this.canvas1.ActualHeight;                    //记忆me控件的原始大小,以及me控件的原始位置           meW=this.me.ActualWIDth;                    meH=this.me.ActualHeight;                    meleft=Canvas.Getleft(me);                    metop=Canvas.Gettop(me);                     //布局控件放大到当前应用程序(在浏览器中)界面大小                    this.canvas1.WIDth=Application.Current.Host.Content.ActualWIDth;                    this.canvas1.Height=Application.Current.Host.Content.ActualHeight;           //设置me控件层次到上层(20是界面元素个数最大值,实际没有这么多)                     Canvas.SetZIndex(me,20);                    //视频控件也放大到当前应用程序界面大小                    thisthis.me.WIDth=this.canvas1.WIDth;                    thisthis.me.Height=this.canvas1.Height;           //视频控件位置设置                    Canvas.Setleft(me,0);                    Canvas.Settop(me,0);           //使用按Esc键提示,以及按Esc键提示框位置,并将提示框放置最上层                    this.Esctext.Visibility=Visibility.Visible;                    Canvas.Setleft(Esctext,0);                    Canvas.Settop(Esctext,0);                    Canvas.SetZIndex(Esctext,21);                    //设置按Esc键事件(自定义)                    Application.Current.RootVisual.KeyDown += new KeyEventHandler(ESC_Down);                    //使用Silverlight的全屏控制Application.Current.Host.Content.IsFullScreen=!Application.Current.Host.Content.IsFullScreen;                     }                }                private voID ESC_Down(object sender, KeyEventArgs e)                {                      //如果按下Esc键                    if (e.Key.ToString()=="Escape"){           //Esc键提示框关闭,恢复布局原始大小                         this.Esctext.Visibility=Visibility.Collapsed;                                       this.canvas1.WIDth=canvas1W;                        this.canvas1.Height=canvas1H;           //恢复me控件原始大小,置于底层,并恢复原始位置                         this.me.WIDth=meW;                         this.me.Height=meH;                         Canvas.SetZIndex(me,0);                        Canvas.Setleft(me,meleft);                         Canvas.Settop(me,metop);                    }    
总结

以上是内存溢出为你收集整理的Silverlight视频播放器全部内容,希望文章能够帮你解决Silverlight视频播放器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1068189.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存