Welcome to MSDN Blogs Sign in | Join | Help

Random on Windows Media

After 10 years of supporting Windows Media I might have a few tips you could use.
Causes of 408's in a Windows Media Services log

One common question I get from Windows Media Services admins who have looked through their log files is about the cause of the 408 status codes.  Before answering the question directly, I need to define what a 408 is.  Simply put, it is an abnormal disconnect.  All it means is that at some point during the stream the client disconnected and did not report its statistics back to the server.  Normally Windows Media Player posts a log message back to the server that contains information about the client’s playback experience when the playback stops (or a similar event).  If the server does not receive this log post, for whatever reason, it takes the statistics it has compiled on its own and writes out a log entry with the c-status code of 408 in the log.

 

As for the causes, there could be a number of them.  The client simply could have lost its connection to the Internet.  In load balancing scenarios it’s not uncommon to see 408’s when the load balancer does not have affinity (sticky settings) set.  In load balancing scenarios, when the player attempts to post back to the server, particularly if the client is using HTTP 1.0 for the connection, it posts on a new TCP session.  That new session could get load balanced to a different server.  The original server that had streamed the audio/video to the client then does not receive the log post, so it logs a 408.  Occasionally we also see misbehaved clients (non-Windows Media Player clients that still report that they are WMP) and proxies.  I have noticed that in some logs clients that have the cs(User-Agent) field with a value of:  NSPlayer/9.0.0.2980.  This is the original release of WMP 9 with no hotfix updates.  It is extremely rare to see a client that has not been hotfixed.  More likely this is a proxy that is impersonating a WMP client.  It’s possible that the proxy is somehow not passing the client stats from the client on to the WMS server.

Using HTTP Referer to prevent deep linking to a WMS server

For a number of years now I've had customers ask me about how to prevent deep linking from random people directly to their Windows Media server.  Deep linking is described on http://en.wikipedia.org/wiki/Deep_linking.  Often this occurs when a web site owner does not ask for permission to point an embedded media player on their own site to a stream on someone else’s Windows Media server.  The web site owners who host their own Windows Media servers may want to allow only those clients that visit their web site access to the WMS server.  They may also want to have their client authenticate with a user name and password to be able to stream the video content.

Let me stop right here and say that the sample code that I’m providing is just that.  It’s sample code.  No warranty expressed or implied.  You’re on your own.  Let me also say that this is not going to keep your content 100% double extra secure.  It is just an easy *somewhat* secure way of preventing deep linking.  If you want high security, look into the Windows Media Rights Manager SDK.

