一个silverlight播放器的DEMO(Expression Encoder 2)

    因为这个DEMO的演示用到了Expression Encoder, 而相关下载链接, 请点击这里。      

     原文中的老外因为不满足于Expression Encoder所提供的模板代码,他认为在媒体列表中应该实现点播的效果。而
不仅仅是“一味”的顺序播放。因此他在Expression Encoder代码生成的基础上,对Xaml和js文件都做了相应改动。下面
我们来看一下他所开发的主要流程。


     首先使用Expression Encoder来创建一个项目,并将其模板设置为"Expression" (因为本人不喜欢这个模板,所以在DEMO中使用了"Executive"模板),然后单击Import按钮来选择要播放的视频文件。如下图所示。最后单击“Encode”进行编码转换(当转换成功后会启动一个测试页面进行演示,“Preview In Brower”需勾选)。



     这样我们就可以在“Directory”设置项中下找到我们所生成的所有项目文件了。

    因为模板文件生成的XAML中不带播放列表,所以要修改XAML文件中
 Canvas 的高度,并将下面的XAML代码(播入列表代码)放在该文件的结尾处:

<!--  Playlist region starts here  -->
<!--  Navigation Arrows   -->
< Path  x:Name ="LeftArrow"  Opacity ="0.74"  Width ="38"  Height ="38"  Stretch ="Fill"  Stroke ="#FF000000"  
Canvas.Left
="11"  Canvas.Top ="514"  Data ="M37.5,0.5 L37.5,37.5 0.5,37.5 z"  Fill ="#FFFFFFFF"  
RenderTransformOrigin
="0.5,0.5"  Cursor ="Hand" >
    
< Path.RenderTransform >
        
< TransformGroup >
            
< ScaleTransform  ScaleX ="1"  ScaleY ="1" />
            
< SkewTransform  AngleX ="0"  AngleY ="0" />
            
< RotateTransform  Angle ="134.119" />
            
< TranslateTransform  X ="0"  Y ="0" />
        
</ TransformGroup >
    
</ Path.RenderTransform >
</ Path >
< Path  x:Name ="RightArrow"  Opacity ="0.74"  Width ="38"  Height ="38"  Stretch ="Fill"  Stroke ="#FF000000"  
Canvas.Left
="588"  Canvas.Top ="514"  Data ="M37.5,0.5 L37.5,37.5 0.5,37.5 z"  Fill ="#FFFFFFFF"  
RenderTransformOrigin
="0.5,0.5"  Cursor ="Hand" >
    
< Path.RenderTransform >
        
< TransformGroup >
            
< ScaleTransform  ScaleX ="1"  ScaleY ="1" />
            
< SkewTransform  AngleX ="0"  AngleY ="0" />
            
< RotateTransform  Angle ="314.365" />
            
< TranslateTransform  X ="0"  Y ="0" />
        
</ TransformGroup >
    
</ Path.RenderTransform >
</ Path >

<!--  The outer canvas here is clipped: only the area defined by the rectangle geometry is visible   -->
<!--  This is necessary as when we animate the 'Library' canvas inside it we do not want to see the 
thumbnails slide under the navigation arrows and off the screen
-->
< Canvas  x:Name ="ClippedCanvas"  Canvas.Top ="491"  Canvas.Left ="43"  Width ="550"  Height ="90"  
Background
="Silver" >
    
< Canvas.Clip >
        
< RectangleGeometry  Rect ="0, 0, 550, 114" />
    
</ Canvas.Clip >
   
    
<!--  Animations to move the playlist left and right. They are numbered so that we can call them 
logically from code 
-->
    
< Canvas.Resources >
        
< Storyboard  x:Name ="MoveLeft01" >
            
< DoubleAnimation  Storyboard.TargetProperty ="(Canvas.Left)"  Storyboard.TargetName ="Library"  
                                   From ="13"  To ="-613"  Duration ="0:0:2"   />
        
</ Storyboard >
        
< Storyboard  x:Name ="MoveRight02" >
            
