Archive for the 'IIS7' Category

Common mistakes / issues when creating and using Composite Stream Manifests (.CSM)

One of the greatest features added on the Beta 2 version of the IIS Smooth Streaming Player Development Kit (SSPDK) is the support for Composite Stream Manifests for Rough Cut Editing. This a powerful feature which I really recommend looking at, and if you want to learn the basics of the CSMs you must take a look at the following posts:

I’ve been working with CSMs for three months now, so in this post I would like to share with you the lessons I’ve learnt during the process of creation and usage of the CSMs.

There are a few common mistakes and issues you might face during that process, so I hope this post will be helpful for the community. 

 

Configure IIS to serve .CSM files

In order to do that, you have to add a mime type entry on IIS for the .CSM extension on every IIS server that is serving up the .csm files. The mime type for the .csm must be “text/xml”. You can do this on the IIS Manager. Also you can achieve the same by editing the applicationHost.config and adding the following line:

 <mimeMap fileExtension=”.csm” mimeType=”text/xml” />

 

“Error encountered on HEAD request to manifest uri <your manifest> for <position> clip in RCE manifest”

This will likely be the first issue you will encounter after trying to use a CSM. When using a CSM the Smooth Streaming Media Element (SSME) attempts to do a HEAD request on the manifest for each clip to make sure that the content hasn’t been moved (and if it has, it will used the new URL on the response).

There are two changes you have to make in order to fix this issue.

The first one is related to an existing known-issue on the applicationHost.config file of IIS. This server bug prevents the On-Demand smooth streaming handler from responding to HEAD request. To fix this go to the Smooth Streaming Readme page and check the Known Issues section, specifically the “Configuring the SmoothHandler handler mapping to process HTTP Head requests” item.

The second change must be done on the clientaccesspolicy.xml file, essentially to indicate that HEAD requests are allowed. To fix this make sure that your clientaccesspolicy.xml file includes http-methods=”*”or http-methods=”GET,HEAD,POST”:

<?xml version=”1.0″ encoding=”utf-8″?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-methods=”*” http-request-headers=”*”>     
        <domain uri=”*”/>
      </allow-from>     
      <grant-to>     
        <resource path=”/” include-subpaths=”true”/>
      </grant-to>     
    </policy>
  </cross-domain-access>
</access-policy>

 

“Caught exception trying to parse main manifest: V2 Manifest: Audio stream requires CodecPrivateData attribute”

This is because the CSM contains a clip that is referring a V1 Manifest, which is not a valid source for a CSM.

 

“Caught exception trying to parse main manifest: First video (audio) chunk in clip <position> [start time = <start time>, duration = <duration>] does not contain clip start position <clipStartPosition>”

This message indicates that the first chunk time + the first chunk duration of the reported stream is smaller or larger that the clip’s begin position. Therefore the first chunk time + the first chunk duration of the stream must contain the clip’s begin position.

 

“Caught exception trying to parse main manifest: Last video (audio) chunk in clip <position> [start time = <start time>, duration = <duration>] does not contain clip end position <clipEndPosition>”

This message indicates that the last chunk time + the last chunk duration of the reported stream is smaller or larger that the clip’s end position. Therefore the last chunk time + the last chunk duration of the stream must contain the clip’s end position.

 

Different Audio encoding settings in the CSM clips

If you have clips with different audio encoding settings, then the playback will suddenly stop. Due to a limitation on Silverlight, the audio settings have to be the same. The Silverlight pipeline is not able to handle audio property changes on the fly. So make sure that the audio of the clips are being encoded at same bit rate.

 

Sparse stream data within the clip

This will likely not cause any issue, but as today having sparse stream data within a clip is not supported I decided to include it on this list.

 

As you see, there are a couple of things to have in mind when creating and using composite stream manifests. I hope this post encourages you to use this amazing feature.

 

Happy streaming!

kick it on DotNetKicks.com

Shout it

Live Smooth Streaming: Managing Publishing Points Programmatically on IIS Media Services 3.0

Many people have been asking me how to manage publishing point programmatically on IIS Media Services 3.0 (instead of the 2.0 bits, as I explained in this post)

So, I started to dig and I came up with the following code:

// Live Streaming Section Path
const string LiveStreamingSectionPath = “system.webServer/media/liveStreaming“;
 
// Change this settings with your values
 
// Site name
string siteName = “Default Web Site“;
// Application name
string applicationName = “/SmoothStreaming“;
// Publishing point filename
string fileName = “LiveSmooth.isml“;
 
ServerManager serverManager = new ServerManager();
 
// Gets the site from IIS
Site site = serverManager.Sites[siteName];
 
// Gets the application from IIS
Application application = site.Applications[applicationName];
 
// Gets the LiveStreamingSection from the site configuration 
ConfigurationSection section = site.GetWebConfiguration().GetSection(LiveStreamingSectionPath);
 
// Gets the ConfigurationMethodInstance to get the available publishing points
ConfigurationMethodInstance instance = section.Methods["GetPublishingPoints"].CreateInstance();
 
// Sets the input parameters of the GetPublishingPoints method
instance.Input["siteName"] = site.Name;
instance.Input["virtualPath"] = applicationName;
 
// Executes the method
instance.Execute();
 
