Rewind and Fast Forward using the Smooth Streaming Media Element (SSME) Beta 2

Hey Folks! Time ago I blogged about how to add the Slow Motion capability to your Smooth Streaming player by using the Smooth Streaming Media Element published by the IIS team.

Now it’s time to share with you how to provide the rewind and fast forward options to enable a real rich video experience.

Again, adding support for these features is easy, and if you understood what we did for providing the Slow Motion experience, then the following will be a piece of cake.

For rewind, the trick is getting all the playback rates under 0.0 and for fast forward, all the playback rates above 1.0.

Show me the code!

Rewind
/// <summary>
/// Toogles the PlaybackRate of the Smooth Streaming Media Element.
/// Uses the PlaybackRates under 0.0 to support Rewind.
/// </summary>
public void OnRewind()
{
    // PlaybackRate index to set on the SSME.
    int newPlaybackRateIndex = 0;
    // Verify the state of the SmoothPlayer
    if (this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Paused
        || this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Playing
        || this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Buffering)
    {
        // Get the current PlaybackRate of the SSME
        double playbackRate = this.PlaybackRate;
        // The first time we get the Rewind PlaybackRates from
        // the SSME supported PlayBackRates. Rewind PlaybackRates 
        // are under 0.0
        if (this.rewindPlaybackRates == null)
        {
            this.rewindPlaybackRates = new List<double>();
            IList<double> supportedPlaybackRates = this.SmoothPlayer.SupportedPlaybackRates;
            for (int i = 0; i < supportedPlaybackRates.Count - 1; i++)
            {
                if (supportedPlaybackRates[i] < 0.0)
                {
                    this.rewindPlaybackRates.Add(supportedPlaybackRates[i]);
                }
            }
            this.rewindPlaybackRates.Add(1.0);
        }
        // Verify if the current PlaybackRate is within the 
        // allowables values. Get the index of the new 
        // PlaybackRate to set.
        if (playbackRate >= 0.0)
        {
            newPlaybackRateIndex = 0;
        }
        else
        {
            for (int i = 0; i < this.rewindPlaybackRates.Count - 1; i++)
            {
                if (this.rewindPlaybackRates[i] == playbackRate)
                {
                    newPlaybackRateIndex = (i + 1) % this.rewindPlaybackRates.Count;
                    break;
                }
            }
        }
        this.SmoothPlayer.SetPlaybackRate(this.rewindPlaybackRates[newPlaybackRateIndex]);
    }
}
Fast Forward
/// <summary>
/// Toogles the PlaybackRate of the Smooth Streaming Media Element.
/// Uses the PlaybackRates greather than 1.0 to support Fast forward.
/// </summary>
public void OnFastForward()
{
    // PlaybackRate index to set on the SSME.
    int newPlaybackRateIndex = 0;
    // Verify the state of the SmoothPlayer
    if (this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Paused
        || this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Playing
        || this.SmoothPlayer.CurrentState == SmoothStreamingMediaElementState.Buffering)
    {
        // Get the current PlaybackRate of the SSME
        double playbackRate = this.PlaybackRate;
        // The first time we get the Fast Forward PlaybackRates from
        // the SSME supported PlayBackRates. Fast Forward PlaybackRates 
        // are above 1.0
        if (this.fastForwardPlaybackRates == null)
        {
            this.fastForwardPlaybackRates = new List<double>();
            IList<double> supportedPlaybackRates = this.SmoothPlayer.SupportedPlaybackRates;
            for (int i = 0; i < supportedPlaybackRates.Count - 1; i++)
            {
                if (supportedPlaybackRates[i] > 1.0)
                {
                    this.fastForwardPlaybackRates.Add(supportedPlaybackRates[i]);
                }
            }
            this.fastForwardPlaybackRates.Add(1.0);
        }
        // Verify if the current PlaybackRate is within the 
        // allowables values. Get the index of the new 
        // PlaybackRate to set.
        if (playbackRate <= 1.0)
        {
            newPlaybackRateIndex = 0;
        }
        else
        {
            for (int i = 0; i < this.fastForwardPlaybackRates.Count - 1; i++)
            {
                if (this.fastForwardPlaybackRates[i] == playbackRate)
                {
                    newPlaybackRateIndex = (i + 1) % this.fastForwardPlaybackRates.Count;
                    break;
                }
            }
        }
        this.SmoothPlayer.SetPlaybackRate(this.fastForwardPlaybackRates[newPlaybackRateIndex]);
    }
}