Typically what I have recommended in the past is using an authorization plug-in running in WMS.  Essentially you would generate a query string on your web server that contains some unique value on the end (example:  mms://streaming.contoso.com/video.wmv?authorization=6883af2234jjji8).  In this example the authorization code of 6883af2234jjji8 would be unique for the session while browsing the web site.  You could then drop that value and a time/date stamp onto a SQL server.  You would write an authorization plug-in for WMS that would take the client request, look up the authorization ID in the SQL server and then allow or disallow the connection.  There are a number of variations on this theme, but typically it’s usually done somewhat like this.

I wanted to do something easier that required much less programming and didn’t have to have special web code or a third server (like SQL) to handle a deep linking issue.  The code example below is an Active Script sample.  Copy the code (or download it from the link below) and save it as a .vbs file in your C:\WMPub folder.  This folder has the appropriate NTFS permissions for WMS to be able to read from the .vbs and write the log file.  Then locate the WMS Active Script Event Handler in the WMS admin under Windows Media Services\<machine name>\Properties\Event notification.  In the Active Script plug-in, browse to the script sample in the WMPub folder.  Note, you will need to make one change to the third line in the script as noted in the comment in the code.  Enable the plug-in and you’re ALMOST done.  The way this script works is by reading the HTTP REFERER header value from the HTTP protocol from the user's GET request.  This GET request is made when you link to the content on your Windows Media server from the HTML page on your web server.  The HTTP REFERER is automatically included in the request.  If the user is not making a request from a web page on your web site, they will be denied access.

NOTE:  This value is not available with RTSP.  That means that you must turn off RTSP for this to work properly.

Here’s the code:

 Dim strMyServer
'Change the www.contoso.com value to the DNS name of your site.
strMyServer = "www.contoso.com"

Dim LogFile

Sub CreateLog
  Dim fso
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set LogFile = fso.CreateTextFile("c:\wmpub\wmroot\AuthorizationLog.txt", True)
End Sub

Sub TraceInformation( strTraceText )
    LogFile.WriteLine( strTraceText )
End Sub

Sub OnWMSPluginInitialize ( ServerCtx )
    CreateLog
    tempStr = "OnWMSPluginInitialize " & Now
    TraceInformation( tempStr )
End sub

Sub OnWMSPluginShutdown ()
    tempStr = "OnWMSPluginShutdown " & Now
    TraceInformation( tempStr )
    LogFile.Close
End sub

Function OnWMSEAuthorizeOpen (UserCtx, PresCtx, CmdCtx)
    Dim strReferer
    'Turning off error checking temporarily while getting the user context.  If there is no
    'referer context value then we do not want to end here with an error.  If there is no
    'referer context value we will fail at the first if statement and return the access denied.
    On Error Resume Next
    strReferer = UserCtx("WMS_USER_REFERER").Value
    On Error Goto 0
   
    tempStr = "Validating " & strReferer & " on " & Now
    Dim DomainName
    DomainName = GetLowerFQDN (strReferer)

    if DomainName = LCase(strMyServer) then
        OnWMSEAuthorizeOpen = &H00000000
        tempStr = tempStr & " - Access Granted"
    else
        OnWMSEAuthorizeOpen = &H80070005
        tempStr = tempStr & " - Access Denied"
    end if
    TraceInformation( tempStr )
End Function

Function GetLowerFQDN(strURL)
    'Strips off the initial http:// or https://
    tempDNS = Mid(strURL, InStr(strURL, "://") + 3)

    'Checks to see if a port number is used after the DNS name and strips that off.
    if Mid(tempDNS, 1, InStr(tempDNS, ":")) <> "" then
        tempDNS = Mid(tempDNS, 1, InStr(tempDNS, ":")-1)
    end if

    'Removes everything after and including the first slash.  What remains should be
    'the DNS name.
    if Mid(tempDNS, 1, InStr(tempDNS, "/")) <> "" then
        tempDNS = Mid(tempDNS, 1, InStr(tempDNS, "/")-1)
    end if
    GetLowerFQDN = LCase(tempDNS)
End Function

 

Using Windows Media Services 2008 Cache/Proxy plug-in

One of the main differences between Windows Media Services 9.1 on Windows 2003 and WMS 2008 on Windows Server 2008 is the inclusion of the Cache/Proxy plug-in.  In WMS 9.1 you had to compile (and write some of your own code to do caching) to have cache/proxy functionality.  WMS 9.1 also required that use have the Advanced Server SKU of 2003 to be able to use custom plug-ins.  With Windows Server 2008, even in the Standard SKU, the cache/proxy plug-in is included.

The first step in understanding how to configure the Cache/Proxy plug-in is to find it.  It’s not in the most obvious place in WMS.  It is not in this location:

 Proxy config is not located here

 

The above section is primarily for administering how the plug-in handles client connections.  Typically this is not something you need to configure at all since much of the focus on proxy configuration is dealing with the upstream connections.  Instead, you want to go up to the server level.  On the Properties tab you will see Cache/Proxy Management.  If you select this plug-in you will see WMS Cache Proxy on the right.  This is where you do most of the cache/proxy administration.  Since it is disabled, you will need to enable it to turn your server into a WMS Cache/Proxy server.  Here’s where to find it:

 Cache Proxy 2 - Configure the proxy here

All right, now we can actually configure the cache/proxy.  Go to Properties on the plug-in.

The first thing that you need to decide is the type of proxy that you are setting up.  I’m going to ignore the Proxy Redirect type for the purposes of this article and focus on Proxy and Reverse Proxy.  First, just to keep things a bit more clear I’m going to now refer to the term “Forward Proxy” instead of Proxy to contrast against the Reverse Proxy type even though you won’t see “forward proxy” referenced in the help docs.

 

Forward Proxy

A Forward Proxy is probably the easier of the two proxy types to understand because many people have already implemented something similar with a typical web proxy (such as Microsoft ISA server).  This type of proxy allows internal network clients to use a common access point for requesting content from the Internet.  The Forward Proxy is a “client focused” proxy where the main purpose is to save bandwidth on the client’s connection to the Internet.

You configure the Forward Proxy on the Proxy tab in the WMS Cache Proxy Properties dialog.  You simply select “Proxy” for the type of proxy.  That’s it.

Cache Proxy 3 - Forward Proxy config

With a Forward Proxy you would configure each Windows Media Player client (more on this later) to point to the Forward Proxy.  The Forward Proxy could be in a DMZ or be configured to be dual-homed so that one side is connected to the internal network and one side is connected to the Internet.  Here is a typical configuration:

 

Cache Proxy 4 - Forward Proxy network diagram

When a client is requesting content from the Internet, instead of making the request directly from the client to the Internet based WMS server, the client sends the request with the full URL to the WMS Cache/Proxy server.  This cache/proxy in turn makes the request to the Internet WMS server on the client’s behalf.  The cache/proxy then caches the content (if enabled) and sends the content to the client PC.  If another client requests the same URL, the content is served from proxies cache instead of using Internet bandwidth to get the file.  This can save quite a bit of network bandwidth upstream from the cache/proxy.  Again, this is very similar to the way you would setup a web proxy server such as ISA.

Because the forward proxy can work with any upstream or origin server (Internet based or internal server), you must configure Windows Media Player to point to the server acting as the WMS cache/proxy.  There are two main ways to do this.

 

Manual Location Configuration

This is done in Windows Media Player by going to Tools/Options/Network and configuring both HTTP and RTSP to point to the WMS cache/proxy.

Cache Proxy 5 - WMP proxy settings

In this dialog you would click on the Configure… button and choose the Use the following proxy server radio button and put in the proxy name or address.  Do this for both HTTP and RTSP since the WMS cache/proxy supports both protocols.

Using Group Policy to set the proxy

If your clients are joined to Active Directory then you can use Group Policy to push down a policy to configure Windows Media Player’s proxy settings.  This is very similar to the way you can push down the proxy settings for Internet Explorer.  Run the Group Policy Editor by going to Start/Run and typing in: gpedit.msc.  Navigate to User Configuration\Administrative Templates\Windows Components\Windows Media Player\Networking.  You can then configure the proxy settings for RTSP, HTTP, and MMS similar to how you configured it in Windows Media Player.

 

Reverse Proxy

By contrast, the reverse proxy is a more “server focused” proxy.  This is typically used for a Content Delivery Network (CDN) type of setup where you have a number of servers that you are load balancing to handle a large client load.  Instead of manually replicating on-demand content to each edge server or configuring each edge server for a live stream you can use a reverse proxy to “mirror” the content on an origin server.  Configure each of the reverse proxies to point to the origin server (via name or IP address) on the Proxy tab in the WMS Cache Proxy Properties.  Select the Reverse Proxy radio button.  Note that you can only specify one origin content server. 

Cache Proxy 6 - Reverse proxy settings

When a client makes a request to the reverse proxy the proxy checks its cache to see if it can serve the request locally.  If it cannot then it requests the content from the origin server, caches it locally, and sends the content to the client.  If the client is requesting a live stream then the reverse proxy will use a single connection back to the origin.  The proxy then splits the live stream so that multiple clients can view the stream even though only one connection is made back to the origin server.  Here is a typical reverse proxy setup:

 Cache Proxy 7 - Reverse Proxy network diagram

 

With a load balancer in front of the three reverse proxies in this diagram the three serves can handle much more load than a single server.   Note that typically the load balancer will expose a single URL to the client so that all three servers may appear as one address.

 

Capabilities

Feature

Forward Proxy

Reverse Proxy

Client configuration required

Yes

No

Can load balance proxies

Yes

Yes

Can proxy to any WMS server

Yes

No

Meant for corporate environments 

 Yes

 No

Meant for CDNs

 No

 Yes

 

 

Gotchas

·        While it is possible to use multiple tiers of reverse proxies, not all tiers will cache content or split streams.

·        Make sure you check the Limit Disk Quota box on the Cache tab.  Otherwise you may end up running out of disk space.

·        If you use server-side playlists on the origin server, the content will not be cached on a proxy.  This is because the proxy cannot predict the behavior of the server-side playlist.

·        Reverse proxies do not pass authentication requests from the origin to the client.  If you need to do authentication, then do the authentication on the reverse proxy itself.

·        When a server is configured as a reverse proxy, the local publishing points are no longer accessible.  The reverse proxy truly mirrors the origin server.

 

References

Caching and proxying content with Windows Media Services
http://www.microsoft.com/windows/windowsmedia/howto/articles/cache_proxy.aspx

 

WMP debug page to dump player events

Attached to this post I've included a HTML file (inside the zip) that I use all of the time to see what events the player is throwing.  I've used it to see if there are scripts in a customer's video, to see how many times my player rebuffers in a particular time period, to see what errors are being thrown, etc.  It's something that anyone that works with Windows Media streaming should have.  <Credit for it's creation goes to my friend Rob.>

Forcing the embedded player to reconnect when an error occurs

In the next few posts, I am going to discuss high availability scenarios for times when you absolutely must deliver your video. 

For today's post, I'm going to talk about how to have an embedded version of WMP reconnect to the stream if there is an error.  This is useful in the instances where you have a live stream and want the player to reconnect to the stream if there is an error.  Here is the sample:

<html>
<body>
<OBJECT ID="MPlayer" height="310" width="320" CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
  <PARAM NAME="URL" VALUE="mms://mediaserver/live">
</OBJECT>

<SCRIPT LANGUAGE="javascript" FOR="MPlayer" EVENT="Error()">
<!--
MPlayer.play();
-->
</SCRIPT>

I tried to keep this extremely simple, but whenever you're doing scripting for events for browsers there are always platform and versioning issues.  Essentially we are just using the OBJECT tag to embed the WMP control.  I pointed the URL to a live stream on a WMS server.  I then created a script to listen for the error event on player object.  In this example I don't check to see what the error is, I just tell the player to play.  The assumption I am making is that maybe there was a temporary network error and I am just telling the player to reconnect.

How to maintain an encoder/server connection on a problematic network

I occasionally get contacted by customers that are having problems keeping their Windows Media Encoder 9 Series encoder and Windows Media Services 2008 server connected.  Often it is simply that the network between the two is having some issues, however briefly.  Both the encoder and server have resiliency built in but network conditions can get to a point where the stream stops.  The server's publishing point may either stop or continue to run while it is attempting to reconnect.

 The best thing to do in this situation is to get the encoder and server setup to reconnect to each other whenever there is an error.  Since the encoder supports both push and pull connections, there is a method that works best for each connection type.

Encoder Pull

Typically a broadcast publishing point on WMS simply points to the encoder HTTP URL.  Most of the time this is okay, but again if the network is having problems it may not be enough.  What you can do is setup a server side playlist (WSX) to attempt to reconnect if there is a problem. WMS itself will try to do that on the same TCP session, but this workaround will establish a new session and give the network a few seconds to recover.  Here's the playlist:

<?wsx  version="1.0" encoding="utf-8"?>
<smil repeatCount="indefinite">
    <media src="http://encoder:8080?wmreconnect=0"/>
    <media src="c:\wmpub\wmroot\proseware_leadin.jpg" dur="10"/>
</smil>

There are three things to point out here.  First you will see that the first media item in the playlist is our connection to the encoder.  I've added the wmreconnect=0 query string.  This turns off the WMS reconnection logic.  We're doing this because if there is any sort of problem we want the server to immediately fail and roll to the next item in the playlist.  Second, is the next item in the playlist.  Above I have just pointed it to a JPG file that's one of the samples that comes with WMS.  I've set it to play for 10 seconds, but you could set it to a shorter time.  You could change this piece of content to any number of things.  You could use a "sorry we're having technical difficulties" video or JPG.  You could set it to a JPG file that is completely black.  Or you could point it to a different encoder machine.  That's actually the best option if you have two separate encoders encoding the same content.  This gives you a lot of redundency.  The only thing you can't use is the same encoder URL as the first one.  WMS sees this as the same playlist item and does not reconnect in the same way.  Third we have the SMIL repeatCount set to "indefinite".  This causes the items between the SMIL and /SMIL tags to be repeated for as long as the publishing point is running.

 Encoder Push

With push it is a little different. Instead of the server being responsible for maintaining the connection, now the encoder is responsible for maintaining the connection.  Since Windows Media Encoder does not have playlist functionality we created some hotfixes to help with the reconnection issues.

1a) Install fix from http://support.microsoft.com/kb/929182 if running WME on Windows Vista.
1b) Install fix from http://support.microsoft.com/kb/915483 if running WME on Windows XP.

