The Universal Playlist Format
Author: | Stavros Korokithakis |
Version: | 1 |
Date: | 2017-02-28 |
Status: | Pre-alpha |
1. Introduction ¶
The Universal Playlist Format (UPF) is a data format for music (or video, or even other types of) playlists. It aims to be more flexible and complete than existing formats. A Universal Playlist (UPL) will allow better description of the tracks it contains, as well as enable added functionality in players.
Rather than just a simple filename and, perhaps, a title, the UPF contains multiple identifiers (including the filename and title), which serve different use cases. The cryptographic hashes allow library management programs to always know which entry refers to which file, even if you move them or sync your playlist across computers (and even different players), while the MusicBrainz Track ID allows programs to always know, unambiguously and exactly, which song a particular file contains. That means that you will be able to upload a playlist to iTunes or Spotify (if they support the UPL format) and instantly have all your songs on those services, without having to search for them one by one.
2. Motivation ¶
Current playlist formats are greatly lacking in descriptive power. Most formats are a simple ordered list of filenames, which is brittle and inflexible. Here are some of the usecases that playlist formats should be able to address, and which the UPF aims to:
- When files are moved, players should be able to automatically update their playlists, without any additional work from the user. The playlist should contain enough information for the player to unambiguously decide which playlist entry refers to which moved file.
- When user A sends a playlist file (and just the playlist, not any of the music files) to user B, user B's music player should be able to find all the songs from the playlist that user B already owns, so they can be played.
- A user should be able to export a playlist of all their songs from an online music service (for example, their iTunes playlists) and import them on another service (for example, Spotify), in such a way that the latter service can match the songs in the user's playlist with those on their library. This allows the user to have playlist portability without having to search for or match songs one by one.
- If a user has the same song in varying bitrates in their library, the player should be able to automatically group all the various alternatives under the same playlist item, and choose the best quality either automatically or by asking the user.
Current playlist formats don't allow the above use cases, because they don't contain enough information for music players to be able to unambiguously find the song each entry refers to. The UPF tries to change this, and enable all the above uses.
3. Specification ¶
The UPF is JSON-based.
A playlist that adheres to the UPF specification is called a Universal Playlist, or UPL, and a UPL file has the file extension upl
, for example favorites.upl
.
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 RFC 2119.
The term "clients" will herein refer to music players, library managers, tag editors, and any other piece of software that reads or writes UPL files.
A UPL file MUST be valid JSON, and it SHOULD be formatted in a human-readable way. All UPL documents MUST be UTF-8 encoded. All strings herein are assumed to be Unicode strings. The term "mapping" in this document refers to a JSON associative array, and the term "sequence" to a JSON list.
3.1. File format ¶
The top-level item is a JSON sequence, containing one or more mappings. Each of those mappings is a playlist, thus the UPL format can support more than one playlist per file. This is better shown in the example below.
The keys of those mappings are detailed here:
3.1.1. format
¶
string, mandatory
The format and version of the playlist.
Currently, this is always "UPL1"
, as that is the only version that exists.
3.1.2. name
¶
string, recommended
The name of the playlist, for display purposes. No maximum number of characters is currently specified, but clients MAY enforce a maximum when reading or writing files.
3.1.3. id
¶
string, optional
An RFC 4122 UUID, for identifying the playlist.
This SHOULD be randomly generated on playlist creation.
If the client that is reading the playlist needs an id
and one is not provided in the file, the client SHOULD then generate one.
3.2. entries
¶
sequence, mandatory
A sequence of mappings, containing the entries in the playlist. The keys of this mapping are described below.
3.2.1. artist
¶
string, mandatory
The artist of the entry, for display or lookup purposes. As this might be used for lookups, care should be taken to set this field to mirror the official name as closely as possible.
3.2.2. title
¶
string, mandatory
The title of the entry, for display or lookup purposes.
As with artist
, this might be used for lookups, so it should be as close to the official title as possible.
3.2.3. album
¶
string, optional
The album that the track belongs to, for display or lookup purposes. As this might be used for lookups, care should be taken to set this field to mirror the official name as closely as possible.
3.2.4. duration
¶
float, recommended
The duration (total song length) of the entry, in seconds. The minimum float accuracy is one second, (i.e. the value may be an integer), and the maximum accuracy is not currently specified.
3.2.5. start
¶
float, optional
The time position in the song where playback should start from.
This is intended for tracks that are compilations, such as DJ sets or whole CDs, and is comparable to a cue sheet.
If a start
parameter is found in the entry, the player SHOULD start playback from that timestamp in the file.
3.2.6. end
¶
float, optional
The time position in the song where playback should end.
This is intended for tracks that are compilations, such as DJ sets or whole CDs, and is comparable to a cue sheet.
If an end
parameter is found in the entry, the player SHOULD consider that timestamp to be the end of the track, and end playback there.
3.2.7. ids
¶
mapping, recommended
The ids
key contains a mapping of one or more IDs that uniquely identify various aspects of the track.
The client should try to gather and write as many IDs as is practical for each track, and at least the filepath
type is recommended, but this can be omitted if the client cannot come up with any IDs.
The rationale behind this is that the artist
, title
and duration
fields are useful on their own, even in the absence of any other identifier.
Each key in the mapping is the type of identifier, and the value is the value of the identifier. The value MAY either be a string or a sequence of strings, and either is equally valid.
Clients SHOULD support at least the identifiers in the Identifier types section, but a client MAY choose to support additional identifiers. Clients SHOULD ignore unknown identifier types, but MUST NOT strip them from the original file, and SHOULD include them in the new file, if the playlist is written again.
It is up to the client to decide the resolution order of the identifiers. It is RECOMMENDED that the client resolves files in an order that roughly goes from most specific to least specific and, secondarily, fastest to slowest, for example:
filepath
md5
/sha1
/sha2
/sha3
uri
acoustidfp
mbtrackid
/mbrecid
/acoustid
If more than one item is present in an identifier sequence, the items SHOULD be considered weighted in that order, and the player SHOULD try to resolve them in that order. In practice, the first item in the sequence that can be found/accessed/loaded SHOULD win.
The standard names of identifier types are described in the Identifier types section.
3.2.8. Identifier types ¶
The names of the official identifier types are as follows:
md5
: The MD5 function.sha1
: The SHA-1 function.sha1
: The SHA-1 function. Choosing a hash length is up to the client.sha2
: The SHA-2 function. Choosing a hash length is up to the client.sha3
: The SHA-3 function. Choosing a hash length is up to the client.filepath
: A string of the path of the file, for looking up in the filesystem. The path MAY be absolute or relative to the directory in which the UPL file resides.mbtrackid
: The file's MusicBrainz Track ID. This is the MBID corresponding to themb_releasetrackid
tag.mbrecid
: The file's MusicBrainz Recording ID.acoustid
: The file's AcoustID.acoustidfp
: The file's AcoustID/Chromaprint fingerprint.uri
: The URI on which a file may be found. The schema may be anything a client will know how to read, e.g.https://
,ftp://
,ssh://
, or evenfile://
.
3.3. Example ¶
Here's an example of what a UPL file might look like:
[{
"format": "UPL1",
"name": "Favorites",
"id": "2b43009f-d6a6-4f00-8533-09a9a73d8b54",
"entries": [
{
"artist": "Anciients",
"album": "Voice of the Void",
"title": "Following the Voice",
"duration": 408.764081632,
"start": 33.928382,
"end": 401.846235,
"ids": {
"md5": "6d522c2de22e678d590b9a2abae8f6d2",
"sha2": "a9a1c684b6e5d97e3bee3183a048080324dd834371e516a06ce1096b",
"sha3": "e577cce68a69735acccd5d8603b3e663f6aa5bc9",
"mbtrackid": "b00a2b97-53f1-485a-9121-1fe76b55e651",
"filepath": [
"Anciients/Following the Voice.mp3",
"/home/user/music/Anciients/Following the Voice.mp3"
],
"uri": [
"nfs://example.com/music/ftv.mp3",
"http://example.com/music/ftv.mp3"
]
}
},
{
"artist": "Metallica",
"album": "Atlas, Rise!",
"title": "Hardwired… to Self‐Destruct",
"duration": 388.61333333333334,
"ids": {
"md5": "0f4fb7236153879dab1bb76d8ae3376b",
"sha2": "cf26e02999a460ffde08a0c39a895010c5ee0a9083799e3b66c9e06da9e81a34",
"mbrecid": "4329387e-4207-497b-b47e-b59b4522f7c1",
"mbtrackid": "bfa4dc11-0e94-4687-8673-fca0444454c0",
"filepath": [
"Metallica/Atlas, Rise!.mp3",
"/home/user/music/Metallica/Atlas, Rise!.mp3"
]
}
}
]
},
{
"format": "UPL1",
"id": "299d785c-6038-4abf-8000-5f9410486002",
"name": "Metal",
"entries": [
{
"title": "Dream No More",
"album": "Hardwired‧ to Self‐Destruct",
"artist": "Metallica",
"duration": 389.6,
"ids": {
"filepath": "Metallica/Dream No More.mp3",
"mbrecid": "48bc0608-0871-4382-a00e-e009e879fb13",
"mbtrackid": "9becc24c-3236-43fd-ad27-63752b6db80d",
"md5": "bc1d58d8cfc41666d5efeaa3866cb2f4",
"sha2": "15852d39722952157a02c852fcc8301e4a7a37225aaa295d07646853eca958bf"
}
}
]
}]
4. Client behavior ¶
To the extent that this specification can influence the behavior of programs reading/writing UPL files, it will try to specify some best practices for working with the UPL format:
- Clients MUST NOT modify any of the data in the playlist unless the user has specifically performed an action that the latter understands will modify data. Silent changing of identifiers MUST NOT be done, unless it is part of an editing operation such as changing tags or pointing the entry to a different version of a song. Silently changing the identifiers because the client has only managed to find a different version of the song is especially heinous, and MUST be avoided always.
5. Implementations ¶
Software that supports the UPL format includes:
- pls2upl, a utility that converts a PLS playlist to a UPL playlist.
6. Frequently asked questions ¶
6.1. Why JSON? ¶
The first draft of this specification used YAML as its persistence format, but this was changed after further deliberation. JSON is much more widely used than YAML, although it is not as readable. The main argument against YAML was the size of its specification, and the fact that it has so many features that makes compatibility between different libraries very hard.
The UPF strives to be as compatible as possible between different implementations, and the smaller feature set of JSON and the stricter specification leads to simpler, smaller, faster and more compatible libraries.
7. Contact ¶
To report issues or give feedback for this specification, please file an issue or issue a pull request to the project's repository.