For more information about the SSME Beta 2 release, check Vishal’s post : IIS Smooth Streaming Player Development Kit Beta 2 released

Enjoy it!
kick it on DotNetKicks.com
Shout it

PRISM @ CodeCamp Buenos Aires 2009

This post announces an event being held at Buenos Aires, Argentina.

CodeCamp Buenos Aires 2009

 

On September 26th, a new CodeCamp will take place at Buenos Aires. This year, I will join my teammate Diego Poza and together we will talk about how to develop composite applications for WPF & Silverlight using PRISM. Our presentation starts at 4:15 PM and will last 1 hour.

 

During the presentation we will go over PRISM Core Concepts and show a real-world implementation. Don’t miss the surprises at the end of the session.

Desarrollando aplicaciones modulares en WPF y Silverlight con Prism

On a related topic, Southworks is one of the sponsors of the event and several other southies will be presenting as well:

  • Matias and Johnny will be presenting about Mega Datacenters with Windows Azure. Johnny will also join Zaiden and together they will present about VS 2010 and C# 4.0
  • Martin Salias will be in functional mode explaining the main advantages of F#.
  • Nico Paez will be talking about open source tools for .NET
  • Beto, our IT Pro, will be off the charts. He will present in four sessions talking about Hyper-V, Windows Server 2008 R2 and SSME (SCOM, SCVMM, SCDPM).

Are you going to miss this amazing event? Register Now!

Where: Universidad de Palermo, Mario Bravo 1050, Buenos Aires

Time: From 9:30 AM to 19:00 PM

See you in the event and in the Southworks booth.

Live Smooth Streaming: How-to: Start, Stop & Shutdown a Publishing Point Programmatically

During the last months I have been working in a project highly related to multimedia and iis-smoothclient development technologies such as Silverlight. And in the last few weeks, I started to look to some of the new IIS Media services such as Smooth Streaming and Live Smooth Streaming in order to gather as much knowledge about them to perform some spikes for the project.

One of the things that came up while spiking was finding a way to start, stop & shutdown a publishing point via code.

Microsoft.Web.Administration to the Rescue

ServerManagerWith IIS7 a new API to administer IIS from managed code was introduced. This API is really simple to use and with a few lines of code you can manipulate the server configuration as any other information available in IIS7. (if you want to taste the power of this API, I recommend you to read this post from Carlos Aguilar Mares).

So, I used the Microsoft.Web.Administration.dll assembly, that can be found at IIS Directory (%windir%\System32\inetSrv), to perform the operations over the publishing point. But it was not so easy to do it, as there is no information available yet about what RSCA function has to be called  and which parameters need to be used in order get the desired results.

Then, I started to look at the different IIS configuration files (%windir%\System32\inetsrv\config) searching for clues and I came up with the Microsoft.Web.Management.Media.LiveStreaming.dll assembly (this assembly can be found in the GAC after installing the Live Smooth Streaming bits).

In that moment I summoned my best friend Reflector and together went to the depths of this assembly until we found some code that might be useful for our objective.

After doing some tests, I ended up with the following method:

private static void ExecuteRscaFunction(ConfigurationElement workerProcess,
                                        string siteName, string applicationPath,
                                        string fileName, string functionName)
{
    ConfigurationMethod configurationMethod = workerProcess.Methods["GetCustomData"];

    ConfigurationMethodInstance instance = configurationMethod.CreateInstance();
    instance.Input["guidIdOfFunctionCall"] = “Media_LiveStreaming_Control”;

    string currentLogicalPath = applicationPath;

    if (!currentLogicalPath.EndsWith(“/”, StringComparison.OrdinalIgnoreCase))
    {
        currentLogicalPath = currentLogicalPath + “/”;
    }

    string fullPath = string.Concat(currentLogicalPath, fileName);
    string parameters = string.Format(CultureInfo.InvariantCulture, “{0};{1};{2}”,
                                      functionName, siteName, fullPath);
    instance.Input["parametersOfFunctionCall"] = parameters;
    instance.Execute();
}