2) Make the registry changes (but do not install the hotfix from) http://support.microsoft.com/kb/895182.

With these fixes installed the encoder should keep attempting to reconnect to the server until it gets a connection.

Silverlight installation requires the SSE CPU instruction set

One of the guys on my team recently tried installing Silverlight 2.0 on one of his older systems.  He got the error, "Unable to install Silverlight" and, "Your processor is not supported."  When you click on More information you see the error:

Message ID: 1503

Microsoft Silverlight is not supported on your computer.  Your CPU does not support the SSE instruction set which is required by Silverlight.

Intel introduced the SSE extension in 1999.  AMD added SSE support in 2001.  Machines with processors that were manufactured prior to those dates did not have the SSE extension.

Silverlight primarily uses the SSE extension for its floating point support.

Fix for WMS 503 issue released

Since this is a fairly major issue for a number of people that are running Windows Media Services 2008, I thought this warranted it's own post.  I prevously described the issue at http://blogs.msdn.com/randomnumber/archive/2008/09/05/wmp-unable-to-connect-to-wms-9-5-wms-returning-503-service-unavailable.aspx where WMS returns a 503 error when the server is behind a NAT.  A fix is now published at http://support.microsoft.com/kb/960372.  It also contains two other fixes that were not included in WMS 2008 that had been fixed for WMS 9.

 

