自制Silverlight视频播放器(一)-VideoPlayer视频播放控件

  近期在赶一个客户的项目,采用Silverlight技术制作一个视频播放页面。目前版本基于SL 2 Beta 1开发,已初步完Demo版,现将开发所得经验分享如下:
  效果图:

(播放视频)



(鼠标放在缩略图上,显示相关说明)



(鼠标放在视频名称上,显示相关说明)



(点击缩略图视频“翻跟头”进入播放区)



(点击缩略图视频“翻跟头”进入播放区)


页面浏览:http://cms.huadublog.cn/VodSL/VodSLTestPage.html


SL自定义控件经验分享

1、VideoPlayer视频播放控件
  该控件主要功能有Play/Pause/Stop等,这些功能我认为比较简单,在此不提。主要说说如果通过Slider控件实现播放进度条的方法。
  首先创建MediaElement与Slider。
  然后分析下进度条的实现原理:
    A、如何实现Slider与播放进度的同步?答:为MediaElement设置TimelineMarker,将MarkerReached时修改Slider进度值。注意,一定要在MediaElement.MediaOpened事件中添加TimelineMarker。因为添加TimelineMarker要考虑影片的实际长度,比如说,如果想在Slider上设置100个点,那每一点代表的时间就是影片总长度的1/100。看看我的代码:

            this.slider.Minimum = 0;
            
this.slider.Maximum = 100;
            
double seconds = this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
for (int i = (int)this.slider.Minimum; i < (int)this.slider.Maximum; i++)
            
{
                TimelineMarker marker 
= new TimelineMarker();
                
double time = seconds / this.slider.Maximum * i;
                marker.Time 
= new TimeSpan(00, (int)time);
                marker.Text 
= "a";
                marker.Type 
= "Test";
                
this.mediaElement1.Markers.Add(marker);
            }

  在此需要注意的是,一定要设置marker.Type,否则您试试,一运行程序就崩溃了。呵呵。
  好了,接下来在MediaElement.MarkerReached事件中添加以下代码:

            double time= e.Marker.Time.TotalSeconds;
            
double seconds= this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
if (seconds <= 0)
            
{
                
return;
            }

            
double marker = (time * this.slider.Maximum / seconds);
            txtSlider.Text 
= e.Marker.Time.Hours + ":" + e.Marker.Time.Minutes + ":" + e.Marker.Time.Seconds;
            
this.slider.Value = marker;

  在此,我们根据当前Marker的时间点与总时长算出播放时间占总时间的比例,然后计算出Slider当前应该的进度值。就OK了,如果要显示当前时长的话,只要txtSlider.Text = e.Marker.Time.Hours + ":" + e.Marker.Time.Minutes + ":" + e.Marker.Time.Seconds;即可。

  然后我们再实现进度条的拖拽功能。
  在Slider.ValueChanged事件中添加以下代码:

            double seconds = this.mediaElement1.NaturalDuration.TimeSpan.TotalSeconds;
            
double time = seconds / this.slider.Maximum * this.slider.Value;
            mediaElement1.Position 
= new TimeSpan(00,(int) time);

  一切搞定!
  不过细心的你可能会发现一个问题,那就是MediaElement.MarkerReaded可以改变Slider.Value,而Slider.Value的改变又会引发Slider.ValueChanged,该事件中又有MediaElement.Position=v,这又会引发MediaElement.MarkerReaded,呵呵,死循环吧,没关系,自己加一个信号变量就行了。这我不再详述了。
  

posted on 2008-04-25 14:58  snowwolflibo  阅读(3570)  评论(6编辑  收藏  举报