| Comments

You may be reading the title and wondering what is MediaStreamSourceMediaStreamSource is a piece of the Silverlight runtime that removes a the influence of a media file's container, giving developers direct access to APIs for manipulating encoded elementary audio and video streams.

Huh?

Basically it can enable you as the developer to implement file parsers/etc. in managed code instead of Silverlight, enabling support beyond the native built-in formats for media.  There hasn’t been much information about these types of topics, and I’d agree that for the mainstream, they may be a bit more advanced media scenarios for when the default containers and formats aren’t enough for your use.  Outside of the MSDN documentation there hasn’t really been any good samples of this use either.

Until now.

One of the program managers on the Silverlight media team, Larry Olson, has just provided a detailed public sample of the MediaStreamSource in action on the MSDN Code Gallery site.  He calls the effort ManagedMediaHelpers.  The project contains:

    • Silverlight class library (MediaParsers) which has helper classes for working with MP3 files, including being able to find the right point in an MP3 to begin playback.
    • Silverlight test project for NUnit
    • Silverlight class library (Mp3MediaStreamSource) which has logic for using MP3 file streams
    • Silverlight Application Demo which shows the interaction between a MediaElement and a MediaStreamSource

Why would you want this?  Larry outlines in the project:

“For one thing, having access to elementary streams means that developers can now implement scenarios that other solutions haven't necessarily provided thus far. One example of this is adaptive streaming or multi-bitrate support as was seen during the 2008 Olympics.

For another reason, having access to elementary streams allows developers to implement scenarios that the Silverlight runtime hasn't had a chance to implement yet or that the runtime might not be able to implement in the same timeframe that a developer wants it. Examples of this could be, RTSP:T protocol support, SHOUTcast protocol support, seamless audio looping, ID3 v1 and ID3 v2 metadata support, and many other scenarios.”

This is a great sample and source for those working with media within Silverlight.  Right now it is audio only, MP3 support, but gives you an idea of the MediaStreamSource API and functionality you could implement.

| Comments

i recently got an email from a developer who was using on a site to display high-quality media.  what?! you though silverlight was a windows-only technology? blasphemy!  you see, silverlight is a client-technology, which means as long as it can be served up to the browser (and the user has the plugin), the server can be your own custom version of l337hax0r web edition or whatever.  now, there are advantages of using internet information services on windows and some integration with asp.net, but that's not what this post is about.  on to the issue at hand will you...

so the email...he was getting an error message:

ActionController::RoutingError (No route matches "/player.xaml" with {:method=>:get}):

now i'm not incredibly familiar with what web server configuration he is running (although he is running netbeans/mongrel), but it got me thinking of 2 things.  first, maybe he needed to add a mime mapping.

for silverlight, the following MIME map is for .xaml files: .xaml: application/xaml+xml

but then i also thought that it might be something of some files moved around and such.  i deduced from his note that an template was being used as he mentioned he moved the javascript files to the javascripts directory of his rails application.  for those who don't know, rails is an MVC pattern web framework.  when creating a rails application you get a few different folders created for you (note: i'm just talking rails foo command here).  a lot of the work is done in controllers/models/views folder but there is also a folder called public.  within there are your typical images and javascripts type folders.  basically you can think of public mapping to "/" for static files.

now most rails applications probably wouldn't want all the encoder output to be dumped into /public as-is.  if developers are anything like me (OCD about project folder organization), then you want *.js to be in one place, etc.  i suspected that my reader put all the encoder files in the /public/javascripts folder.  this would be fine and should work okay.  but lets say you want some organization.

for example, i want to put my .js files in /public/javascripts, my jpg/pngs in /public/images and i'm going to create a folder for my xaml and a folder for media (wmv).  great, so we move all the files around then we run the Default.html page.  nothing happens.  why?  well a few things need to change if you move things around.

first, you need your hosting page (in this case right now it is Default.html) to reference the right path to the javascript locations.  so in our example we'd modify (in Default.html) lines like:

<script type='text/javascript' src="Silverlight.js"></script>
<script type='text/javascript' src="BasePlayer.js"></script>

to this:

<script type='text/javascript' src="javascripts/Silverlight.js"></script>
<script type='text/javascript' src="javascripts/BasePlayer.js"></script>