IIS Smooth Streaming beta released

The next big thing in streaming is now released in beta form.  That is the IIS 7 Smooth Streaming:  http://www.iis.net/extensions/SmoothStreaming

This is the technology that was used last summer with Silverlight for the Olympics to stream the on demaind content.

Troubleshooting the Silverlight MediaElement 4001 Error

This is my first post on Silverlight, so I thought I would post on a common issue that I've seen developers have problems with.  Since I focus mainly on the MediaElement piece of Silverlight I'm going to stick almost solely to that on this blog when I post about Silverlight.

If you've ever developed a Silverlight application that plays video, you've probably at some point seen the following error:

Silverlight error message
ErrorCode: 4001
ErrorType: MediaError
Message: AG_E_NETWORK_ERROR

In fact, it's probably the only error you've ever seen with regards to the MediaElement.  That's because it IS the only error that MediaElement throws.

Here are a few possible causes for this error:

  • Streaming from WMS through an Authenticated Proxy - Silverlight gets video in two different modes.  If the video is coming from a web server, such as IIS, then it is progressively downloading the video from the web site.  This downloading is handled by the browser.  If Silverlight is streaming from a Windows Media server then this streaming is handled internally by Silverlight and not by the browser.  Since browsers support proxy authentication you will not see the 4001 error if you are getting the video content from a web server.  Silverlight does not support proxy authentication natively and therefore doesn't support proxy authentication when streaming from a Windows Media server.

    There are only two workarounds, and they are the obvious ones.  First, don't require proxy authentication on the proxy.  Second, put the content on a web server.  In the enterprise, this may not be an option.
     
  • Codec Not Supported by Silverlight - Because Silverlight streams .wmv and .wma files you may have a video encoded with a codec that Silverlight does not support.  The file extension .wma and .wmv are both forms of the ASF file format that Silverlight supports.  However, because ASF is just a file container you can use just about any codec  to compress the audio and video within that ASF container.  While the Windows Media Audio v9 codec (often abbreviated WMA) and Windows Media Video v9 codec (often abbreviated WMV) are some of the most common codecs you do occasionally find other codecs within .wma and .wmv files.  For example, a number of years ago Windows Media Encoder used the ACELP.net audio codec for voice.  Silverlight does not support this codec, so you get an error.

    The workaround for this is to re-encode  the video into a format that Silverlight supports.  For a list of supported codecs, see the MSDN article:  Supported Media Formats, Protocols, and Log Fields.
  • Incorrect Pathing - This is your common 'file not found' type problem.  If you mistype the path to the video then you're going to get the 4001 error.  You can often find pathing issues by typing the full URL into your browser.  If Windows Media Player opens and cannot find the file then most likely you are using an incorrect URL.  If you are a developer and are building a Silverlight 2 project with Visual Studio and including the video as part of your project, make sure that the video is in the ClientBin folder in the Web project.
  • Crossing Zones - As part of the Silverlight security model, when you run an application in a more secure zone (such as from the local hard drive) you cannot play video from a less secure zone.  An example of this is building a Silverlight application that is run from the local web server that Visual Studio instantiates.  In this scenario you are crossing from the Local Intranet Zone where the Silverlight application is running to the Internet Zone where the video is being streamed from.  This is not allowed for security reasons.

    As a workaround try to keep both the location were the Silverlight application and the video are in the same zone.  Keep in mind that it IS possible to cross domains, just not zones.  You could host your Silverlight application on one domain and serve your video content from another domain.
