在Silverlight中使用SmoothStreamingMediaElement创建Smooth Streaming播放器

我在“IIS 7 Smooth Streaming技术在Silverlight 3中的应用 ”一文中详细介绍了有关IIS 7、Smooth Streaming技术以及如何在Silverlight中使用MediaElement控件播放Smooth Streaming视频的内容,在继续本文之前,如果你对什么是Smooth Streaming还存在疑问,你可以先去看看我的那篇文章,也算作是一个入门吧。

  在本文中,我将向大家介绍一个新控件——SmoothStreamingMediaElement,也被称之为SSME,它是IIS Smooth Streaming Player Development Kit工具包中的一个Silverlight控件,是在原MediaElement控件基础上的功能加强,主要增加了对Smooth Streaming视频源的直接支持以及一些相关事件。大家可以去微软的官方站点上下载该工具包,目前已经出到Beta2版了。

  在上一文中我向大家介绍了如何利用现有的MediaElement控件来支持Smooth Streaming视频的播放,事实上这种方法具有很大的局限性,例如控制播放进度、添加视频播放时的tracing事件等等。SmoothStreamingMediaElement控件作为MediaElement控件的一个加强版本,正好弥补了这方面的不足,同时,该控件也支持普通视频文件的播放。你当然还记得Smooth Streaming官方站点上的那个Big Buck Bunny演示影片,或许你也想知道它是怎么实现的,不要着急,在接下来的一系列文章中将会花点篇幅来向大家介绍,今天我们主要看看如何使用SSME控件,因为Big Buck Bunny的核心控件就是SSME。

 

需要些什么

  1. 既然是开发一个Silverlight工程,那么首先Visual Studio和Silverlight Tool kits是肯定需要的,这点我就不详细介绍了,相信大家的这个环境都是具备的,如果不具备,可以去微软官网上找相关的资源。

  2. IIS Smooth Streaming Player Development Kit。目前的版本应该是Beta2版,下载后安装,你会发现Microsoft.Web.Media.SmoothStreaming.dll,这个正是我们所需要的。

  3. 另外就是一些开发Silverlight所要具备的知识了,如果你从未开发过Silverlight程序并且对Silverlight一无所知,那么我建议你不要继续往下看了。

 

如何开始

  现在我们应该就可以着手开始我们的工程了。首先在Visual Studio中创建一个Silverlight工程,如下图。

2010-1-21 13-58-19

   然后将Microsoft.Web.Media.SmoothStreaming.dll拷贝到你Silverlight工程的Bin\Debug\目录下(注意在Visual Studio中创建Silverlight项目时会同时创建一个用来进行测试的Web项目,不用将该文件复制到Web项目的Bin目录下),将该类库引用到Silverlight工程中。

  然后我们需要将SSME控件添加到MainPage.xaml页面上,有两种方法,第一种方法是在Visual Studio的工具箱中单击右键-“选择项”,在弹出的对话框中选择“Silverlight组建”选项卡,然后点击“浏览”,找到Microsoft.Web.Media.SmoothStreaming.dll文件,确定并关闭对话框,这时控件SSME会出现在Visual Studio的工具箱中,你可以直接将该控件拖放到页面上。这和在Visual Studio中添加普通的ASP.NET自定义控件是一样的。

2010-1-21 14-05-50
  另一种方法是在页面中手动注册并引用控件。打开MainPage.xaml,在页面的头部添加下图所示的内容,Visual Studio的智能感知可以帮助你快速找到你要引用的命名空间。然后你在页面上就可以直接使用SSME命名空间下的控件了,其中就包含了SmoothStreamingMediaElement控件。

image

 