The most important thing of the method above is the functionName parameter. This parameter can be one the following values depending on what you want to accomplish:

  • StartPublishingPoint. This is used to start a publishing point.
  • StopPublishingPoint. This is used to stop the live source of the publishing point.
  • ShutdownPublishingPoint. This is used to shutdown a publishing point.

To understand where the others parameters should come from, let’s take a look at the following example: image So, if we want to the start the LiveSmoothStream publishing point associated to the SmoothStreaming application from the Default Web Site, we should call the ExecuteRscaFunction method in this way:

ExecuteRscaFunction(workerProcess,
                    “Default Web Site”, “/SmoothStreaming”,
                    “LiveSmoothStream.isml”, “StartPublishingPoint”);

The remaining parameter (workerProcess) must be retrieved from the application pool associated to the application.

Note: You can use the Microsoft.Web.Administration API to get all the values previously mentioned.

To see if the function is working you can add the following lines of code at the end of the method to parse the output and print it on the console.

string rawOutput = instance.Output["data"] as string;

byte[] bytes = Convert.FromBase64String(rawOutput);
ASCIIEncoding encoding = new ASCIIEncoding();

Console.WriteLine(encoding.GetString(bytes));

The output after executing the Stop, Shutdown and Start functions:

image

Hope this helps!. If you want to learn more about Smooth Streaming you might find useful the following links:

Happy streaming!.

kick it on DotNetKicks.com

Prism v2: Migrating from Drop 9 to Drop 10

As you may know, last Friday a new drop of the Composite Application Guidance for WPF & Silverlight was released.

As Erwin said in this post, one of the breaking changes of this new drop is that they removed the .Silverlight and .Desktop extensions from the Assembly names. If you are like me and have more than one solution using Prism v2 with a bunch of projects, you will probably find really annoying going over each project to update the references and the xaml files.

So, in order to accomplish this, I created a Powershell script that will look for all the .csproj and .xaml that contain references to the old prism assemblies and will update it to the new version of them.

Note: If you have your code in TFS, make sure to go offline before running the script, so when you go back online it will detect the changes.

Disclaimer

This code is provided “AS IS” with no warranties, and confers no rights.

Download

You can find the script here.

 

Hope you find it useful.

Silverlight & Composite Application Guidance (Prism): Spike published

Weeks ago we shipped the Composite Application Guidance for WPF and with the Prism team we started to spike around the migration of the Composite Application Library to Silverlight 2 Beta 2. The good news is that yesterday we published that spike. (A ’spike’ is a small and quickly developed sample application in order to mitigate some risks).

After downloading and decompressing the latest change set of the source control, you will find a new folder named spikes that contains the Composite Application Library migrated to Silverlight. As you may imagine, there were many challenges that we had to address in order to make it “work”  (Rob Eisenberg wrote two articles describing differences between WPF and Silverlight that you might want to check: There’s some darkness in your silver light and Silverlight Problems That Affect Me).

Note: The migration is not complete, we used the spike to have a perspective of the challenges.

 

Modularity

Module loading in Silverlight is very different from WPF, so this was a challenge. We continued spiking on different approaches, but those spikes are not uploaded to Codeplex yet.

Regarding the module enumerators, System.Configuration is not supported by Silverlight current version, so we are using a new XML file module enumerator (not published either).

Regions

In WPF, the RegionManager attached property value gets inherited by the elements in the visual tree. This cannot be done in Silverlight due to the lack of the FrameworkPropertyMetadataOptions.Inherits option. However, we have found a workaround for this issue.

If you want to declare regions in XAML, you have to create an application resource to store the RegionManager instance, so it can be used by the views. This can be done in the Bootstrapper, as shown in the code below:

protected override void ConfigureContainer()
{
   base.ConfigureContainer(); IRegionManager regionManager = Container.Resolve<IRegionManager>();
   Application.Current.Resources.Add(“RegionManager”, regionManager);
}

And the view has to explicitly set the RegionManager attached property to the resource created previously.

