| Comments

In an email dialog today I saw someone asking how he could use an existing Encoder 2 template for existing media or streaming URIs when you don’t have something to encode.  After a few explanations, he replied that someone should blog this – and I agree :-).

So what did he mean?  Well, when you use Expression Encoder, you are typically going to be encoding media to a format to consume.  Encoder also gives you an additional option in the output settings to generate a media player for that encoded content.  These are all based on templates that I’ve previously written about that are available in the product as well is the source code for you to extend.

But what if you have a media file that doesn’t need encoding or you have a streaming URI and you don’t need to encode anything, but want the player?  To some it might not be so obvious so let me try to walk you through the steps.

You need the player

First you need the player.  The XAP that is, of the template you want to use.  There are essentially two ways of going about getting this:

    1. Getting the MediaPlayerTemplate.xap file from an existing output you already did (that used the same template you want)
    2. Building the XAP using the source of the templates and building it from scratch (requires .NET compiler or Visual Studio)

Obviously if you have the XAP of your desired template, you are ready to proceed.  If you don’t, then you’ll need to proceed to step 2.  Here’s what you’ll do:

Building the Player

First, find the template you want.  These are located in C:\Program Files\Microsoft Expression\Encoder 2\Templates\en (note: if you are on 64-bit or a different language, this path may differ slightly).  Within here you’ll see a list of templates by name.  Find the one you want and within that folder there is a Source directory.  That’s what you want.  I highly recommend actually moving the source files to a different place rather than edit directly in the templates directory.  There is a Visual Studio 2008 solution/project file in there and you can open it up and compile. 

As long as you are in there…

If you don’t need all the features of the template (i.e., Adaptive Streaming, etc) consider reading James Clarke’s post on removing some of those references and still creating the same template, but with reduced functionality.

Once compiled (remember to choose the right configuration - i.e., Release, Debug - for your needs), you’ll have in the Bin directory of that project the MediaPlayerTemplate.xap file you need. 

Passing parameters

So how can you compile the player template without media?  The Encoder 2 Silvelright 2 templates are completely parameter driven.  If you notice in any existing encoded project output (look at the default.html file generated) you’ll see the object tag used to host the player.  It may look something like this:

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
   2:     <param name="source" value="MediaPlayerTemplate.xap"/>
   3:     <param name="onerror" value="onSilverlightError" />
   4:     <param name="initparams" value='autoplay=True,autoload=True,enablecaptions=True,muted=False,stretchmode=0,displaytimecode=False,playlist=&lt;playList><playListItems><playListItem title="Moonlight%201.0%20Install%20on%20OpenSuse" description="Screencast%20of%20Moonlight%20install%20on%20OpenSuse.%20%20Virtual%20image%20provided%20by%20http://susestudio.com." mediaSource="MoonlightInstall.wmv" adaptiveStreaming="False" thumbSource="" frameRate="14.9669006991039" width="800" height="600" ><chapters><chapter  position="9.674" thumbnailSource="MoonlightInstall_9.674.jpg" title="Silverlight%201.0%20Chess%20playback%20from%20Vertigo" /><chapter  position="13.967" thumbnailSource="MoonlightInstall_13.967.jpg" title="Standard%20Silverlight%20installer%20integrates%20with%20Moonlight%20install%20links." /><chapter  position="18.058" thumbnailSource="MoonlightInstall_18.058.jpg" title="Firefox%20first%20nag%20message%20to%20protect%20user%20from%20web%20installs." /><chapter  position="20.784" thumbnailSource="MoonlightInstall_20.784.jpg" title="Second%20Firefox%20nag%20message%20(plugin%20message%20from%20trusted%20sources)" /><chapter  position="24.543" thumbnailSource="MoonlightInstall_24.543.jpg" title="Plugin%20installation%20complete%252C%20Firefox%20restart" /><chapter  position="32.055" thumbnailSource="MoonlightInstall_32.055.jpg" title="Silverlight%201.0%20Chess%20now%20working%20with%20Linux/Moonlight" /><chapter  position="43.801" thumbnailSource="MoonlightInstall_43.801.jpg" title="Video.Show%20from%20Vertigo" /><chapter  position="46.675" thumbnailSource="MoonlightInstall_46.675.jpg" title="Launching%20a%20media%20player%20in%20Moonlight%20for%20first%20time" /><chapter  position="48.334" thumbnailSource="MoonlightInstall_48.334.jpg" title="Microsoft%20Media%20Pack%20(codecs)%20prompt%20for%20install" /><chapter  position="51.249" thumbnailSource="MoonlightInstall_51.249.jpg" title="Media%20Pack%20EULA" /><chapter  position="60.051" thumbnailSource="MoonlightInstall_60.051.jpg" title="Re-launch%20media%20player%20with%20Media%20Pack%20installed" /><chapter  position="71.010" thumbnailSource="MoonlightInstall_71.010.jpg" title="HD%20media%20playback%20via%20Moonlight%20on%20Linux" /><chapter  position="72.490" thumbnailSource="MoonlightInstall_72.490.jpg" title="Fullscreen%20mode" /><chapter  position="76.138" thumbnailSource="MoonlightInstall_76.138.jpg" title="Bubblemark%20application%20on%20Moonlight" /></chapters></playListItem></playListItems></playList>' />            
   5:     
   6:     <a href="http://go2.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
   7:          <img src="http://go2.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:     </a>
   9: </object>
  10: <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