熟悉下SSME控件的常用属性和事件

  有必要先向大家介绍下SSME控件中一些常用的属性和事件,由于该控件没有包含在任何一个版本的Silverlight标准类库中,目前还只是一个测试版,所以微软官方提供的资料很少,在msdn上虽然能够见到它的身影,但是几乎没有任何示例和相关解释,读者可以查看一下它都包含哪些东西,http://msdn.microsoft.com/en-us/library/microsoft.web.media.smoothstreaming.smoothstreamingmediaelement_members.aspx。在这里我给出一些常用的属性和方法,如果你对MediaElement控件很熟悉,那么非常好,你可以毫不费力地过渡到SSME上,因为SSME几乎支持了MediaElement控件的全部属性和方法。

  AutoPlay:与MediaElement不同,除非你显示指定AutoPlay的值为True,否则即使SSME已经成功打开的视频源也不会自动播放视频。

  Source:播放普通视频文件时的地址。

  SmoothStreamingSource:播放Smooth Streaming视频文件时的地址。

  VideoPlaybackTrack.Bitrate:通过该值可以得到SSME当前播放影片的比特率,如果SSME当前播放的是Smooth Streaming格式的影片,那么比特率会随网络带宽动态发生变化。

  VideoDownloadTrack.Bitrate:同样的,通过该值可以得到当前下载影片的比特率。

  RenderedFramesPerSecond:通过该值可以得到当前播放影片的帧率(即每秒播放多少帧)。

  PlaybackTrackChanged:当播放影片的比特率发生变化时触发。

  DownloadTrackChanged:当下载影片的比特率发生变化时触发。

  细心的读者是否已经发现,我们通过上面给出的这些属性和事件,加上Silverlight里的路径动画,是不是就可以构造一个类似于Big Buck Bunny的播放器呢?先别着急,我们还是先熟悉熟悉SSME吧,我打算在下一篇文章中再来介绍那个让人找摸不透的播放器呢。

 

继续完善我们的SSME播放器

  接着进行我们的工程。知道如何在工程中加入SSME了,下面你可以试着将这段代码复制到你的MainPage.xaml页面中。 

复制代码
< UserControl  x:Class ="SmoothStreamingPlayer.MainPage"  
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"  xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"  
    xmlns:SSME
="clr-namespace:Microsoft.Web.Media.SmoothStreaming;assembly=Microsoft.Web.Media.SmoothStreaming"  
    mc:Ignorable
="d"  d:DesignWidth ="640"  d:DesignHeight ="480" >  
  
< Grid  x:Name ="LayoutRoot" >  
        
< Grid.RowDefinitions >  
            
< RowDefinition  Height ="0.90*" ></ RowDefinition >  
            
< RowDefinition  Height ="0.05*" ></ RowDefinition >  
            
< RowDefinition  Height ="0.05*" ></ RowDefinition >  
        
</ Grid.RowDefinitions >  
        
< SSME:SmoothStreamingMediaElement  AutoPlay ="True"  x:Name ="SmoothPlayer" SmoothStreamingSource ="http://localhost:77/Wildlife.ism/manifest"  Grid.Row ="0" />  
    
</ Grid >  
</ UserControl >
复制代码

  注意SmoothStreamingSource的值应当指定为一个你事先已经准备好的Smooth Streaming视频源,如果这个视频源不在本地,你可能需要添加跨域访问的代码,有关如何创建Smooth Streaming视频源以及如何架设Smooth Streaming视频服务,请参考“IIS 7 Smooth Streaming技术在Silverlight 3中的应用”一文。

  好了,按下F5,启动工程直接查看效果,你会发现浏览器中除了一块黑色外并没有播放你所指定的影片,怎么回事啊?难道视频地址给错了?首先请确保你所给出的地址可以通过浏览器直接访问,得出的结果应该类似于下面这样的画面:

2010-1-21 14-59-08

  如果不能通过浏览器直接访问,那你就要检查你的视频服务了,或许你需要通过Expression Encoder重新转换视频并发布到IIS 7上。如果可以通过浏览器直接访问,那么恭喜你,你所看到的黑色画面是正常的。还记得我在上一文中说过调试Smooth Streaming播放器时只能通过IIS 7,而不能直接通过Visual Studio或者Blend吗?所以你不得不在你机器的IIS 7上部署一个Web站点,然后将用来进行测试的Web工程中的所有文件复制到Web站点中,然后通过浏览器进行访问。

  如果一切顺利的话,你应该可以在你的浏览器中看到影片了,仔细观察影片,你会看到一开始的时候画面是比较模糊的,但是SSME可以根据网络带宽动态调整画面质量,随着影片的播放,你会发现画面越来越清晰了。如果你仍然看不到影片,可能会有几个原因,首先还是视频服务的问题,你需要重新去确认视频服务是否可用并能正常访问;然后是权限的问题,你可以试着将浏览器地址中的localhost改为你的机器名,然后重新刷新浏览器,或者修改Silverlight工程中SSME的SmoothStreamingSource的地址,将其中的localhost改为你的机器名(如果你使用的是本地的视频源),如果视频源和Web站点都在同一台机器上,你应该同时使用localhost或是机器名。下面是在我本地看到的影片的播放效果:

2010-1-21 15-10-09

 

添加播放控制部分

  当然,一个像样的播放器是需要有播放控制面板的,我打算在我们的SSME播放器上添加一个播放进度条、音量控制、开始/暂停按钮、停止按钮。添加控件后的xaml代码如下:

复制代码
< UserControl
    
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"  xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:SSME
="clr-namespace:Microsoft.Web.Media.SmoothStreaming;assembly=Microsoft.Web.Media.SmoothStreaming"
    mc:Ignorable
="d"  xmlns:dataInput ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class ="SmoothStreamingPlayer.MainPage"
    d:DesignWidth
="640"  d:DesignHeight ="480" >
    
< Grid  x:Name ="LayoutRoot" >
        
< Grid.RowDefinitions >
            
< RowDefinition  Height ="0.90*" />
            
< RowDefinition  Height ="0.05*" />
            
< RowDefinition  Height ="0.05*" />
        
</ Grid.RowDefinitions >
        
< SSME:SmoothStreamingMediaElement  AutoPlay ="True"  x:Name ="SmoothPlayer"  Grid.Row ="0" />
        
< Slider  x:Name ="playSlider"  Grid.Row ="1"  Cursor ="Hand"  Maximum ="100" />
        
< ToggleButton  x:Name ="playToogleButton"  Grid.Row ="2"  HorizontalAlignment ="Left"  Margin ="8,0,0,4"  Width ="33"  Content ="暂停"  Height ="20"  Cursor ="Hand" />
        
< Slider  Margin ="115,4,0,8"  Grid.Row ="2"  HorizontalAlignment ="Left"  Width ="65"  x:Name ="volumeSlider"  Cursor ="Hand"  Maximum ="1"  Value =" {Binding Path=Volume, ElementName=SmoothPlayer, Mode=TwoWay} "   />
        
< dataInput:Label  HorizontalAlignment ="Left"  Margin ="87,3,0,5"  Width ="29"  Grid.Row ="2"  Content ="音量" />
        
< Button  x:Name ="stopButton"  HorizontalAlignment ="Left"  Margin ="45,0,0,4"  Grid.Row ="2"  Content ="停止"  Width ="33"  Height ="20"  Cursor ="Hand" />
    
</ Grid >
</ UserControl >
复制代码

   SSME的SmoothStreamingSource改到后台去指定了,为的是方便在Blend中打开Silverlight工程,因为Blend会默认在页面打开的时候自动加载视频并生成缩略图,由于我们指定的播放地址不是普通地址,视频加载的时候Blend会报错,导致页面无法在Blend中打开。

  UI界面已经完成了,尽管比较难看!说老实话,我也不是美工出身,对界面这方面也不是很在行。下面的工作就是让这些控件能够发挥作用,我将我的代码给出来,大家可以做个参考。

复制代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;
using  System.Windows.Controls.Primitives;