Getting your CD or DVD listed so it shows automatically in Windows Media Player
When you are ripping CDs with Windows Media Player, the player can automatically go out to the Internet to  retrieve the metadata describing the CD such as the album name, artist, track information, etc.  If you are an artist that would like to have your CD or DVD information added to the database, you need to contact All Music Guide (AMG).  Microsoft has no direct control over this listing since we license the database from AMG.  The page http://allmusic.com/cg/amg.dll?p=amg&sql=32:amg/info_pages/a_product_submissions.html describes what you need to do.  Once AMG's database is updated, the data will be propagated to Microsoft and other licensees of AMG’s database.  This usually takes a few weeks.
Windows Media Player now works with Kerberos

You may have seen in a network trace that when Windows Media Player connects to Windows Media Services that if the server had Negotiate authentication enabled for the publishing point that Kerberos would fail with a Service Principal Name unknown error.  Specifically in the trace you'd see a response that contained KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN.  WMP would fail silently and roll over to NTLM.  NTLM would then handle the authentication.

As of December 9, 2008, Windows Media Player 11 now works with Kerberos authentication.  A security update, http://www.microsoft.com/technet/security/bulletin/ms08-076.mspx, changed the way that the player handles Kerberos.  I've only tested this with WMP 11, but it's possible that the update affected older versions of the player as well allowing them to work.