Notice the initParams option?  If you aren’t familiar, you can send Silverlight 2 applications parameters using this method.  There’s a video walk-through on using initParams you can view on the Silverlight community site.  The key area here (among the other options) for media URIs is the playlist parameter.  Singling that one out you’ll see the structure looks like this:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <playList>
   3:   <playListItems>
   4:     <playListItem title="Moonlight%201.0%20Install%20on%20OpenSuse" description="Screencast%20of%20Moonlight%20install%20on%20OpenSuse.%20%20Virtual%20image%20provided%20by%20http://susestudio.com." mediaSource="MoonlightInstall.wmv" adaptiveStreaming="False" thumbSource="" frameRate="14.9669006991039" width="800" height="600" >
   5:       <chapters>
   6:         <chapter  position="9.674" thumbnailSource="MoonlightInstall_9.674.jpg" title="Silverlight%201.0%20Chess%20playback%20from%20Vertigo" />
   7:         <chapter  position="13.967" thumbnailSource="MoonlightInstall_13.967.jpg" title="Standard%20Silverlight%20installer%20integrates%20with%20Moonlight%20install%20links." />
   8:         <chapter  position="18.058" thumbnailSource="MoonlightInstall_18.058.jpg" title="Firefox%20first%20nag%20message%20to%20protect%20user%20from%20web%20installs." />
   9:         <chapter  position="20.784" thumbnailSource="MoonlightInstall_20.784.jpg" title="Second%20Firefox%20nag%20message%20(plugin%20message%20from%20trusted%20sources)" />
  10:         <chapter  position="24.543" thumbnailSource="MoonlightInstall_24.543.jpg" title="Plugin%20installation%20complete%252C%20Firefox%20restart" />
  11:         <chapter  position="32.055" thumbnailSource="MoonlightInstall_32.055.jpg" title="Silverlight%201.0%20Chess%20now%20working%20with%20Linux/Moonlight" />
  12:         <chapter  position="43.801" thumbnailSource="MoonlightInstall_43.801.jpg" title="Video.Show%20from%20Vertigo" />
  13:         <chapter  position="46.675" thumbnailSource="MoonlightInstall_46.675.jpg" title="Launching%20a%20media%20player%20in%20Moonlight%20for%20first%20time" />
  14:         <chapter  position="48.334" thumbnailSource="MoonlightInstall_48.334.jpg" title="Microsoft%20Media%20Pack%20(codecs)%20prompt%20for%20install" />
  15:         <chapter  position="51.249" thumbnailSource="MoonlightInstall_51.249.jpg" title="Media%20Pack%20EULA" />
  16:         <chapter  position="60.051" thumbnailSource="MoonlightInstall_60.051.jpg" title="Re-launch%20media%20player%20with%20Media%20Pack%20installed" />
  17:         <chapter  position="71.010" thumbnailSource="MoonlightInstall_71.010.jpg" title="HD%20media%20playback%20via%20Moonlight%20on%20Linux" />
  18:         <chapter  position="72.490" thumbnailSource="MoonlightInstall_72.490.jpg" title="Fullscreen%20mode" />
  19:         <chapter  position="76.138" thumbnailSource="MoonlightInstall_76.138.jpg" title="Bubblemark%20application%20on%20Moonlight" />
  20:       </chapters>
  21:     </playListItem>
  22:   </playListItems>
  23: </playList>