< DoubleAnimation  Storyboard.TargetProperty ="(Canvas.Left)"  Storyboard.TargetName ="Library"  
                                   From ="-613"  To ="13"  Duration ="0:0:2"   />
        
</ Storyboard >
    
</ Canvas.Resources >
   
    
<!--  The Library Canvas groups the playlist buttons into a single element that can be easily animated 
left - right.  
-->        
    
< Canvas  Width ="1157.275"  Height ="82.96"  Canvas.Left ="0"  Canvas.Top ="0"  x:Name ="Library" >
        
< Canvas  Width ="550.275"  Height ="82.96"  x:Name ="playlist1" >
            
< Image  x:Name ="play0"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="1.png"  
                                   Stretch ="Fill"  Cursor ="Hand"   />
            
< Image  x:Name ="play1"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="2.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="139" />
            
< Image  x:Name ="play2"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="3.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="278" />
            
< Image  x:Name ="play3"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="4.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="417" />
        
</ Canvas >
        
< Canvas  Width ="550.275"  Height ="82.96"  x:Name ="playlist2"  Canvas.Left ="607" >
            
< Image  x:Name ="play4"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="5.png"  
                                   Stretch ="Fill"  Cursor ="Hand"   />
            
< Image  x:Name ="play5"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="6.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="139" />
            
< Image  x:Name ="play6"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="7.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="278" />
            
< Image  x:Name ="play7"  Opacity ="0.74"  Width ="133.275"  Height ="82.96"  Source ="8.png"  
                                   Stretch ="Fill"  Cursor ="Hand"  Canvas.Left ="417" />
        
</ Canvas >
    
</ Canvas >
</ Canvas >

    
    下面就要改一下相应的js文件了,找到StartPlayer.js文件,新的播入列表方法放在页面的最上面:

// 全局变量声明

var  curPos  =   1 // 当前播入的媒体文件在列表中的位置
var  maxPos  =   2 // 当前的分页数,因为是8个文件,每4个文件为1页,所以这里是两页
var  cVideos  =   8 // 视频文件个数(本DEMO中有8个)