noting that of course there are more than just these two files.  now if we run the application it would still fail.  this is for two reasons, both of which are in StartPlayer.js.  the first is on or about line 8 of the script:

   1:   
   2:   
   3:   
   4:  function get_mediainfo(mediainfoIndex) {
   5:      switch (mediainfoIndex) {        
   6:   
   7:          case 0:
   8:              return  { "mediaUrl": "CodeTripSample.wmv",
   9:                        "placeholderImage": "CodeTripSample_Thumb.jpg",

the next is on or about line 24:

  22:  function StartPlayer_0(parentId) {
  23:      this._hostname = EePlayer.Player._getUniqueName("xamlHost");
  24:      Silverlight.createObjectEx( {   source: player.xaml', 

these both need to map to the right references of where that content has moved...so noting my above folder changes (images/javascripts/media/xaml) my StartPlayer.js file now starts like this:

   1:   
   2:   
   3:   
   4:  function get_mediainfo(mediainfoIndex) {
   5:      switch (mediainfoIndex) {        
   6:   
   7:          case 0:
   8:              return  { "mediaUrl": "media/CodeTripSample.wmv",
   9:                        "placeholderImage": "images/CodeTripSample_Thumb.jpg",
  10:                        "chapters": [               
  11:                                    ] };                                                                
  12:                            
  13:          default:
  14:               throw Error.invalidOperation("No such mediainfo");
  15:       }
  16:  }
  17:   
  18:  function StartWithParent(parentId, appId) {
  19:      new StartPlayer_0(parentId);
  20:  }
  21:   
  22:  function StartPlayer_0(parentId) {
  23:      this._hostname = EePlayer.Player._getUniqueName("xamlHost");
  24:      Silverlight.createObjectEx( {   source: 'xaml/player.xaml', 

and all is well -- my rails app starts and my silverlight content is loaded.  my resulting rails app structure looks like this:

simple enough, but if you move things around you might not have known where you need to change things.  you may wonder why you don't have to change the MediaElement in the player.xaml file.  well, if you are using an expression encoder template, the Url of that element is controlled by the StartPlayer.js mediaUrl attribute being passed to the player.

so if you have static information for your rails app this would probably work fine for you, but i suspect your rails application might be using views and such.  so you'd probably want to ensure you are modifying the appropriate view in views/layouts to ensure the javascript reference is correct, etc.

hope this helps.

| Comments

i've been asked recently why i use the template code in my samples for media playback in .  simple: free code :-).  the templates in expression encoder provide very interesting stub code handling the simple and advanced media playback capabilities already for you.  if all you need is a simple mediaelement in your silverlight application, then sure, it's a bit heavy.  but if you are developing a media playback integration with end-user controls, you may want to consider it.  it provides all the simple play/pause/etc functionality, but also the glitz of volume slider handlers, time thumb handlers, fullscreen view, etc.  very slick.

anyhow, maybe you decide to go this route and create your killer player with your own xaml (you can see a screencast of this here).  you decide you are sick with cut/paste every time and using the stub and having to replace.  no problem, create your experience as a custom template!  here's how.

first, take a look at the template files in the expression encoder template folder (<installdir>\Microsoft Expression\Encoder 1.0\Templates\en).  you'll see all sorts of replacement code in there.  if you like all of the functionality, then don't change a thing (except your xaml).  if you have special code in your implementation then spend some more time looking at the replacement values and see what you have to modify.  for our purposes here, let's assume we are only modifying the xaml UI. 

create a new folder in the Templates\en (or your language) directory.  it doesn't matter what you name it here...this is not what shows up in the output options.  i've named mine 'TimHeuerSimple' just to be clean and, well simple.

then what i do (remember in this sample here we are only replacing the xaml ui) is copy the contents of a previous template (i use corporate silver) and put it in my new folder.  done.  now you have (or should) make three changes:

    1. edit the player.xaml file in the new folder to be your desired xaml.  should be a simple open, select all, paste, save operation for most.
    2. create a new preview image so the user can get a glimpse of the preview.  it doesn't have to be named preview.jpg, but as long as it is, you'll save yourself one more change :-).  the other preview images are 649x487 so i just stuck with those sizes as well.
    3. open the Default.html file.  look at line 2.  here is where you'll change to the template name you want the user to see.  your templates are always added to the bottom of the other template listings, so no need to get trickery here with the name.  NOTE: if you created your preview image as something other than 'preview.jpg' line 3 in this file is also where you will change the pointer to that preview.

boom, you are done.  now next time you start expression encoder, you'll see your template as an output option:

there you have it...now when you want to encode your media and have the output into your custom player (or perhaps a corporate/departmental standard look and functionality) you have it.

hope this helps!