This sample above represents a single media file with chapter markers.  The bare minimum for a single media URI would be:

   1: <playList>
   2:   <playListItems>
   3:     <playListItem mediaSource="MoonlightInstall.wmv"></playListItem>
   4:   </playListItems>
   5: </playList>

So if you have a streaming URI (i.e., mms://mysite.com/live-baseball-game.asx) you would use this playlist structure:

   1: <playList>
   2:   <playListItems>
   3:     <playListItem mediaSource="mms://mysite.com/live-baseball-game.asx"></playListItem>
   4:   </playListItems>
   5: </playList>

and then in your HTML page you could have something like this for the full implementation (noting to use the appropriate width/height for your needs):

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
   2:     <param name="source" value="MediaPlayerTemplate.xap"/>
   3:     <param name="onerror" value="onSilverlightError" />
   4:     <param name="initparams" value='autoplay=True,autoload=True,enablecaptions=True,muted=False,stretchmode=0,displaytimecode=False,playlist=&lt;playList><playListItems><playListItem mediaSource="mms://mysite.com/live-baseball-game.asx"></playListItem></playListItems></playList>' />            
   5:     
   6:     <a href="http://go2.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
   7:          <img src="http://go2.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:     </a>
   9: </object>
  10: <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

It is important to note that if you know the other parameters like framerate, etc. you should provide as much information you can for the playListItem node, but I’m just noting the bare minimum above.

Can I do this in code?

Yes, if you were using the media player in code you can still use this method in either XAML as noted in a previous post of mine or in code using something like this:

   1: public Page()
   2:         {
   3:             InitializeComponent();
   4:             Loaded += new RoutedEventHandler(Page_Loaded);
   5:         }
   6:  
   7:         void Page_Loaded(object sender, RoutedEventArgs e)
   8:         {
   9:             ExpressionMediaPlayer.MediaPlayer mp = new ExpressionMediaPlayer.MediaPlayer();
  10:             mp.Width = 800;
  11:             mp.Height = 600;
  12:             ExpressionMediaPlayer.PlaylistItem playListItem = new ExpressionMediaPlayer.PlaylistItem();
  13:             playListItem.MediaUrl = new Uri("mms://mysite.com/live-baseball-game.asx");
  14:             mp.Playlist.Add(playListItem);
  15:             LayoutRoot.Children.Add(mp);
  16:         }

I suspect people would not be using the code concept as much but I just wanted to point it out here.

Summary

So having the MediaPlayerTemplate.xap file is really all you need.  Anything else can be sent as parameters either via the object tag, the XAML control or in code.  This enables being able to really re-use the template you desire without having to run an encoder job just to get the template and change the code.

Hope this helps!

| Comments

In an email dialog today I saw someone asking how he could use an existing Encoder 2 template for existing media or streaming URIs when you don’t have something to encode.  After a few explanations, he replied that someone should blog this – and I agree :-).

So what did he mean?  Well, when you use Expression Encoder, you are typically going to be encoding media to a format to consume.  Encoder also gives you an additional option in the output settings to generate a media player for that encoded content.  These are all based on templates that I’ve previously written about that are available in the product as well is the source code for you to extend.

But what if you have a media file that doesn’t need encoding or you have a streaming URI and you don’t need to encode anything, but want the player?  To some it might not be so obvious so let me try to walk you through the steps.

You need the player

First you need the player.  The XAP that is, of the template you want to use.  There are essentially two ways of going about getting this:

    1. Getting the MediaPlayerTemplate.xap file from an existing output you already did (that used the same template you want)
    2. Building the XAP using the source of the templates and building it from scratch (requires .NET compiler or Visual Studio)

Obviously if you have the XAP of your desired template, you are ready to proceed.  If you don’t, then you’ll need to proceed to step 2.  Here’s what you’ll do:

Building the Player

First, find the template you want.  These are located in C:\Program Files\Microsoft Expression\Encoder 2\Templates\en (note: if you are on 64-bit or a different language, this path may differ slightly).  Within here you’ll see a list of templates by name.  Find the one you want and within that folder there is a Source directory.  That’s what you want.  I highly recommend actually moving the source files to a different place rather than edit directly in the templates directory.  There is a Visual Studio 2008 solution/project file in there and you can open it up and compile. 

As long as you are in there…

If you don’t need all the features of the template (i.e., Adaptive Streaming, etc) consider reading James Clarke’s post on removing some of those references and still creating the same template, but with reduced functionality.