function  get_mediainfo(mediainfoIndex) {
    
switch  (mediainfoIndex) {       

        
case   0 :
            
return   {  " mediaSource " " Movie1.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   1 :
            
return   {  " mediaSource " " Movie2.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   2 :
            
return   {  " mediaSource " " Movie3.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   3 :
            
return   {  " mediaSource " " Movie4.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   4 :
            
return   {  " mediaSource " " Movie5.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   5 :
            
return   {  " mediaSource " " Movie6.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   6 :
            
return   {  " mediaSource " " Movie7.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               

        
case   7 :
            
return   {  " mediaSource " " Movie8.wmv " ,
                      
" placeholderSource " "" ,
                      
" chapters " : [] };                                                               
                         
        
default :
             
throw  Error.invalidOperation( " No such mediainfo " );
     }
}

   将原码中的原有播放文件列表变量和相关内容注释:

//     this._playlist=[];
//
    try {
//
        eval( 'this._playlist=['+
//
        '{"mediaSource":"15_mt_l2s_callingsqlfunctions.wmv",'+
//
        '"placeholderSource":"",'+
//
        '"chapters":'+
//
            '['+
//
            ']},'+
//
        '{"mediaSource":"18_mt_l2s_transactions.wmv",'+
//
        '"placeholderSource":"",'+
//
        '"chapters":'+
//
            '['+
//
            ']}'+
//
        '];' );
//
    }
//
    catch(e){}

//     this._galleryItems=[];
//
    try {
//
        eval( 'this._galleryItems=['+
//
        'new ExpressionPlayer.GalleryItem("15_mt_l2s_callingsqlfunctions.wmv",""),'+
//
        'new ExpressionPlayer.GalleryItem("18_mt_l2s_transactions.wmv","")'+
//
        '];' );
//
    }
//
    catch(e){}

//     this._player.set_galleryInfo( this._galleryItems, Function.createDelegate(this, this._onClickGalleryItem) ); 
//
    this._onPlayNextVideo(null,null);   

      将下列代码放在该注释下方来解决对相应媒体播放按钮进行事件绑定:

// wire up the rollover and click events for each of our play buttons       

this .Plugin  =  document.getElementById( this ._hostname);

for  ( var  i  =   0 ; i  <  cVideos; i ++ )
{
    
var  element  =   this .Plugin.Content.findName( ' play '   +  i);
    element.addEventListener(
" MouseEnter " , Function.createDelegate( this , this ._rollOver));
    element.addEventListener(
" MouseLeave " , Function.createDelegate( this , this ._rollOut));
    element.addEventListener(
" MouseLeftButtonUp " , Function.createDelegate( this , this ._playX));
}

this .Plugin.Content.findName( ' LeftArrow ' ).addEventListener( " MouseEnter "
                                   Function.createDelegate( this , this ._rollOver));
this .Plugin.Content.findName( ' LeftArrow ' ).addEventListener( " MouseLeave "
                                   Function.createDelegate( this , this ._rollOut));
this .Plugin.Content.findName( ' LeftArrow ' ).addEventListener( " MouseLeftButtonUp "
                                   Function.createDelegate( this , this ._slideLeft));
this .Plugin.Content.findName( ' RightArrow ' ).addEventListener( " MouseEnter "
                                   Function.createDelegate( this , this ._rollOver));
this .Plugin.Content.findName( ' RightArrow ' ).addEventListener( " MouseLeave "
                                   Function.createDelegate( this , this ._rollOut));
this .Plugin.Content.findName( ' RightArrow ' ).addEventListener( " MouseLeftButtonUp "
                                  Function.createDelegate(
this , this ._slideRight));

this ._onPlayNextVideo( null null );    


    而下面就是其相应的事件处理代码了:

  

 _rollOver:  function (sender, eventArgs) {
    sender.opacity
= 1 ;
 },
 
  _rollOut: 
function (sender, eventArgs) {
    sender.opacity
= 0.74 ;
 },
 
 _playX: 
function (sender, eventArgs) {
    
var  X  =  Number(sender.Name.substring( 4 ));
    
this ._currentMediainfo  =  X;
    
this ._player.set_mediainfo( get_mediainfo( X ));
    sender.opacity
= 1 ;
 },
 
 _slideLeft: 
function (sender, eventArgs) {
      
switch (curPos)
      {
          
case   1 :
              sender.findName(
" LeftArrow " ).opacity  =   0.85 ;
              
break ;
          
default :
              sender.findName(
" MoveRight0 "   +  curPos).Begin();
              curPos
-- ;  
      }
 }, 
 
 _slideRight: 
function (sender, eventArgs) {
    
switch (curPos)
      {              
          
case  maxPos:
              sender.findName(
" RightArrow " ).opacity  =   0.85
            
break ;               
          
default :
            sender.findName(
" MoveLeft0 "   +  curPos).Begin();
              curPos
++ ;
              sender.findName(
" LeftArrow " ).opacity  =   1 ;     
      }
 }


     因为使用了新的播放列表变量,所以原来生成的如下方法内容会被改写如下:
  

_onPlayPreviousVideo:  function (sender, eventArgs) {
    
if  ( this ._currentMediainfo > 0 )      
    {
        
this ._player.set_mediainfo(get_mediainfo( -- this ._currentMediainfo ));   
    }  
},

_onPlayNextVideo: 
function (sender, eventArgs) {
    
if  ( this ._currentMediainfo < cVideos)      
    {
        
this ._player.set_mediainfo(get_mediainfo( ++ this ._currentMediainfo ));   
    }
},
 

     到这里我们可以在本地运行一下default.htm来看一下效果。

     然后为了演示方便,我将这个Application上传到了Silverlight Streaming
上,经常了n遍的上传之后,终于测试成功,所以才在本文开头做了相应的演示。

    好了,今天的内容就先到这里了.



本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/86909,如需转载请自行联系原作者