The short answer
M3U is more widely accepted and easier to write by hand. XSPF is defined down to the element name, so an XML parser can tell you precisely what is broken instead of a player silently skipping a line. If a player offers both, M3U is the safer default for a simple list; XSPF is the better choice when the playlist travels between applications and must carry defined playlist-level fields.
What each one is
XSPF stands for XML Shareable Playlist Format, and it is pronounced "spiff". It was produced by the Playlist Ad-Hoc Group and sponsored by the Xiph.Org Foundation, with version 1 published in January 2005. The specification states plainly why it exists: almost every player accepts M3U, but also invents an XML playlist format of its own, and XSPF is meant to be the shared one.
M3U has no equivalent document. It grew by adoption, and the extended version added
#EXTINF without anyone publishing a standard for it. That is not a defect
for a list of file paths, but it means a wrong M3U file fails quietly, while a wrong
XSPF file fails with an error that names the problem.
Structural difference
| M3U | XSPF | |
|---|---|---|
| Foundation | Plain text, one address per line | XML document |
| Specification | None published | XSPF Version 1, January 2005 |
| Media type | None for the playlist itself | application/xspf+xml |
| Root element | Not applicable | playlist, with version="1" |
| Namespace | Not applicable | http://xspf.org/ns/0/ |
| Entry container | The next line after #EXTINF |
trackList, then track |
| Address field | The line itself | location, expressed as a URI |
| Title and duration | In #EXTINF |
Their own elements, alongside creator and album |
| Escaping | None | XML rules, so & must be escaped |
One detail in that table is worth reading twice: the namespace is
ns/0 while the version is 1. That is deliberate. Version 1
playlists are backwards compatible with version 0 parsers, so the namespace was left
alone.
The same two tracks in both formats
As M3U:
#EXTM3U
#EXTINF:180,Opening song
Music/Opening.mp3
#EXTINF:240,Second song
Music/Second.mp3
As XSPF:
<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<title>Two songs</title>
<trackList>
<track>
<location>file:///music/opening.mp3</location>
<title>Opening song</title>
<duration>180000</duration>
</track>
<track>
<location>file:///music/second.mp3</location>
<title>Second song</title>
<duration>240000</duration>
</track>
</trackList>
</playlist>
Two differences stand out. XSPF durations are in milliseconds, so a three-minute track
is 180000, not 180. And locations are URIs, which means a
local file needs the file:/// prefix rather than a plain path. Passing the
same address through a browser is a quick way to test whether a location is written
correctly.
What XSPF is for, and what it is not
The specification is unusually blunt about this, and it corrects a common assumption.
XSPF is not a catalogue of media metadata. The authors state that the function of a
playlist is to identify objects and communicate their order, not to carry details about
the composer or the song, and that a playlist format should not try to compete with the
databases that already do that. Rich metadata is meant to arrive through the
link and meta elements rather than through the core format.
So the structure XSPF adds is not a richer tag set. It is a defined shape: a
playlist element that may carry a title, creator, annotation, date and
licence, and exactly one trackList, whose track elements each
list one or more candidate location URIs. The spec even calls those
locations fuzzy names, because a track can be identified by a URI, a hash or a set of
descriptive fields, and the player is trusted to resolve them.
That is also why every playlist element in the format is described as optional except the track list itself. Editable fields are conveniences; the requirement is that the document is well-formed and points at something renderable.
What a player must do with a broken track
One rule in the specification is worth knowing when debugging. If a track cannot be rendered, a player must skip it and must not stop the sequence. So an XSPF file whose fourth track is broken should still play the other three, and a player that stops entirely is not following the spec.
The duration field carries a similar warning. It is in milliseconds, but
the spec calls it a hint and says a player must not use it to decide how long to render
a track, because generators produce slightly different values. Treat it as a label, not
as a control.
Symptom and cause
| What you see | Likely cause |
|---|---|
| Parser error naming a line | Unescaped & or a tag closed in the wrong order |
| File parses but the player ignores every track | location holds a plain path instead of a URI |
| Player rejects the document outright | xmlns missing from the playlist element |
| Track list is empty | Entries placed outside trackList, or misspelled with a lower-case l |
| Durations look absurdly long | Seconds written where milliseconds are expected |
| Title has odd characters | Entities not escaped, or the file saved in a non-UTF-8 encoding |
Where the syntax bites
-
An unescaped ampersand. A stream address containing
&is valid in M3U and breaks XSPF unless it is written as&. This is the most common failure when converting. -
trackListwith a capital L. XML element names are case-sensitive, andtracklistis not the same element. -
A missing namespace. A
playlistelement withoutxmlnsis well-formed XML but not a usable XSPF document. -
Plain paths instead of URIs.
Music/Opening.mp3is a valid M3U line and an invalid XSPF location. - Quiet failure the other way. An M3U file with a stray blank line or a missing header may open, with an entry silently missing, and give no clue why.
Which should you use
For a queue of local files that you will open in a desktop player, M3U is shorter and universally readable. Choose XSPF when the playlist must carry a title, a creator and per-track metadata, or when it is produced by an application that already writes XML and you want the output to be checkable against a published document. If you are generating playlists programmatically, XSPF is the friendlier target: an XML library handles the escaping, and a schema tells you when the output is wrong.
Writing one by hand
Start with the XML declaration, then a playlist element carrying
version="1" and xmlns set to the XSPF namespace. Add an
optional title and creator inside it, then one
trackList. Every track goes inside that list as a track
element, and every track needs at least one location holding a URI.
Keep the element order roughly as the specification lists it. XSPF defines a sequence for the children of each element, and while a lenient parser may accept any order, a strict one is entitled to reject a document that ignores it. Close every tag, and escape any ampersand in a URL.
If you are generating the file from code, let an XML library build the tree and serialise it. Hand-concatenating strings is how unescaped ampersands and stray angle brackets get into a playlist, and those are the failures that are hardest to see when you read the result in a browser, because the browser repairs them for display.
Converting between them
From M3U to XSPF: add the XML declaration and the playlist element with its
namespace, wrap entries in trackList and track, move each
address into location as a URI, move the title out of the
#EXTINF line, and multiply the duration by 1,000. From XSPF to M3U: write
#EXTM3U, then for each track write an #EXTINF line with the
duration divided by 1,000 and the title, followed by the location.
Convert in a text editor or a script, and keep the original. Character entities are the part most likely to be damaged, because they exist in only one of the two formats.
Checking the result
The M3U file inspector reads
.m3u and .m3u8 files in your browser and lists every line, so
you can confirm an M3U file produced by a conversion. It does not open XSPF files. For
the other comparisons, read M3U vs M3U8 and
M3U vs PLS.
Where this information comes from
The XSPF details, including the namespace, the version, the
trackList spelling, URI locations and the milliseconds convention, come
from the XSPF Version 1 specification and its
quickstart page. Statements about M3U describe common player behaviour, since the
format has no published specification.