Once compiled (remember to choose the right configuration - i.e., Release, Debug - for your needs), you’ll have in the Bin directory of that project the MediaPlayerTemplate.xap file you need. 

Passing parameters

So how can you compile the player template without media?  The Encoder 2 Silvelright 2 templates are completely parameter driven.  If you notice in any existing encoded project output (look at the default.html file generated) you’ll see the object tag used to host the player.  It may look something like this:

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
   2:     <param name="source" value="MediaPlayerTemplate.xap"/>
   3:     <param name="onerror" value="onSilverlightError" />
   4:     <param name="initparams" value='autoplay=True,autoload=True,enablecaptions=True,muted=False,stretchmode=0,displaytimecode=False,playlist=&lt;playList><playListItems><playListItem title="Moonlight%201.0%20Install%20on%20OpenSuse" description="Screencast%20of%20Moonlight%20install%20on%20OpenSuse.%20%20Virtual%20image%20provided%20by%20http://susestudio.com." mediaSource="MoonlightInstall.wmv" adaptiveStreaming="False" thumbSource="" frameRate="14.9669006991039" width="800" height="600" ><chapters><chapter  position="9.674" thumbnailSource="MoonlightInstall_9.674.jpg" title="Silverlight%201.0%20Chess%20playback%20from%20Vertigo" /><chapter  position="13.967" thumbnailSource="MoonlightInstall_13.967.jpg" title="Standard%20Silverlight%20installer%20integrates%20with%20Moonlight%20install%20links." /><chapter  position="18.058" thumbnailSource="MoonlightInstall_18.058.jpg" title="Firefox%20first%20nag%20message%20to%20protect%20user%20from%20web%20installs." /><chapter  position="20.784" thumbnailSource="MoonlightInstall_20.784.jpg" title="Second%20Firefox%20nag%20message%20(plugin%20message%20from%20trusted%20sources)" /><chapter  position="24.543" thumbnailSource="MoonlightInstall_24.543.jpg" title="Plugin%20installation%20complete%252C%20Firefox%20restart" /><chapter  position="32.055" thumbnailSource="MoonlightInstall_32.055.jpg" title="Silverlight%201.0%20Chess%20now%20working%20with%20Linux/Moonlight" /><chapter  position="43.801" thumbnailSource="MoonlightInstall_43.801.jpg" title="Video.Show%20from%20Vertigo" /><chapter  position="46.675" thumbnailSource="MoonlightInstall_46.675.jpg" title="Launching%20a%20media%20player%20in%20Moonlight%20for%20first%20time" /><chapter  position="48.334" thumbnailSource="MoonlightInstall_48.334.jpg" title="Microsoft%20Media%20Pack%20(codecs)%20prompt%20for%20install" /><chapter  position="51.249" thumbnailSource="MoonlightInstall_51.249.jpg" title="Media%20Pack%20EULA" /><chapter  position="60.051" thumbnailSource="MoonlightInstall_60.051.jpg" title="Re-launch%20media%20player%20with%20Media%20Pack%20installed" /><chapter  position="71.010" thumbnailSource="MoonlightInstall_71.010.jpg" title="HD%20media%20playback%20via%20Moonlight%20on%20Linux" /><chapter  position="72.490" thumbnailSource="MoonlightInstall_72.490.jpg" title="Fullscreen%20mode" /><chapter  position="76.138" thumbnailSource="MoonlightInstall_76.138.jpg" title="Bubblemark%20application%20on%20Moonlight" /></chapters></playListItem></playListItems></playList>' />            
   5:     
   6:     <a href="http://go2.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
   7:          <img src="http://go2.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:     </a>
   9: </object>
  10: <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

