Thursday, 25 March 2010

Showing MPEG Videos in Silverlight (or, how to hide the Silverlight control using jQuery)

Recently I've had the very interesting opportunity to work on a project which has a Silverlight front-end and a SharePoint back-end.  Silverlight only supports the WMV format for video, so we handle WMV files natively in Silverlight.  But there was a requirement to also allow other formats (MPEG for example).  We decided to try a third-party tool called Clearbox to show MPEGs (and other file formats) using a "lightbox" approach.

Clearbox:  http://www.clearbox.hu/index_en.html
Lightbox:  http://en.wikipedia.org/wiki/Lightbox_(JavaScript)

Essentially, the solution is to pass the desired file's URL to some Javascript code from Silverlight.  But then the problem becomes, a) how do you hide the Silverlight control when you're displaying your video or image in Clearbox and b) how do you bring back the Silverlight control once the user is done viewing the video or image?

I was pleased with the trick I came up with and I thought I'd share it.

1. Call a Javascript function from Silverlight.

Assume you've got the URL of your MPEG or image file (as a string in C#); this URL (with respect to the requirements of input parameters in Clearbox), would look like something like this:

string filePath = “http://someSPSite/sites/someSPSubsite/someDocumentLibrary/SomeMPEGVideoFile.mpeg”;

You can pass parameters to ClearBox to indicate height and width, or just use the default.  Here are a couple of examples.

example 1:

// jpeg example

ScriptObject script = (ScriptObject)HtmlPage.Window.GetProperty(“clearBoxCaller”);

script.InvokeSelf(“href=” + filePath);

example 2:

// mpeg example

ScriptObject vidScript = (ScriptObject)HtmlPage.Window.GetProperty(“clearBoxCaller”);

vidScript.InvokeSelf(“width=740,height=250,href=” + filePath);

2. Install and set up ClearBox.

a) install ClearBox so clearbox.js (and the clearbox directory) are the same location as your HTML file that hosts the Silverlight control.  See the ClearBox website for more information.

b) configure ClearBox to call a function when the user closes the box.

There is a setting in cb_config.js you must set:

CB_AllowExtFunctCBClose=’on’

This will run a function called

CB_ExternalFunctionCBClose( )

when the user closes ClearBox.  This will be essential using this method I’m describing.

3.  Populate your host HTML file with certain style and script references.

a) you need a style that is used for the Silverlight control when it is visible, and another style that is used to make it invisible.  Note that I’m simply setting the height and width values to zero to make the control invisible.  Here’s what I used:

<style type="text/css">
     DIV.sl
      {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 1024px;
      height: 580px;
      margin-left: -512px;
      margin-top: -290px;
      }

      DIV.slInvisible
      {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 0px;
      height: 0px;
      margin-left: -512px;
      margin-top: -290px;
      }
</style>

b) Then you need references to the jQuery library and Clearbox:

<script src="jquery-1.4.1.js" type="text/javascript"></script>
<script src="clearbox.js" type="text/javascript"></script>

c) Now you need the function calls.  Essentially all this does is to use jQuery selectors and the jQuery “addClass” method to remove the “visible” style, and replace it with the “invisible” style (and use the other function to do the reverse when the user closes ClearBox).  The first function (as indicated by its name) then calls ClearBox (using its CB_Open function) with the parameters you passed in from your Silverlight code:

<script type="text/javascript">

function clearBoxCaller(cbParms) {

$("#silverlightControlHost").removeClass('sl');
$("#silverlightControlHost").addClass('slInvisible');
CB_Open(cbParms);     

}

function CB_ExternalFunctionCBClose() {
            $("#silverlightControlHost").removeClass('slInvisible');
$("#silverlightControlHost").addClass('sl');   

}

</script>

d) finally, your Silverlight control needs to have an ID that allows it to be referenced by the scripts and styles shown above:

<div id="silverlightControlHost" class="sl">

<object data="data:application/x-silverlight," type="application/x-silverlight-2", width="100%" height="100%" id="SilverlightControl">

</object>

</div>

If all is done properly according to the steps above, then, voila… when you invoke the “clearBoxCaller” script from your Silverlight code, Silverlight should disappear, your Clearbox should appear and display the desired image or MPEG video, and when the user closes ClearBox, the Silverlight control will reappear exactly as it was previously. 

4. Pour yourself a cool drink and enjoy!

The Usual Disclaimers:  This code and the ideas described herein are provided without warranty of any kind and I take no responsibility for any problems you may experience.