Generating Playlists for Windows Media Player from RSS Enclosures

Nightmare on 159th St.

A little pet project I wanted to do for quite some time now involved generating a playlist for Media Player from a video feed such as Channel9 videos.

I thought: how hard can it be? RSS is XML, Media Player uses SMIL 2.0 which is XML so all I need is a little XSLT magic and I’m bingo.

ASX just as Freddy Kruger took away my dreams of SMIL 2.0. There is no rich meta-data playlist apart from this nightmare.

With this documentation you can drive the Heart of Gold way beyond Magrathea just by reading the concepts aloud.

By the way, if you want to see pure evil, have a look at HTMLView.

I had to watch my friend "Channel 9 The Videos" turn me down with all its glorious RSS inconsistencies and limitations. I’m not talking about the interesting sort orders offered or the almost unparseable publication date that prevents me from sorting it myself. I mean I could, if only I had the guts of writing a custom XSLT script function.

It’s the unavoidable feed restriction to either the first or the last 50 items. Not that I’d actively watch 100+ hours of Channel 9. But I’d like to do my own filtering, based on category or product, if such meta-data is provided.

And the enclosure links stink. Something like ppgdmtpubwiz01/dmttestgolden$/ should never, ever appear in a public document. That’s something the Pubwiz API QA should look into, I think. But why do the aspx pages show the correct links? Is Channel 9 fooling me?

By the way, I didn’t even look at MSDN TV or the .NET Show. They don’t have enclosures.

Complete and Utter Failure

But I still had XSLT out on the frontline. Then transforming RSS into ASX I almost lost it.

The documentation is a little unclear about casing, so I went with all elements and attributes in uppercase.

I prepared the transform using Whidbey, which has good XSLT editing and debugging support, and got everything working fine.

Back on .NET 1.1, content entities were double-encoded, so I tried fixing it this, but to no avail.

I became bold and tried adding the remaining meta-data as <PARAM> elements. And I experienced the empty element let-down.

In XSLT, <xsl:element/> will always create empty elements as <element></element>. Fixes with <xsl:text disable-output-escaping="true"/> did not help.

Media Player uses its own intepretation of XML text serialization and does not accept <PARAM></PARAM>. No fix came to the rescue.

So this is where the day has left me. This is as far as I have come.

<?xml version="1.0" encoding="UTF-8" ?>

<

xsl:stylesheet version="1.0" xmlns:ng="http://newsgator.com/schema/extensions&quot; xmlns:dc="http://purl.org/dc/elements/1.1/&quot;

xmlns

:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

<

xsl:strip-space elements="rss channel item" />

<

xsl:output method="xml" version="1.0" indent="no" omit-xml-declaration="yes" />

<

xsl:template match="rss">

<

xsl:element name="ASX">

<

xsl:attribute name="VERSION">3.0</xsl:attribute>

<

xsl:attribute name="BANNERBAR">FIXED</xsl:attribute>

<

xsl:element name="ABSTRACT">

<xsl:value-of disable-output-escaping="yes" select="channel/description" />

</xsl:element>

<

xsl:element name="BANNER">

<

xsl:attribute name="HREF">

<

xsl:value-of disable-output-escaping="yes" select="channel/ng:mceImage/@url" />

</xsl:attribute>

<

xsl:element name="ABSTRACT">

<

xsl:value-of disable-output-escaping="yes" select="channel/description" />

</

xsl:element>

<

xsl:element name="MOREINFO">

<xsl:attribute name="HREF">

<

xsl:value-of disable-output-escaping="yes" select="channel/link" />

</xsl:attribute>

<

xsl:attribute name="TARGET">_blank</xsl:attribute>

</xsl:element>

</

xsl:element>

<

xsl:apply-templates select="channel/item">

<

xsl:sort data-type="number" select="position()" order="descending" />

</xsl:apply-templates>

<

xsl:element name="MOREINFO">

<xsl:attribute name="HREF">

<

xsl:value-of disable-output-escaping="yes" select="channel/link" />

</

xsl:attribute>

<

xsl:attribute name="TARGET">_blank</xsl:attribute>

</

xsl:element>

<

xsl:element name="TITLE">

<xsl:value-of disable-output-escaping="yes" select="channel/title" />

</

xsl:element>

</

xsl:element>

</

xsl:template>

<

xsl:template match="item">

<

xsl:element name="ENTRY">

<

xsl:element name="TITLE">

<

xsl:value-of disable-output-escaping="yes" select="title" />

</xsl:element>

<

xsl:element name="REF">

<xsl:attribute name="HREF">

<

xsl:value-of disable-output-escaping="yes" select="enclosure/@url" />

</

xsl:attribute>

</

xsl:element>

<

xsl:element name="AUTHOR">

<

xsl:value-of disable-output-escaping="yes" select="dc:creator" />

</

xsl:element>

<

xsl:element name="ABSTRACT">

<

xsl:value-of disable-output-escaping="yes" select="description" />

</

xsl:element>

<

xsl:element name="MOREINFO">

<

xsl:attribute name="TARGET">_blank</xsl:attribute>

<

xsl:attribute name="HREF">

<

xsl:value-of disable-output-escaping="yes" select="link" />

</

xsl:attribute>

</

xsl:element>

<

xsl:element name="COPYRIGHT">Published <xsl:value-of disable-output-escaping="yes" select="pubDate"/>.</xsl:element>

<!

<xsl:element name="PARAM">

<xsl:attribute name="NAME">Prebuffer</xsl:attribute>

<xsl:attribute name="VALUE">true</xsl:attribute>

</xsl:element>

<xsl:element name="PARAM">

<xsl:attribute name="NAME">PubDate</xsl:attribute>

<xsl:attribute name="VALUE">

<xsl:value-of disable-output-escaping="yes" select="pubDate"/>

</xsl:attribute>

</xsl:element>

<xsl:element name="PARAM">

<xsl:attribute name="NAME">Category</xsl:attribute>

<xsl:attribute name="VALUE">

<xsl:value-of disable-output-escaping="yes" select="category"/>

</xsl:attribute>

</xsl:element>

>

</

xsl:element>

</

xsl:template>

</

xsl:stylesheet>

Advertisements
This entry was posted in Coding Horror. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s