<ItemsControl x:Name=”MainRegionControl” cal:RegionManager.RegionName=”MainRegion” cal:RegionManager.RegionManager=”{StaticResource RegionManager}” />

Events

Events has been migrated successfully, however, the unit tests are still a challenge because of the differences in threading between Silverlight and WPF. One difference we found, is that if you are subscribing to an event using weak references, for this reason you can only use public methods as delegates (lambdas, anonymous delegates or private methods won’t work) because of security restrictions enforced by Silverlight.

Commands

As you might know, the support for commands is missing in Silverlight. This is really bad news, considering that big part of our guidance talk about using Commands for communication between the modules and from the view.

I’m not going into deep details on this because Julian Dominguez published a great post explaining how to use commands in Silverlight.

Download

You can get the spike by downloading the latest change set of the CompositeWPF source control.

Notes

  • We didn’t ship the Unity Application Block, so I recommend you to see Michael Sync’s post in order to have Unity working on Silverlight.
  • In order to run the Unit tests, check Jeff Wilcox’post.

Feedback  / Contributions

Feel free to give us your feedback on the discussion board. If you want to contribute with the CompositeWPF project, check the CompositeWPF contrib. community site.

Enjoy!

CompositeWPF (Prism) Contrib Latest Additions

A week ago we shipped the Composite Application Guidance for WPF and many people (including me) started to contribute in the CompositeWPF Contrib community project and to play with the guidance.

Let’s explore the latest additions added to the CompositeWPF Contrib project.

  • CompositeModuleEnumerator. The CompositeModuleEnumerator makes it possible to combine several module enumerator instances into one module enumerator. This makes it easier for developers to for example combine both fixed modules and modules loaded through the ConfigurationModuleEnumerator.
    image
    For more information about the CompositeModuleEnumerator, see Combining module enumerators in CompositeWPF.
  • ToolBarPanelRegionAdapter. This adapter adapts control of type System.Windows.Controls.Primitives.ToolBarPanel and derived classes.
  • Visual Studio Templates. The goal of these templates is to help users start with the Composite WPF project
    For more information about the Visual Studio Templates, see Composite Application Guidance for WPF Visual Studio Templates.

I’ve been also reorganizing the folder structure of the project, so if you download the latest change set you will find the following structure:

image

If you want to contribute to the project, please follow the Sign Up Process.

Enjoy!

How-to: Fix the ‘The “ValidateXAML” task failed unexpectedly’ error after installing Microsoft Silverlight Tools Beta 2

Last week I’ve installed Microsoft Silverlight Tools 2 Beta 2 on my laptop to start developing applications for Silverlight 2 Beta 2.

Once the installation finish, I created a Silverlight Application just to see if everything works as expected. The application was successfully created but when I tried to build and run the solution, I faced with the following error:

image

After spend some time searching for some clues, I found the following solution:

  1. Open the Visual Studio 2008 Command Prompt.
  2. Execute devenv /ResetSkipPkgs in the command prompt.
    This switch clears all options to skip loading added to VSPackages by users wishing to avoid loading problem VSPackages. This switch also starts Visual Studio.
  3. Close Visual Studio and then execute devenv /Setup in the command prompt.
    This switch forces Visual Studio to merge the resource metadata that describes menus, toolbars, and command groups from all VSPackages available
  4. Open Visual Studio and have fun.

For more information about the Devenv Command Line Switches, see Devenv Command Line Switches on MSDN.

Hope this helps.

Silverlight: Where to start?

logo_main_sl

Microsoft Silverlight is a cross-browser, cross-platform plug-in for delivering the

next generation of .NET based media experiences and rich interactive applications (RIAs) for the Web. Silverlight offers a flexible and consistent programming model that supports AJAX, Python, Ruby, and .NET languages such as VB and C#, and integrates with existing Web applications. Silverlight media capabilities include fast, cost-effective delivery of high-quality audio and video to all major browsers including Firefox, Safari and Internet Explorer running on the Mac or on Windows. By using Expression Studio and Visual Studio, designers and developers can collaborate more effectively using the skills they have today to create Silverlight web experience.


Downloads

Articles & Blog Posts

Main Sites

Learn

Screencasts

Resources & other stuff

Books

Blogs