Notice the initParams option?  If you aren’t familiar, you can send Silverlight 2 applications parameters using this method.  There’s a video walk-through on using initParams you can view on the Silverlight community site.  The key area here (among the other options) for media URIs is the playlist parameter.  Singling that one out you’ll see the structure looks like this:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <playList>
   3:   <playListItems>
   4:     <playListItem title="Moonlight%201.0%20Install%20on%20OpenSuse" description="Screencast%20of%20Moonlight%20install%20on%20OpenSuse.%20%20Virtual%20image%20provided%20by%20http://susestudio.com." mediaSource="MoonlightInstall.wmv" adaptiveStreaming="False" thumbSource="" frameRate="14.9669006991039" width="800" height="600" >
   5:       <chapters>
   6:         <chapter  position="9.674" thumbnailSource="MoonlightInstall_9.674.jpg" title="Silverlight%201.0%20Chess%20playback%20from%20Vertigo" />
   7:         <chapter  position="13.967" thumbnailSource="MoonlightInstall_13.967.jpg" title="Standard%20Silverlight%20installer%20integrates%20with%20Moonlight%20install%20links." />
   8:         <chapter  position="18.058" thumbnailSource="MoonlightInstall_18.058.jpg" title="Firefox%20first%20nag%20message%20to%20protect%20user%20from%20web%20installs." />
   9:         <chapter  position="20.784" thumbnailSource="MoonlightInstall_20.784.jpg" title="Second%20Firefox%20nag%20message%20(plugin%20message%20from%20trusted%20sources)" />
  10:         <chapter  position="24.543" thumbnailSource="MoonlightInstall_24.543.jpg" title="Plugin%20installation%20complete%252C%20Firefox%20restart" />
  11:         <chapter  position="32.055" thumbnailSource="MoonlightInstall_32.055.jpg" title="Silverlight%201.0%20Chess%20now%20working%20with%20Linux/Moonlight" />
  12:         <chapter  position="43.801" thumbnailSource="MoonlightInstall_43.801.jpg" title="Video.Show%20from%20Vertigo" />
  13:         <chapter  position="46.675" thumbnailSource="MoonlightInstall_46.675.jpg" title="Launching%20a%20media%20player%20in%20Moonlight%20for%20first%20time" />
  14:         <chapter  position="48.334" thumbnailSource="MoonlightInstall_48.334.jpg" title="Microsoft%20Media%20Pack%20(codecs)%20prompt%20for%20install" />
  15:         <chapter  position="51.249" thumbnailSource="MoonlightInstall_51.249.jpg" title="Media%20Pack%20EULA" />
  16:         <chapter  position="60.051" thumbnailSource="MoonlightInstall_60.051.jpg" title="Re-launch%20media%20player%20with%20Media%20Pack%20installed" />
  17:         <chapter  position="71.010" thumbnailSource="MoonlightInstall_71.010.jpg" title="HD%20media%20playback%20via%20Moonlight%20on%20Linux" />
  18:         <chapter  position="72.490" thumbnailSource="MoonlightInstall_72.490.jpg" title="Fullscreen%20mode" />
  19:         <chapter  position="76.138" thumbnailSource="MoonlightInstall_76.138.jpg" title="Bubblemark%20application%20on%20Moonlight" />
  20:       </chapters>
  21:     </playListItem>
  22:   </playListItems>
  23: </playList>

This sample above represents a single media file with chapter markers.  The bare minimum for a single media URI would be:

   1: <playList>
   2:   <playListItems>
   3:     <playListItem mediaSource="MoonlightInstall.wmv"></playListItem>
   4:   </playListItems>
   5: </playList>

