Silverlight MediaElement Playing a Video stored in Windows Azure Blob Storage

There are two things that I want to show in this post:

  1. That you can use Silverlight in a Windows Azure Cloud Service
  2. That you can stream a movie progressively via http (more about that here) from Windows Azure Blob storage

The code is attached to this blog post.  Note that you will have to add and reference the Common and StorageClient projects that come as samples in the Windows Azure SDK.

What I did, is start with my Simple Blob Storage Walkthrough and adapted it to be a Video Store instead.

image

The top part of the app is really the same as in the Simple Blob Storage Walkthrough where another column was added to the GridView to provide play buttons.

When you hit play, the Silverlight control sitting underneath the form part of the page uses a MediaElement to play the video.  The video is played directly from its location in blob storage.

Adding Silverlight

Starting where the Simple Blob Storage Walkthrough finished off, lets add Silverlight to that project.  (this assumes that you have Silverlight Tools installed.  See here for more information)

Note that you may have to configure the mime type in IIS for Silverlight -- you'll know if you get a "Could not download Silverlight application"error:

Registering MIME type in development fabric

To ensure solutions containing Silverlight clients work correctly in the development fabric, please ensure that the MIME type for the Silverlight .xap extension is configured correctly in IIS.

1. Open Internet Information Services (IIS) Configuration Manager and select the server to manage (usually the top-level item on the left side)

2. Double-click MIME Types on the right side

3. Add an entry to map the .xap extension to the application/x-silverlight-app MIME type

Right click on the solution node in the Solution Explorer and select Add -> New Project.  Select "Silverlight Application":

image

Name the project VideoPlayer.

Select to "Link this Silverlight control into an existing Web site" and make sure that your Web Role is selected.  For this walkthrough I chose not to add a test page as I want to add the Silverlight control onto the existing page.

image

Solution Explorer will now look contain a Silverlight project and will look like this:

image

Open up Default.aspx and at the bottom of the page, just after the statusMessage Label you had from the previous walkthrough, add the following snippet to add the Silverlight control onto the page:

         <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <div style="height: 100%;">
            <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/VideoPlayer.xap" MinimumVersion="2.0.30523"
                Width="100%" Height="100%" />
        </div>

You also need to Register the Silverlight assembly otherwise the asp:Silverlight tag will come up as unknown.  You can do this at the top of Default.aspx, right under the "<%@ Page ..." tag:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DownloadSite_WebRole._Default" %>
<%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"
    TagPrefix="asp" %>

You may also have to add a reference to System.Web.Silverlight from your web Role (it can be found on the .Net tab of the add references dialog).

Open up Page.xaml and change the Background property of the Grid to "Green" so that we can see the control on the aspx page.  Hit "F5" to debug.

You should get the following:

image

Cool!  We have Silverlight!

Coding up the Silverlight Page

First we need a MediaElement to play the video.  Open up Page.xaml and add the MediaElement tag to the Grid as follows.  While we're at it, let's set the Width and Height of the Page to be 640 x 480 to make the video a little bigger and remove the Background attribute. 

Name the MediaElement "mediaPlayer".

 <UserControl x:Class="VideoPlayer.Page"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
    Width="640" Height="480">
    <Grid x:Name="LayoutRoot">
        <MediaElement x:Name="mediaPlayer"/>        
    </Grid>
</UserControl>

Note: A couple of issues I've been seeing (with the PDC October 2008 CTP) while developing Silverlight applications running on a Windows Azure Web Role: debugging doesn't seem to be working, the xap in the Web Role isn't always updating as expected resulting in a stale Silverlight UI on F5.  For the second problem, I found right clicking on the Silverlight project and hitting "Rebuild" then right clicking on the Web Role and hitting "Rebuild" before hitting F5 resolved the problem.  We're actively investigating both issues.

We'll just keep things really simple.  When the play button is clicked, we'll use Javascript to call a method on the Silverlight control passing in the URI that contains the video to play.

Let's add a scriptable method to the Page class in Page.xaml.cs:

 using System.Windows.Browser;
public partial class Page : UserControl
{
    {. . .}
    [ScriptableMemberAttribute]
    public void Play(string fileUriString)
    {
        if (!string.IsNullOrEmpty(fileUriString))
        {
            Uri fileUri = new Uri(fileUriString);
            mediaPlayer.Source = fileUri;
        }
    }
}

If you want to know more about the ScriptableMemberAttribute and how all this works, please see the MSDN article here.

The second part of making the control scriptable is to register the scriptable object.  That is done in App.xaml.cs in Application_Startup()

 using System.Windows.Browser;
private void Application_Startup(object sender, StartupEventArgs e)
{
    Page p = new Page();
    HtmlPage.RegisterScriptableObject("VideoPlayer", p);

    this.RootVisual = p;
}

Playing the Video

In order to play the video, we need to add a "play" button to each row of the GridView.

Open up Default.aspx and in the Columns for the GridView, add a column at the end for the Play button.  We'll use the <input/> tag for this as we don't want a postback to occur when we click the button (that will re-initialize the Silverlight control)

 <asp:TemplateField>
    <ItemTemplate>
        <input type="button" value="Play"/>
    </ItemTemplate>
