We describe an XML playlist format which is open, moderately simple, and carefully engineered.
2.3.1 URI, URLs and URNs
2.3.2 Requirements notation
3.1 Defining playlists
3.2 What a playlist is not
3.4 Content resolver
3.5 Fuzzy names
4 Element definitions
5 Requirements for XSPF generators
6 Requirements for XSPF players
6.1 Graceful failure
6.2 Relative paths
6.3 Extension URIs
§ Author's Addresses
§ Copyright and Patent Statements
There is no XML format for playlists that can measure up to the standards of the formats for web pages (HTML), weblogs (RSS/Atom), and web graphs (RDF/XML). It is evident that there is a need, because XML is the preferred data description language of the moment and as a result the tools and skills to use it are ubiquitous.
It is also evident that existing playlist formats fall short. ASX (for Windows Media Player) and the iTunes library format are proprietary. ASX resembles XML in that it uses angle brackets, but is not XML by any means. M3U, RAM, and M4U are flat files; QuickTime is binary; Pls is in the Windows .ini format; Gnomoradio RDF is RDF, not XML. SMIL addresses a much larger problem space than the average digital music player. The timing model of RSS is incompatible with playlists. Few of these formats are well documented. None of these formats make simple features easy to code and hard features possible. Only one is an open standard. Not one offers playlist interoperability across major vendors.
The question for software developers is why should I support this new XML playlist format? The choice is between M3U and SMIL. Almost every digital music player accepts M3U but also invents an XML playlist format. Inventing a format creates work, for example to study related formats; you should use XSPF to avoid the work. SMIL, on the other hand, is a prescription for a kind of application that is different from a typical music player — it describes layouts in time, while XSPF describes concepts common among music players. Given a song with the comment "danceable!", SMIL might have an instruction to write that text in the upper left in a bold sans-serif font, while XSPF would tell a player that the text is a comment and say nothing about formatting.
A very simple document looks like this:
<?xml version="1.0" encoding="UTF-8"?> <playlist version="1" xmlns="http://xspf.org/ns/0/"> <trackList> <track><location>file:///music/song_1.ogg</location></track> <track><location>file:///music/song_2.flac</location></track> <track><location>file:///music/song_3.mp3</location></track> </trackList> </playlist>
<?xml version="1.0" encoding="UTF-8"?> <playlist version="1" xmlns="http://xspf.org/ns/0/"> <trackList> <track><location>http://example.net/song_1.ogg</location></track> <track><location>http://example.net/song_2.flac</location></track> <track><location>http://example.com/song_3.mp3</location></track> </trackList> </playlist>
Our group started work in February 2004, achieved rough consensus on version 0 in April 2004, did implementations and fine tuning throughout summer and fall 2004, and declared the tuned version to be version 1 in January 2005. Between August and November of 2006 we unfroze this document for a final round of improvements to the drafting, limiting changes to those which did not require any implementation to be modified.
Ian C. Rogers and Robert Kaye bootstrapped our project. Dave Brown, Dan Brickley, and Kevin Marks contributed ideas which had a strong influence on architecture and syntax. Sebastian Pipping and Ivo Emanuel Gonçalves were the drivers behind the 2006 revisions.
We are grateful for comments and feedback from Ryan Shaw, Alf Eaton, Steve Gedikian, Russell Garrett, Ben Tesch and Pau Garcia i Quiles. Special thanks to the developers Tomas Franzén (who participated in our work from the very beginning), Jim Garrison, Brander Lien, and Fabricio Zuardi, and to everyone who contributed their time and skill on the mailing list and wiki.
We would especially like to thank our hosts at the the Xiph.org foundation and Metabrainz foundation for their continuing generosity.
We use the term URI in this document regardless of whether a given URI specifies the location of a resource (a URL) or its name (a URN) independent of location.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
An XSPF playlist describes a sequence of objects to be rendered. Objects might be audio, video, text, playlists, or any other media type. The function of a playlist is to identify the objects and communicate their order.
The function of a playlist is not to communicate metadata about the composer, song title, etc. Metadata is hard and there are many providers already. We decided that we couldn't compete, and that there was no need for us to try. Moreover, good metadata does not travel well — every user has to recreate it. Metadata should come from external sources and namespaces like MusicBrainz or Gracenote; this what the XSPF link and meta elements are for.
The function of a playlist is not to store derived information about objects that a user has a copy of. A playlist is not a catalog. A catalog is computed across hard data like files; it stores information like filesystem paths and the contents of ID3 tags. This data has no value on any machine but the one on which it originated. Sharing this data would be a privacy and security violation. Software which needs access to this data has no reason to maintain it in a standard format, because it has no reason to allow access to it. Standardizing this data would be fruitless, because there are an endless number of measurements that software might take and store. Derived information belongs in a catalog.
Things a playlist is not, then, are a metadata format or a catalog. We took care to enable these features, but also to avoid duplicating their functionality, poorly.
If there is no reason for a playlist to be shared, there is no need for a new format. Even a buggy format does no damage if it is created and consumed by the same software on the same machine. The need for a new format only comes up when a playlist travels from one machine to another, for example when it is published on the internet.
One type of shareability is between different pieces of software on the same machine. It is common for playlists created with one application to not be usable by another application on the same machine, because of different or conflicting interpretations of the playlist format. M3U suffers from this very badly, because M3U playlists often reference files according to a base path which changes from application to application. The XSPF group aimed to fix this by providing unambiguous definitions.
The other type of shareability is between different machines. For playlists to be meaningful on different machines, they must be able to identify network resources. Audio and video objects are often abstractions like "movie X by director Y" rather than computer-friendly objects like "whatever file can be gotten from the URI http://foo/x/y". To handle this problem, we have provided support for media objects to be found via queries; XSPF identifiers are fuzzy names.
On a surface level you can use XSPF like any other playlist format. Drop a bunch of filenames into an XSPF document, prepend "file://" to each, and you're ready to go. Under the surface there is much more.
The guiding design principle was to separate the functionality of a catalog of files from the functionality of a list of songs. Most software music players on the PC have some sort of cache for file information. This cache stores a list, or catalog, of available files and metadata from ID3 tags and other sources. XSPF is not a catalog format. XSPF exists only to say which songs to play. Almost everything in XSPF is for the purpose of answering the question which resource, rather than the question what is this resource.
If XSPF is not a catalog format, what is it? XSPF is an intermediate format. We expected a new kind of software called a content resolver to do the job of converting XSPF to a plain old list of files or URIs. A content resolver would be smart enough to keep your playlists from breaking when you move your media from /oggs to /music/ogg. It would be able to figure out that a playlist entry by the artist "Hank Williams" with the title "Your Cheating Heart" could be satisfied by the file /vorbis/hankwilliams/yourcheatingheart.ogg. It might even know how to query the iTunes music store or another online provider to locate and download a missing song.
The content resolver maintains the catalog of your songs in whatever format it prefers. It might use a flatfile, a file in the Berkeley DB format, or a SQL database. It might use only ID3 metadata, but it might also know how to query MusicBrainz or another metadata service.
All XSPF user agents are content resolvers, in that they have complete leeway to turn the contents of a track element into a specific set of bytes.
Any given track can be identified in a number of ways. We provided means for absolute identifiers like URIs, filesystem paths and secure hashes, but also for query-based identifiers — free text fields like artist and work title and numeric fields for song length, all of which together should be enough for a good content resolver to turn into files.
Notice that the namespace is 0 but the version is 1. This is because version 1 playlists are backwards compatible with version 0 parsers.
Human-readable name of the entity (author, authors, group, company, etc) that authored the playlist. xspf:playlist elements MAY contain exactly one.
A human-readable comment on the playlist. This is character data, not HTML, and it may not contain markup. xspf:playlist elements MAY contain exactly one.
URI of a web page to find out more about this playlist. Likely to be homepage of the author, and would be used to find out more about the author and to find more playlists by the author. xspf:playlist elements MAY contain exactly one.
Canonical ID for this playlist. Likely to be a hash or other location-independent name. MUST be a legal URI. xspf:playlist elements MAY contain exactly one.
URI of an image to display in the absence of a //playlist/trackList/image element. xspf:playlist elements MAY contain exactly one.
Creation date (not last-modified date) of the playlist, formatted as a XML schema dateTime. xspf:playlist elements MAY contain exactly one.
A sample date is "2005-01-08T17:10:47-05:00". PHP to produce such a string from a unix timestamp is:
$main_date = date("Y-m-d\TH:i:s", $timestamp); $tz = date("O", $timestamp); $tz = substr_replace ($tz, ':', 3, 0);
In the absence of a timezone, the element MAY be assumed to use Coordinated Universal Time (UTC, sometimes called "Greenwich Mean Time").
Note: in version 0 of XSPF, this was specifed as an ISO 8601 date. xsd:dateTime is the same thing (with better documentation) for almost every date in history, and there are no playlist creation dates that might be different.
URI of a resource that describes the license under which this playlist was released. xspf:playlist elements may contain zero or one license element.
An ordered list of URIs. The purpose is to satisfy licenses allowing modification but requiring attribution. If you modify such a playlist, move its //playlist/location or //playlist/identifier element to the top of the items in the //playlist/attribution element. xspf:playlist elements MAY contain exactly one xspf:attribution element.
Such a list can grow without limit, so as a practical matter we suggest deleting ancestors more than ten generations back.
<attribution> <location>http://bar.com/modified_version_of_original_playlist.xspf</location> <identifier>somescheme:original_playlist.xspf</identifier> </attribution>
The link element allows XSPF to be extended without the use of XML namespaces. xspf:playlist elements MAY contain zero or more link elements.
The meta element allows metadata fields to be added to XSPF. xspf:playlist elements MAY contain zero or more meta elements.
The extension element allows non-XSPF XML to be included in XSPF documents. The purpose is to allow nested XML, which the meta and link elements do not. xspf:playlist elements MAY contain zero or more extension elements.
<playlist version="1" xmlns="http://xspf.org/ns/0/" xmlns:cl="http://example.com"> <extension application="http://example.com"> <cl:clip start="25000" end="34500"/> </extension> <trackList /> </playlist>
Ordered list of xspf:track elements to be rendered. The sequence is a hint, not a requirement; renderers are advised to play tracks from top to bottom unless there is an indication otherwise.
If an xspf:track element cannot be rendered, a user-agent MUST skip to the next xspf:track element and MUST NOT interrupt the sequence.
xspf:playlist elements MUST contain one and only one trackList element. The trackList element my be empty.
URI of resource to be rendered. Probably an audio resource, but MAY be any type of resource with a well-known duration, such as video, a SMIL document, or an XSPF document. The duration of the resource defined in this element defines the duration of rendering. xspf:track elements MAY contain zero or more location elements, but a user-agent MUST NOT render more than one of the named resources.
Canonical ID for this resource. Likely to be a hash or other location-independent name, such as a MusicBrainz identifier. MUST be a legal URI. xspf:track elements MAY contain zero or more identifier elements.
For example, the URI http://musicbrainz.org/track/7e1d6f5f-0ac3-4889-8b57-506a67b459fc.html is an identifier for a specific song, but dereferencing that identifier will not yield a copy of the song.
Human-readable name of the track that authored the resource which defines the duration of track rendering. This value is primarily for fuzzy lookups, though a user-agent may display it. xspf:track elements MAY contain exactly one.
Human-readable name of the entity (author, authors, group, company, etc) that authored the resource which defines the duration of track rendering. This value is primarily for fuzzy lookups, though a user-agent may display it. xspf:track elements MAY contain exactly one.
A human-readable comment on the track. This is character data, not HTML, and it may not contain markup. xspf:track elements MAY contain exactly one.
URI of a place where this resource can be bought or more info can be found. xspf:track elements MAY contain exactly one.
URI of an image to display for the duration of the track. xspf:track elements MAY contain exactly one.
Human-readable name of the collection from which the resource which defines the duration of track rendering comes. For a song originally published as a part of a CD or LP, this would be the title of the original release. This value is primarily for fuzzy lookups, though a user-agent may display it. xspf:track elements MAY contain exactly one.
Integer with value greater than zero giving the ordinal position of the media on the xspf:album. This value is primarily for fuzzy lookups, though a user-agent may display it. xspf:track elements MAY contain exactly one. It MUST be a valid XML Schema nonNegativeInteger.
The time to render a resource, in milliseconds. It MUST be a valid XML Schema nonNegativeInteger. This value is only a hint — different XSPF generators will generate slightly different values. A user-agent MUST NOT use this value to determine the rendering duration, since the data will likely be low quality. xspf:track elements MAY contain exactly one duration element.
The link element allows XSPF to be extended without the use of XML namespaces. xspf:track elements MAY contain zero or more link elements.
The meta element allows metadata fields to be added to xspf:track elements. xspf:track elements MAY contain zero or more meta elements.
The extension element allows non-XSPF XML to be included in XSPF documents. The purpose is to allow nested XML, which the meta and link elements do not. xspf:track elements MAY contain zero or more extension elements.
<playlist version="1" xmlns="http://xspf.org/ns/0/" xmlns:cl="http://example.com"> <trackList> <track> <extension application="http://example.com"> <cl:clip start="25000" end="34500"/> </extension> </track> </trackList> </playlist>
To ensure interoperability, conforming applications MUST generate playlists that follow the definitions listed in section 4 (element descriptions).
If a media player is unable to render a track in the sequence, the player MUST NOT stop rendering the sequence and MUST attempt to continue at the next track. Players will frequently encounter resources that they cannot render — this is not a fatal error unless the player stops processing the playlist.
The rules for determining the base URI can be be summarized as follows (highest priority to lowest): The base URI is embedded in the document's content. The base URI is that of the encapsulating entity (message, document, or none). The base URI is the URI used to retrieve the entity. The base URI is defined by the context of the application.