So if you have a streaming URI (i.e., mms://mysite.com/live-baseball-game.asx) you would use this playlist structure:

   1: <playList>
   2:   <playListItems>
   3:     <playListItem mediaSource="mms://mysite.com/live-baseball-game.asx"></playListItem>
   4:   </playListItems>
   5: </playList>

and then in your HTML page you could have something like this for the full implementation (noting to use the appropriate width/height for your needs):

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
   2:     <param name="source" value="MediaPlayerTemplate.xap"/>
   3:     <param name="onerror" value="onSilverlightError" />
   4:     <param name="initparams" value='autoplay=True,autoload=True,enablecaptions=True,muted=False,stretchmode=0,displaytimecode=False,playlist=&lt;playList><playListItems><playListItem mediaSource="mms://mysite.com/live-baseball-game.asx"></playListItem></playListItems></playList>' />            
   5:     
   6:     <a href="http://go2.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
   7:          <img src="http://go2.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:     </a>
   9: </object>
  10: <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>

It is important to note that if you know the other parameters like framerate, etc. you should provide as much information you can for the playListItem node, but I’m just noting the bare minimum above.

Can I do this in code?

Yes, if you were using the media player in code you can still use this method in either XAML as noted in a previous post of mine or in code using something like this:

   1: public Page()
   2:         {
   3:             InitializeComponent();
   4:             Loaded += new RoutedEventHandler(Page_Loaded);
   5:         }
   6:  
   7:         void Page_Loaded(object sender, RoutedEventArgs e)
   8:         {
   9:             ExpressionMediaPlayer.MediaPlayer mp = new ExpressionMediaPlayer.MediaPlayer();
  10:             mp.Width = 800;
  11:             mp.Height = 600;
  12:             ExpressionMediaPlayer.PlaylistItem playListItem = new ExpressionMediaPlayer.PlaylistItem();
  13:             playListItem.MediaUrl = new Uri("mms://mysite.com/live-baseball-game.asx");
  14:             mp.Playlist.Add(playListItem);
  15:             LayoutRoot.Children.Add(mp);
  16:         }

I suspect people would not be using the code concept as much but I just wanted to point it out here.

Summary

So having the MediaPlayerTemplate.xap file is really all you need.  Anything else can be sent as parameters either via the object tag, the XAML control or in code.  This enables being able to really re-use the template you desire without having to run an encoder job just to get the template and change the code.

Hope this helps!

| Comments

Over the holiday this past week I got a ping from Scott Cate about some Silverlight media questions, namely a player and Silverlight Streaming.  The gist of the conversation was that the Encoder 2 SP1 templates and the SLS Plugin don’t play nice together (yet).  I know that the team has been testing some updates to the plugin for uploading Silverlight 2 templates to SLS, but for now if you tried to do that you’ll get a random error message that won’t make sense to you (something along the lines of template not found).

After talking with Scott and understanding his scenario more (media formats and CDN hosting – note: CDN=Content Delivery Network - specifically) we, well I, decided it might be a good idea to use an alternate player right now.  Of course I suggested the one that Joel and I worked on, but there are also many other out there.  I should also point out that the Encoder 2 SP1 templates also include a fully functional Silverlight 2 player with source code that you can use.  Scott took my player as a start (not sure if it will be the final one he uses) and we went to chatting about the implementation.  I first told him he could still use SLS and just upload the XAP, etc. but remembered that SLS doesn’t fully support an easy implementation of initParams just yet (it can, but a little workaround-ish right now).  After learning of the initParams, Scott wanted to host the player on his CDN and just pass in the media URI as the param (exactly what our player is built for).

I pointed to the instructions on the SL2VideoPlayer CodePlex site and we started implementing.  So Scott was going to have his pages delivered from his CMS system on his site (let’s call it foo.com) and have the Silverlight application delivered from his CDN (let’s call that mycdn.com).  Then the media was going to be hosted on another CDN (Silverlight Streaming).  We had three networks in play here: foo.com, mycdn.com and Silverlight Streaming.  In his site delivered by his CMS system he’d have the object tag for the player implemented something similar to:

   1: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="640" height="480">
   2:         <param name="source" value="http://mycdn.com/myaccount/VideoPlayerM.xap"/>
   3:         <param name="background" value="white" />
   4:         <param name="initParams" value="m=http://silverlight.live.com/accountid/Bear.wmv" />
   5:                <param name="minruntimeversion" value="2.0.31005.0" />
   6:         <a href="http://go.microsoft.com/fwlink/?LinkId=124807" style="text-decoration: none;">
   7:              <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
   8:         </a>
   9:     </object>

Note that the source for the Silverlight application is a full URI to the CDN endpoint of the XAP file.  Also note the initParams which would point to the video file hosted on Silverlight Streaming (this isn’t the real URI, just a sample).  When rendered, we saw the Silverlight default loader (%age orb) and then a white screen – nothing.  WTF?!  Loading up my favorite tool for Silverlight network debugging we saw the XAP being delivered and loaded, but then the media file was not.

I then remembered that I may have forgot to tell Scott that any remotely loaded XAP needs to ensure that it is delivered with the correct content-type of application/x-silverlight-app to ensure that it would load properly.  We double-checked this and ensured it was (of course it was because it was already being loaded, but good to double check).  Then we couldn’t figure out why it wasn’t loading the media.

Aha!  I remembered that there was one snippet of code that was in there that does a check for a query string parameter.  In doing this, the Silverlight application uses the HTML DOM bridge to interact with, well, the HTML DOM.  This is what was causing the problem.  By default, remotely loaded XAP files cannot access the HTML DOM without the author explicitly allowing it.  So we had to add another parameter to the object tag, the enableHtmlAccess param.  I sent it to Scott in an email (after testing myself) and thought we were done.  He said it still wasn’t working.  Frustrated, we kept looking.  Sergey from the network team alerted me to a possibility of some character encoding issues.  Yep, that was it.  Here’s a screenshot from the code that wasn’t working:

Spot the issue?  The copied/pasted param quotes were not in ASCII encoding and thus I’m assuming HTML was ignoring it.  After Scott typed it out rather than pasting, it worked fine.

Phew!  Nothing like banging your head in the weeds of code when it is a little typo!

Summary

So if you are looking to host your Silverlight content on a CDN for delivery, make sure two things:

    1. The server delivering your XAP content must deliver with the correct MIME type: application/x-silverlight-app
    2. If there is any code in your XAP that does HTML bridge interaction, you’ll have to add the enableHtmlAccess param to either your object tag instantiation as a param, or to your createObject call if using Silverlight.js.

I hope this helps some!

| Comments

I received a comment regarding the new Expression Encoder SP1 Silverlight player templates and how they can be used within your own application.  Right now the templates appear to stand on their own.  That’s only because the output of an Encoder action will be an encoded file, the template you chose (XAP) and an HTML page to host the Silverlight player application.

But what if you already have an application and are trying to integrate media playback within it?  How can you take advantage of the Encoder templates, but just drop them in your existing application?  Let’s take a quick look.

Let’s say we have an existing application.  For the sake of this post, let’s just show some primitive controls and display a Button and TextBox within some StackPanel layouts:

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="ExPlayer.Page"
   5:     Width="640" Height="480" 
   6:     >
   7:  
   8:     <Grid x:Name="LayoutRoot" Background="White">
   9:         <StackPanel Orientation="Horizontal">
  10:             <StackPanel Height="Auto" Width="309">
  11:                 <Button Content="Button"/>
  12:                 <TextBox Text="TextBox" TextWrapping="Wrap"/>
  13:             </StackPanel>
  14:             <StackPanel Height="Auto" Width="250" x:Name="MediaArea"/>
  15:         </StackPanel>
  16:     </Grid>
  17: </UserControl>

Now we want to add a media player using the Encoder templates to our application in the StackPanel labeled MediaArea.  First, we need to get the media player from the template as a control.  Easy enough since the source code for the Expression Encoder Silverlight 2 templates are included.  Browse to your install directory for Expression (usually C:\Program Files\Microsoft Expression\Encoder\Templates\en\) and pick the Silverlight 2 template you want to use.  NOTE: This is only for Silverlight 2 templates, so be sure not to get frustrated at me :-) -- you’ve been forewarned.  I’ll choose the SL2Standard template.  Notice within that folder there is also a Source folder.  Within there is an ExpressionPlayer folder and associated C# source code project.  Open that project in Visual Studio 2008.

