Web Playlists for IIS 7 - Using Playlist With Different Media Players

By Vishal Sood

February 27, 2008

This article describes how various clients can interact with Web Playlists to display the playlist content. Web Playlists works with the clients mentioned in this article; however, any client that supports ASX natively or through extensions can use this feature.

This article contains:

Prerequisites

To install the Web Playlists extension for IIS 7 and above, see the Installation Notes section in the IIS Media Services Readme.

Windows Media Player

Follow the steps below to consume an ISX (Web Playlist) file in Windows Media Player 11 (WMP)

1. Open Windows Media Player 11.

2. Click File. Select Open URL.

3. Type in the URL to the .isx file and click OK.

Silverlight

Silverlight has an out-of-the-box Media Element that can play ASX files. This fits very well with the Web Playlists handler, as it sends out an ASX response when an .isx URL is requested. Thus, for us to be able to play back Web Playlists in Silverlight, we must use the Media Element.

Media Element

MediaElement is the object in the Silverlight rendering engine that knows how to play back audio and video content.

Adding media to a page is as simple as adding a MediaElement to your markup and providing a Uniform Resource Identifier (URI) to the media to play. The following example creates a MediaElement and sets its Source property to the URI of a video file. The MediaElement begins playing when the page loads.

<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
<MediaElement x:Name="media" Source="http://myserver/mymedia/media.isx" Width="300" Height="300" />
</Canvas>

The MediaElement object can play Windows Media Video (WMV), Windows Media Audio (WMA), and MP3 files. For a detailed list of the formats and protocols supported, see Supported Media Formats and Protocols.

Using PARAM Tags in Silverlight

To the play the playlist in a Silverlight MediaElement, simply point the Source of the MediaElement to the ISX file location. This plays the playlist entries in the order specified. In case you want to control the appearance of next / previous buttons, or control the seek bar on the client site, you must access the PARAM tags associated with the MediaElement. By default, Silverlight just ignores these PARAM tags. The PARAM tags of interest in our case are CANSKIPFORWARD, CANSKIPBACK and CANSEEK along with the attribute CLIENTSKIP for the entry. CLIENTSKIP is handled by Silverlight by disabling seek on the media element.

Any of these PARAM tags can easily be accessed from a Silverlight app by using Attributes. Here is a simple piece of code that tells how to read an attribute:

function onMediaOpened(sender, args)
{
// Variable to hold the MediaAttribute.
var attribute;
// Get the MediaAttribute named Title
try {
var attributesCollection = sender.Attributes;
attribute = attributesCollection.getItemByName("Title");
}
catch(errorObj)
{
alert(errorObj.message);
}
// Display the Value of the MediaAttribute
if(attribute != null)
{
alert("The title of the track is: " + attribute.value);
}
}

After you have read the attributes CANSKIPFORWARD, CANSKIPBACKWARD and CANSEEK, you can easily control the UI experience by appropriately enabling / disabling the controls.By default, Silverlight does not have implemented the concept of skipping to the next entry in the playlist. One way to overcome this limitation is to seek to the end of the current entry and let the next entry play automatically.

Silverlight Reference

Flash Player

The Web Playlist .isx file, when accessed on the client side, generates an ASX file. To play a Web Playlist file in Flash, we need to add the capability for Flash to parse ASX files. ASX files are simply XML files. The way to add this capability to Flash player is to write an Action Script (.AS) which can load the ASX response from the web request and then parse the response to get the relevant entries and PARAM tags. Then, tie them back to the controls in the UI element where the media will play.

Below are a few classes that help in parsing the ASX response sent by the Web Playlists module when a get request is made for an .ISX Playlist file. This is just a sample and suggests one way of doing the same.

import mx.utils.Delegate;
import mx.events.EventDispatcher;
import sampleplayer.communication.PlaylistEntry; class sampleplayer.communication.Playlist { public var addEventListener:Function, removeEventListener:Function; private var dispatchEvent:Function; private var _xml:XML;
private var _title:String;
public var _entries:Array; function Playlist() {
trace("Playlist instantiated");
_xml = new XML();
mx.events.EventDispatcher.initialize(this);
} public function load(sServerPath:String):Void {
_entries = new Array();
_xml.onLoad = Delegate.create(this, onLoad);
_xml.load(sServerPath);
}

public function clear()
{
_entries.length = 0;
} private function onLoad(success:Boolean):Void {
if (success) {
var index:Number = 0;
//trace(_xml.childNodes);
for (var node:XMLNode = _xml.firstChild.firstChild; node != null; node=node.nextSibling) {
switch (node.nodeName) {
case "ENTRY" :
var entry:PlaylistEntry = new PlaylistEntry(node);
_entries[index++]= entry ;
break;
case "TITLE" :
//process the playlist title - sample code
_title = node.nodeValue;
break;
}
}
trace("Entry count:"+ _entries.length);
trace(_entries);
}
dispatchEvent({type:"onPlaylistLoaded", target:this, status:success});
} } class sampleplayer.communication.PlaylistEntry { public var title:String;
public var path:String;
public var canSeek:Boolean;
public var canSkipForward:Boolean;
public var canSkipBackward:Boolean;
function PlaylistEntry(node:XMLNode) {
trace("Entry instantiated");
canSeek = true;
canSkipForward = true;
canSkipBackward = true;
load(node);
}
private function load(node:XMLNode) {
for (var temp:XMLNode = node.firstChild; temp != null; temp=temp.nextSibling) {
switch (temp.nodeName) {
case "REF" :
path = temp.attributes.HREF;
break;
case "PARAM" :
var name = temp.attributes.NAME;
var value = temp.attributes.VALUE;
switch (name) {
case "CANSKIPBACK" :
canSkipBackward = (value == "NO");
break;
case "CANSKIPFORWARD" :
canSkipForward = (value == "NO");
break;
case "CANSEEK" :
canSeek = (value == "NO");
}
break;
}
}

if(node.attributes.CLIENTSKIP == "NO")
{
canSeek = false;
canSkipForward = false;
canSkipBackward = false;
}
}

public function toString():String
{
return "Entry ref=" + path + " canSeek=" + canSeek + " canSkipF="+ canSkipForward + " canSkipB=" + canSkipBackward;
}
}

The Playlist class above helps parse an ASX file to get the playlist entries and the PlaylistEntry class helps parse each entry to get appropriate PARAM tags to be used to set the player controls in the UI accordingly. The code above makes use of XML parsing abilities provided by the Flash SDK. The Playlist class parses the ASX to store all entries in an array and then PlaylistEntry goes through the array to parse the appropriate data for each entry.

The classes above should be used together with NetConnection, NetStream and Video classes provided by Flash. Below is a sample piece of code that shows how these could be used. The actual implementation is left to the reader.

nc = new NetConnection(); //create a connection
nc.connect( null ); //null connection for progressive download
ns = new NetStream(nc);//create a stream
video.attachVideo(ns); //pipe stream to this video object
ns.setBufferTime("10"); // Sets the initial buffer
ns.play("a.flv");



Discuss in IIS Forums