WMP unable to connect to WMS 2008; WMS returning 503 Service Unavailable

I've talked to a number of people that are having problems streaming from Windows Media Services 2008 on Windows Server 2008 when the server is behind a NAT firewall, some proxies, or load balancers.  Clients on the internal network work just fine.  In a network trace you'll see at WMS is returning a 503 Service Unavailable as the first response to the RTSP DESCRIBE or HTTP GET. 

WMS is doing a DNS query for the domain name in the RTSP or HTTP request when the request is not the local NetBIOS, local DNS, or local IP.  If a WMP client is requesting content through a NAT or similar device (such as some proxies and load balancers that hides or translate an external URL to an internal URL), the requested address might be something like mms://streaming.contoso.com/live.  However internally the server name might be WMS01 or WMS01.corp.contoso.com.  This generally is only going to happen if you're using Network Address Translation.

WMS 9.5 now contains a cache/proxy in the box.  What's happening is when WMS doesn't recognize the requested URL as itself it is assuming that the request may be a proxy request.  This happens even if the cache/proxy plug-in is disabled.  Because internal clients would use the internal IP, NetBIOS, or DNS name, the server recognizes those request as intended for the local server itself.

You can work around this problem by adding any possible DNS name that could be requested by a client to the WMS server's c:\windows\system32\drivers\etc\HOSTS file and point it to localhost.  It would be something like:

127.0.0.1    streaming.contoso.com

We're investigating a way to fix this issue more permanently.

Cheap load balancing using an ASX as created by an ASP

This load balancing solution will cost you a grand total of about 10 minutes of time.  Now I will say that it's definitely not the best load balancing solution out there, but it's cheap and works amazingly well for something so simple.

First I need to explain a feature of ASX files that makes this somewhat bullet proof.  ASX files have the very awesomely cool feature of allowing you to specify a rollover URL within an entry tag.  This allows you to specify a primary and backup (or many different backups) URL.  You do this by specifying multiple ref tags within a single entry tag.  This tells the player that if the first one fails, roll to the next ref URL.

<asx version ="3.0">
 <entry>
  <ref href="mms://server1/video.wmv" mce_href="mms://server1/video.wmv"/>
  <ref href="mms://server2/video.wmv" mce_href="mms://server2/video.wmv"/>
 </entry>
</asx>

So if for whatever reason our connection to server1 fails we'll rollover to the URL pointing to server2.  This works great if all you need is a backup server in case the first one goes down but it doesn't make any attempt to balance the load.

I love random numbers.  Note the blog name.  Here's an instance where they really work to our advantage.  In the code below I use the randomize function to generate a random number between 0 and 1.  I use this as the deciding factor on how to order my ASX file.  Depending on what the random number is, if it's below .5 then you will start with server2 and fail over to server1.  If it's above .5 then you start with server1 and fail over to server2:

<% Response.ContentType="video/x-ms-asf" %><ASX version="3.0">
 <entry>
<% randomize
   if rnd > .5 then
%>  <Ref href="mms://server1/live"/>
  <Ref href="mms://server2/live"/><% else %>  <Ref href="mms://server2/live"/>
  <Ref href="mms://server1/live"/><% end if %>
 </entry>
</asx>

You could easily expand this example to include 3 or more servers.  You'd need to use some else if statements and divide the number of servers into 1 to give you the numbers to check for.  For example, if you have 3 servers you'll need to check to see if the random number is below .33 or above .66 (with the else being between the two).

You could also do something more complicated by maintaing state on the web server to keep track of what the last response to the client was so that you're always going from server1 to server2 to server1, etc.  But I've found that to be fairly unnecessary if you're dealing with more than just a handfull of clients.  It is possible, but not likely, that one server could just happen to have a lower load because everyone that's connected to it is watching very short clips.  Again, I did say this wasn't the best solution out there, but it's definitely cheap.  Oh, and it's better than just doing DNS round-robin because with DNS you don't necessarily know if a particular server is down and don't get failover.

Using Wallclock Scheduling in WMS to start a broadcast at a specific time

Over the years I've talked to a number of people that want to broadcast a live video at a certain time of day.  Usually this is in a corporate network where a CEO is doing a large broadcast to the entire company or something similar that needs to happen at a specific time without the intervention of a WMS admin.  One of the features that comes with WMS starting in Windows 2003 SP1 is wallclock scheduling.  This gives you the ability within a server side playlist to trigger an event to take place at a specific time.

 I'll detail two examples of how you can schedule a broadcast.  The first one below loops through the three videos indefinitely in the second priority class called "od" until the higher priority "live" priority class fires off at 5:41 PM.  This may seem a little out of order, but the way this works is that because "live" is listed above "od" the first priority class would normally play first.  However, with the wallclock tag set to begin at a specific time "live" will not start until that time.  So the server plays the lower priority "od" until "live" hits it's wallclock scheduled time.

<?wsx version="1.0" encoding="utf-8"?>
<smil>
    <excl>
        <priorityClass id="live" lower="pause">
            <media src=http://encodermachine:8080 begin="wallclock(17:41:00)"/>
        </priorityClass>
        <priorityClass id="od">
            <seq repeatCount="indefinite" begin="0s">
                <media src="C:\wmpub\WMRoot\snowboard_300.wmv"/>
                <media src="C:\wmpub\WMRoot\powered_by_300.wmv"/>
                <media src="C:\wmpub\WMRoot\racecar_100.wmv"/>
            </seq>
        </priorityClass>
    </excl>
</smil>

 There are times when you don't actually want to stream data the entire time you're waiting for the broadcast.  You could throw up a banner video that says, "This video will not play until 5:41 PM" and put some groovy music behind it but the network admin is likely going to wonder why you've been chewing up bandwidth hours before the broadcast.  So instead you may just want to start the broadcast at 5:41.  You'd think you could delete the "od" priority class and just use the one "live" one to start whenever it's scheduled for.  However, there's a requirement in WMS that when a publishing point starts it actually has to play something.  Not indefinitely, but it does need to successfully see bits going through the pipeline.  So what you do instead is something like this:

<?wsx version="1.0" encoding="utf-8"?>
<smil>
    <excl>
        <priorityClass id="live" lower="pause">
            <media src=http://encodermachine:8080 begin="wallclock(17:41:00)"/>
        </priorityClass>
        <priorityClass id="od">
            <seq begin="0s">
                <media src="C:\wmpub\WMRoot\pinball.wmv"/>
            </seq>
        </priorityClass>
    </excl>
</smil>

Note that all that really happened was that I removed the repeatCount.  I changed the "od" priority class to be just the one short pinball.wmv, but that's only because it's the shortest of the sample clips.  So what happens is that when the publishing point starts pinball.wmv would play to the end.  If you have a client connect as soon as the publishing point starts they will see pinball play and then a black screen.  The client may timeout after a couple of minutes because no data is actually being sent.  The publishing point won't start sending data until lthe wallclock scheduled time.  At that point clients can connect and view the live stream.

More Posts Next page »
Page view tracker