Now build the project.  Done.  You now have a control you can use.  Here’s how we’ll do it.

Going back to our own application we need to add a reference to the ExpressionPlayer.dll and MediaPlayer.dll we just built.  Go ahead and do that in your Silverlight application by choosing Add Reference and then pointing to the assembly location.  Now we need to inform our XAML that we’ll be using this control.  Of course if you add these controls to your Visual Studio 2008 toolbox you can drag-and-drop them onto the XAML code surface and it will append the xmlns attribute for you, or we can add it ourself:

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="ExPlayer.Page"
   5:     Width="640" Height="480" 
   6:     xmlns:expression="clr-namespace:ExpressionMediaPlayer;assembly=ExpressionPlayer"
   7:     xmlns:ExpressionMediaPlayer="clr-namespace:ExpressionMediaPlayer;assembly=MediaPlayer"
   8:     >

I’ve called my namespace “expression” and “ExpressionMediaPlayer” and you can see I’ve pointed (actually Visual Studio’s Intellisense did it all for me) the namespace to the assembly I just referenced.  Now we can use the control.  Here’s the XAML for adding it to my application and adding a media file that is in my applicaiton:

   1: <UserControl
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     x:Class="ExPlayer.Page"
   5:     Width="640" Height="480" 
   6:     xmlns:expression="clr-namespace:ExpressionMediaPlayer;assembly=ExpressionPlayer"
   7:     xmlns:ExpressionMediaPlayer="clr-namespace:ExpressionMediaPlayer;assembly=MediaPlayer"
   8:     >
   9:  
  10:     <Grid x:Name="LayoutRoot" Background="White">
  11:         <StackPanel Orientation="Horizontal">
  12:             <StackPanel Height="Auto" Width="309">
  13:                 <Button Content="Button"/>
  14:                 <TextBox Text="TextBox" TextWrapping="Wrap"/>
  15:             </StackPanel>
  16:             <StackPanel Height="Auto" Width="250" x:Name="MediaArea">
  17:                 <expression:ExpressionPlayer Width="242" Height="177">
  18:                     <expression:ExpressionPlayer.Playlist>
  19:                         <ExpressionMediaPlayer:PlaylistItem MediaUrl="Lake.wmv"/>
  20:                     </expression:ExpressionPlayer.Playlist>
  21:                 </expression:ExpressionPlayer>
  22:             </StackPanel>
  23:         </StackPanel>
  24:     </Grid>
  25: </UserControl>