namespace  SmoothStreamingPlayer
{
    
public   partial   class  MainPage : UserControl
    {
        
private   const   string  VIDEOSOURCE  =   " http://localhost:77/Wildlife.ism/manifest " ;
        
private  TimeSpan _duration;

        
public  MainPage()
        {
            InitializeComponent();
            InitialPlayer();
        }

        
// 初始化属性和事件
         private   void  InitialPlayer()
        {
            
this .SmoothPlayer.SmoothStreamingSource  =   new  Uri(VIDEOSOURCE);
            
// this.SmoothPlayer.Source = new Uri(VIDEOSOURCE);

            
this .playToogleButton.Click  +=   new  RoutedEventHandler(playToogleButton_Click);
            
this .stopButton.Click  +=   new  RoutedEventHandler(stopButton_Click);
            
this .playSlider.ValueChanged  +=   new  RoutedPropertyChangedEventHandler < double > (playSlider_ValueChanged);

            
this .SmoothPlayer.MediaOpened  +=   new  RoutedEventHandler(SmoothPlayer_MediaOpened);
            
this .SmoothPlayer.MediaEnded  +=   new  RoutedEventHandler(SmoothPlayer_MediaEnded);
            
this .SmoothPlayer.MarkerReached  +=   new  TimelineMarkerRoutedEventHandler(SmoothPlayer_MarkerReached);
        }

        
// 拖动播放进度条
         void  playSlider_ValueChanged( object  sender, RoutedPropertyChangedEventArgs < double >  e)
        {
            
double  time  =  _duration.TotalSeconds  /  playSlider.Maximum  *  playSlider.Value;
            
this .SmoothPlayer.Position  =   new  TimeSpan( 0 0 , ( int )time);
        }

        
// 停止播放
         void  stopButton_Click( object  sender, RoutedEventArgs e)
        {
            
this .SmoothPlayer.Stop();
            playSlider.Value 
=   0 ;
            playToogleButton.IsChecked 
=   true ;
            playToogleButton.Content 
=   " 播放 " ;
        }

        
// 播放/暂停
         void  playToogleButton_Click( object  sender, RoutedEventArgs e)
        {
            ToggleButton button 
=  (ToggleButton)sender;
            
if  (button.IsChecked  ==   true   &&   this .SmoothPlayer.CanPause)
            {
                
this .SmoothPlayer.Pause();
                
this .playToogleButton.Content  =   " 播放 " ;
            }
            
if  (button.IsChecked  ==   false )
            {
                
this .SmoothPlayer.Play();
                
this .playToogleButton.Content  =   " 暂停 " ;
            }
        }

        
// 控制播放进度条
         void  SmoothPlayer_MarkerReached( object  sender, TimelineMarkerRoutedEventArgs e)
        {
            
this .Dispatcher.BeginInvoke( delegate ()
            {
                
double  time  =  e.Marker.Time.TotalSeconds;
                
double  seconds  =   this .SmoothPlayer.NaturalDuration.TimeSpan.TotalSeconds;
                
if  (seconds  <=   0 )
                {
                    
return ;
                }
                
double  marker  =  (time  *  playSlider.Maximum  /  seconds);
                playSlider.Value 
=  marker;
            });
        }

        
// 影片播放完后停止播放器并重置进度条
         void  SmoothPlayer_MediaEnded( object  sender, RoutedEventArgs e)
        {
            
this .SmoothPlayer.Stop();
            playSlider.Value 
=   0 ;
            playToogleButton.IsChecked 
=   true ;
            playToogleButton.Content 
=   " 播放 " ;
        }

        
// 影片打开后初始化进度条
         void  SmoothPlayer_MediaOpened( object  sender, RoutedEventArgs e)
        {
            _duration 
=   this .SmoothPlayer.NaturalDuration.HasTimeSpan  ?   this .SmoothPlayer.NaturalDuration.TimeSpan : TimeSpan.FromMilliseconds( 0 );
            
this .SmoothPlayer.Volume  =   0.8 ;

            playSlider.Minimum 
=   0 ;
            playSlider.Maximum 
=   10 ;
            
for  ( int  i  =  ( int )playSlider.Minimum; i  <  ( int )playSlider.Maximum; i ++ )
            {
                TimelineMarker marker 
=   new  TimelineMarker();
                
double  time  =  _duration.TotalSeconds  /  playSlider.Maximum  *  i;
                marker.Time 
=   new  TimeSpan( 0 0 , ( int )time);
                marker.Text 
=   string .Empty;
                marker.Type 
=   string .Empty;
                
this .SmoothPlayer.Markers.Add(marker);
            }
        }
    }
}
复制代码

   其中播放进度条的控制使用了TimelineMarker,由于我要播放的影片是Win7自带的一个高清视频演示文件,播放时长比较短,所以我将Maximum的值设得比较小,你可以根据影片的长短来设定该值。另外,我在程序中将播放地址hard-code到代码里了,你完全可以通过页面上的InitParams参数将播放地址传进来,也或者你可以将播放参数写到playlist里作为xml传进来。

  好了,一切搞定!现在你可以在浏览器中预览SSME播放器啦,下面是在我机器上看到的效果。

2010-1-21 16-29-00

 

结语

  使用SSME可以非常方便地支持Smooth Streaming视频的播放,Silverlight程序员几乎不用做任何额外的工作就可以让自己的Silverlight播放器支持Smooth Streaming视频流,同时,你可以在程序中做出判断以决定让SSME播放普通的视频还是Smooth Streaming视频。接下来的内容我将向大家介绍如何利用SSME并结合FrameRateGraph、BitrateGraph等控件实现一个完整的Big Buck Bunny播放器。



本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2010/01/21/1653314.html,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值