// Gets the PublishingPointCollection type.
Type type = Type.GetType("Microsoft.Web.Management.Media.LiveStreaming.PublishingPointCollection, Microsoft.Web.Management.Media.LiveStreaming“);
 
// Gets the PublishingPointCollection associated with the method output
ConfigurationElement collection = instance.Output.GetCollection(type);
 
// Gets an item from the collection using the Publishing Point fileName as parameter. 
// The item is of type PublishingPoint.
object pubPoint = collection.GetType()
                            .InvokeMember("Item“,
                                          BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance,
                                          null, collection, new object[] { fileName }, null);
 
// Invokes the desired method of the Publishing Point. 
// In this case we are calling the Start method (others supported functions are “Shutdown” and “Stop”)
pubPoint.GetType().InvokeMember("Start“,
                                BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                                null, pubPoint, null);

Remember that in order to use the previous code, you must have references to the following assemblies:

  • Microsoft.Web.Administration.dll (can be found at IIS Directory %windir%\System32\inetSrv)
  • Microsoft.Web.Management.Media.LiveStreaming.dll (can be found in the GAC after installing the Live Smooth Streaming bits)

Hope this helps.

Happy streaming!

kick it on DotNetKicks.com
Shout it

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

Slow Motion using the Smooth Streaming Media Element (SSME)

The week started with really great news from the IIS Team. The IIS Media Services 3.0 streaming was released. Among others features the release includes the RTW bits of Live Smooth Streaming.

Also, in the efforts to bring the Smooth Streaming experience to everyone the IIS team published the IIS Smooth Streaming Player Development Kit 1.0 – Beta 1 which is intended to aid the development of rich Smooth Streaming experiences.

Bunch of posts to review if you are not aware of the new releases:

I’m very excited with this release, as we have been using the Smooth Streaming Media Element almost from its beginning mainly for the work we did for the NBC Sunday Night Football event. (see here & here). I will start sharing with you how to take advantage of the SSME.

In this post I will show you how easy is to bring an Slow Motion experience using the SSME. Vishal blogged a great SSME getting started guide that I encourage you  to review before digging into the details of this post.

Adding support for Slow Motion to your Smooth Player is really easy, and basically what you have to do is getting the playback rates between 0.0 and 1.0, and move across them every time you click your Slow Motion button on the player.

Below you will find a code snippet ready to be used that will help you to implement the Slow Motion logic.

private List<double> slowMotionPlaybackRates;
/// <summary>
/// Toogles the PlaybackRate of the Smooth Streaming Media Element.
/// Uses the PlaybackRates between 0.0 and 1.0 to support Slow Motion.
/// </summary>
public void OnSlowMotion()
{
    // PlaybackRate index to set on the SSME.
    int newPlaybackRateIndex = 0;
    // Verify the state of the SmoothPlayer
    if (this.SmoothPlayer.CurrentState == MediaElementState.Paused
        || this.SmoothPlayer.CurrentState == MediaElementState.Playing
        || this.SmoothPlayer.CurrentState == MediaElementState.Buffering)
    {
        // Get the current PlaybackRate of the SSME
        double playbackRate = this.SmoothPlayer.PlaybackRate;
        // The first time we get the SlowMotion PlaybackRates from
        // the SSME supported PlayBackRates. SlowMotion PlaybackRates 
        // are between 0.0 and 1.0.
        if (this.slowMotionPlaybackRates == null)
        {
            this.slowMotionPlaybackRates = new List<double>();
            IList<double> supportedPlaybackRates = this.SmoothPlayer.SupportedPlaybackRates;
            for (int i = 0; i < supportedPlaybackRates.Count; i++)
            {
                if (supportedPlaybackRates[i] > 0.0 && supportedPlaybackRates[i] < 1.0)
                {
                    this.slowMotionPlaybackRates.Add(supportedPlaybackRates[i]);
                }
            }
            this.slowMotionPlaybackRates.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 || playbackRate >= 1.0)
        {
            newPlaybackRateIndex = 0;
        }
        else
        {
            for (int i = 0; i < this.slowMotionPlaybackRates.Count; i++)
            {
                if (this.slowMotionPlaybackRates[i] == playbackRate)
                {
                    newPlaybackRateIndex = (i + 1) % this.slowMotionPlaybackRates.Count;
                    break;
                }
            }
        }
        this.SmoothPlayer.SetPlaybackRate(this.slowMotionPlaybackRates[newPlaybackRateIndex]);
    }
}

Hope you find the code snippet useful. Stay tuned!, new posts are coming.

PS: If you face any issue with the Smooth Streaming Development Kit or if you just want to provide feedback to the IIS team, please use this thread.

Live Smooth Streaming: How-to: Retrieve the configuration settings programmatically

In my previous post, I explained how the Microsoft.Web.Administration API of IIS7 helped us to manage the Live Smooth Streaming Publishing Points programmatically. In this post I’m going to show you how, using the same API, you can retrieve the Live Smooth Streaming configuration settings.

First, let’s take a look at the Live Smooth Streaming configuration settings window

image

The main idea here is to read the Live Streaming configuration section and get the attributes values from there. The piece of code looks like:

const string LiveStreamingSectionPath = “system.webServer/media/liveStreaming”;

ServerManager serverManager = new ServerManager();

Configuration configuration = serverManager.GetApplicationHostConfiguration();
ConfigurationSection section = configuration.GetSection(LiveStreamingSectionPath);

if (section != null)
{
    foreach (ConfigurationAttribute attribute in section.Attributes)
    {
        Console.WriteLine(“{0}: {1}”, attribute.Name, attribute.Value);
    }

    Console.ReadLine();
}

Running the preceding code will output the following:

image

As you see, reading the configuration settings is easy and can enable you different scenarios, for example, deleting the archived streams of a publishing point.
If you want to take a look at the Live Smooth Streaming schema, go to %windir%\System32\inetsrv\config\schema and open the IISMedia_LiveStreaming_schema.xml file.

Happy streaming!

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