Of course you can interact with it via code as well, but getting the control in your app is easy once you know these steps.  Now my application has a fully-functional media playback without me writing any code and being able to integrate it within my existing application.  I might want to change the style of course to fit my application’s experience, but dropping in a few style attributes wouldn’t be that difficult…and I an always make that a part of the Encoder template as well!  Here’s the “after” screenshot of it in play:

You get full functionality out of the player…with one exception.  I’ve noticed that the fullscreen option doesn’t act the same as if the player was the only app.  To be honest I haven’t looked at what it would take to do that,but remember that now the media player is a part of a bigger app and isn’t the application itself.  So “fullscreen” mode is a part of the container Silverlight application and not just the media player…something to watch out for if you expected your embedded media player now to automatically have the same fullscreen functionality.

| Comments

Apparently “soon” means “the next day” to the Encoder team :-).  On 28 OCT James Clarke told us all about the goodness that is coming to Encoder SP1 and noted it would be available “real soon.” Little did we know he had already clicked the publish process to the download servers. 

What are you waiting for, go start the download for Encoder SP1 and I’ll share my thoughts on some things here.

What’s in it?  I’ll pick my favorites: New Silverlight output templates, H.264/AAC support and IIS7 smooth streaming support.

H.264/AAC Device Encoding Support

SP1 brings the promise made earlier of supporting encoding profiles for H.264 and AAC.  For now we’re supporting two device profiles: 320x240 for smaller flash-based devices and 640x480 for larger displays (output container is single MP4).  As previously note, Silverlight will continue to evolve the codec support in the runtime and you should expect to see broadening support in Encoder for that as well.

I think this is a nice added value to a “service pack” for Encoder (I like how service packs are starting to introduce new features in some of our products).  Hopefully you can integrate this into your encoding workflow as well as one of your outputs.

New Silverlight 2 Output Templates

I personally know that this has been a desire of James and the team for a long time.  One of the things the team wanted to do was provide Silverlight 2 templates but also create a base that people can extend to their specific needs.  Here’s the new “Silverlight 2 Default” template:

It exhibits all the core features you’d expect in a media player base as well as things like closed captioning support and playlist support if needed.  As you can see the UI is also base.  The great thing is that the source for these templates is also provided.  The templates get dumped in the same location as the previous and in each new Silverlight 2 template you’ll also see a folder called “Source” that contains the source for that particular template.  If you look at the ExpressionPlayer folder in these templates you’ll see some of the base functionality that you may extend for your needs.

There are 6 new Silverlight 2 templates in all, with 2 audio-only ones for your podcast embedding in your blog and such.  The new output options provides a listing of the templates in the template directory separated by Silverlight 1 and 2 versions so you can quickly see them grouped by Silverlight version.  The preview window is still there and will provide you a preview of the template regardless of which version you select.  The advantage of using the Silverlight 2 templates is that you can quickly use the <object> instantiation methods and there is no dependent Javascript files associated.  The output of a typical encoding is: your media, default.html host page, and the XAP.  So if you want to swap out a different media player XAP based on an Encoder template, it is a cut/paste operation.  Take a look at the default.html page generated to see some of the initParam usage to drive the initialization of the media.

IIS7 Smooth Streaming Support

Additional support has been added to provide container output support for IIS7 smooth streaming, which provides a container for each bitrate to enable that adaptive streaming affect in delivering your media.  An example of this can be seen at the new SmoothHD.com site, which is using IIS7 smooth streaming and a delivery network provided by Akamai.  It’s some great video on good bandwidth, and even on non-high bandwidth you can see it scale quality as needed.

There are some additional enhancements that come with Encoder SP1 for your media so beyond these two features I’m highlighting here, you should definitely download the Encoder SP1 and take advantage of the features.  Hat tip to James and the Encoder team for this service pack and providing us improvements as well as new features!  Check out their team blog for a detailed post on all the new SP1 features.