</asp:TemplateField>

To that button, let's hook up an event handler when it gets clicked.  I did this programatically on the RowDataBound method on the fileView GridView control. 

The reason is that I wanted an easy way to pass the URI for the video to the Silverlight control.  In the RowDataBound event handler, I can get at the URI and pass it along as a parameter. 

The event handler will be run on the client side in Javascript.

In Default.aspx.cs in Page_Load(), register to handle the event:

 fileView.RowDataBound += new GridViewRowEventHandler(fileView_RowDataBound);

Then handle the event by adding the event handler for each of the <input/> buttons that will pass the URI as a parameter.

 void fileView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        FileEntry fe = (FileEntry)e.Row.DataItem;
        e.Row.Cells[3].Attributes.Add("onclick", "onGridViewRowSelected('" + fe.FileUri + "')");
    }
}

Finally, back in Default.aspx, we add the Javascript event handler that calls the scriptable method on our Silverlight control:

 <script language="javascript" type="text/javascript">
    function onGridViewRowSelected(fileUri) {
        var control = document.getElementById("Xaml1");
        control.content.VideoPlayer.Play(fileUri);
    }
</script>

Hit F5 to give it a try on the Development Fabric/Storage.  Upload a video sample (say from C:\Users\Public\Videos\Sample Videos) and then hit play.

One final thing to remember is the upload file size limit on the FileUpload control which is discussed in the Simple Blob Storage Walkthrough.  More likely you'll run into here with video files.

image

DownloadSite.zip

Comments

  • Anonymous
    November 05, 2008
    PingBack from http://www.tmao.info/silverlight-mediaelement-playing-a-video-stored-in-windows-azure-blob-storage/

  • Anonymous
    November 05, 2008
    Jim walks through adding a Silverlight control to a Windows Azure Cloud Service by showing a Silverlight

  • Anonymous
    November 21, 2008
    Will media element be able to play video streamed frame by frame?  I am talking about the case where you receive media from a live camera as a bitmap image frame by frame. If yes, how to achieve the same? How it has to be passed to the control?

  • Anonymous
    December 01, 2008
    Samir, that would be a great question to ask on the Silverlight forums: http://silverlight.net/forums/

  • Anonymous
    January 10, 2009
    Thank you for submitting this cool story - Trackback from DotNetShoutout

  • Anonymous
    February 12, 2009
    Hi jim, I've developed a Expression Encoder plug-in to store encoded videos @ Azure Blob Storage Services. It's a little bit related with this post i think. You can find the sources here: http://www.codeplex.com/azurepublisher

  • Anonymous
    July 31, 2009
    The comment has been removed

  • Anonymous
    August 03, 2009
    Ramach, that is what I meant in my last paragraph.  To resolve this you can modify the FileUpload size by changing the httpRuntime maxRequestLength attribute in web.config.

  • Anonymous
    July 27, 2010
    In MediaElement object, when you want to play a movie, the proposed file must be set "Resource" in "Build Action" Property. How you can solve this problem?

  • Anonymous
    July 27, 2010
    In MediaElement object, when you want to play a movie, the proposed file must be set "Resource" in "Build Action" Property. How you can solve this problem?

  • Anonymous
    July 28, 2010
    Mahyar, the media file in this case is being played from Blob storage in the cloud, not embedded as a resource in the assembly so build action doesn't come into play here.

  • Anonymous
    July 29, 2010
    Thanks Jnak! But, It does not work in Silverlight 3 & 4. You should add your file as resources in your project. Otherwise, MediaElement will not play the proposed file. this problem is issued in many blogs such as MSDN, personal blogs of developers or etc. Please search in Google or Bing: "MediaElement does not play the file+Silverlight" "Play none resouce file in MediaElement+Sliverlight" "Change BuildAction Progerty for Media File+Silverlight" .... Thanks for your attention to my comment

  • Anonymous
    July 29, 2010
    Moreover you can use these two asp.net code in silverlight 3 & 4 <asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/VideoPlayer.xap" MinimumVersion="2.0.30523"                Width="100%" Height="100%" /> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls"    TagPrefix="asp" %> And Visual Studio 2010 will add the following code instead of asp.net silverlight object and you cannot call Play() method. <form id="form1" runat="server" style="height:100%">    <div id="silverlightControlHost">        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="500" height="400">  <param name="source" value="ClientBin/VideoPlayer.xap"/>  <param name="onError" value="onSilverlightError" />  <param name="background" value="white" />  <param name="minRuntimeVersion" value="3.0.40818.0" />  <param name="autoUpgrade" value="true" />  <a href="go.microsoft.com/fwlink style="text-decoration:none">  <img src="go.microsoft.com/fwlink alt="Get Microsoft Silverlight" style="border-style:none"/>  </a>    </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>        </div>    </form>

  • Anonymous
    July 30, 2010
    I solved the calling scriptable method in Silverlight 4. you can consider the following page. msdn.microsoft.com/.../cc221414(VS.95).aspx But, MediaElement cannot loads none resource files as well as before.

  • Anonymous
    July 30, 2010
    Watch this link. they have same problem. forums.silverlight.net/.../247454.aspx