Skip to content

DPL playlist format

AF-1 edited this page Oct 14, 2023 · 18 revisions

If you need even more options and creative freedom than Dynamic Playlist Creator already provides, the following explanations should help you:

Dynamic playlists are basically plain text files with a "sql" file extension that contain your playlist definition. The following guide applies to built-in and custom dynamic playlists (user-provided and used directly in DPL).

  • The first part of your playlist definition file contains parameters: general parameters like the playlist name, group or category and user input parameters that present users with some options to choose from before starting the playlist.
  • The second part of your playlist definition file contains the actual SQLite statement LMS uses to fetch the tracks.
  • Remember to save your playlist definition file with a ".sql" file extension and to put them in the DPL's folder for custom dynamic playlists called DPL-custom-lists. Unless you've changed its location in DPL's settings, you'll find this folder in your LMS playlist folder.

Here's a simple dynamic playlist example:
-- PlaylistName:Songs - random
-- PlaylistGroups:Christmas/Songs
-- PlaylistCategory:songs
-- PlaylistVirtualLibraryID1:PLUGIN_VLC_FAMILY_LIBRARY
-- PlaylistParameter1:list:Limit to PLAYED songs:0:all songs,1:unplayed songs,2:played songs

select tracks.id, tracks.primary_artist from tracks
    join library_track on
        library_track.track = tracks.id and library_track.library = 'PlaylistVirtualLibraryID1'
    join comments on
        comments.track = tracks.id and comments.value like '%%Christmas%%'
    join tracks_persistent on
        tracks_persistent.urlmd5 = tracks.urlmd5
left join dynamicplaylist_history on
        dynamicplaylist_history.id = tracks.id and dynamicplaylist_history.client = 'PlaylistPlayer'
    where
        tracks.audio = 1
        and tracks.secs >= 'PlaylistTrackMinDuration'
        and dynamicplaylist_history.id is null
        and
            case
                when 'PlaylistParameter1' = 1 then ifnull(tracks_persistent.playCount, 0) = 0
                when 'PlaylistParameter1' = 2 then tracks_persistent.playCount > 0
                else 1
            end
    group by tracks.id
    order by random()
    limit 'PlaylistLimit';

Playlist Parameters

Parameters always start with -- Playlist.

General Parameters

You should definitely set the -- PlaylistName.

With -- PlaylistGroups you can sort your dynamic playlist into any group in the DPL home menu. You don't have to use one of the built-in groups. You can name it anything you want. And groups can have subgroups. The dynamic playlist example creates a group called "Christmas" with a subgroup called "Songs". Groups and subgroups are separated by a slash /
PlaylistGroups is an optional parameter.

-- PlaylistCategory is used to sort playlist by playlist type on the DPL settings page. It's always lower case and it can have any of these values:
songs, artists, albums, genres, years, playlists.
PlaylistCategory is an optional parameter.

If you want to create a context menu dynamic playlist (context menu for artist, album, genre, years or playlist) you have to add this line:
-- PlaylistMenuListType:contextmenu
Otherwise it will show up as a normal (stand-alone) dynamic playlist.

-- PlaylistUseCache: 1 should ⚠️ only be used for dynamic playlists that you know can retrieve all tracks matching your search parameters in one initial database query.
DPL will load all tracks into the cache, thus eliminating the need for further database queries. Subsequent batches of new tracks for the active dynamic playlist will be retrieved from the cache only, and added to a client's playlist much faster as a result. Dynamic playlists that retrieve each batch of new tracks from a different, randomly chosen artist, album, genre, year, decade or static playlist are not suitable for cache use because not all tracks can be retrieved in one initial database query.
⚠️ If you use the PlaylistUseCache option, don't order tracks in SQLite and don't limit the result set, i.e. don't use order by random() or limit.

The -- PlaylistLimitOption:unlimited parameter tells DPL to add an 'unlimited' number of tracks to the playlist. To prevent faulty playlist definitions from adding complete libraries unlimited actually means max. 2000 tracks.

The sqlite statements of many (built-in) dynamic playlists use random sorting. Regardless, DPL additionally tries to increase randomness by shuffling tracks before adding them. If you want to use custom dynamic playlists and disable extra shuffling just add the -- PlaylistTrackOrder:ordered parameter.
Example: Custom dynamic playlists adding complete albums should use the -- PlaylistLimitOption:unlimited and the -- PlaylistTrackOrder:ordered parameter.

Virtual libraries:
You can always ask the user to choose a virtual library (see user input parameters below).
But if you want a one-click custom dynamic playlist without user interaction and you know which virtual library to use already, here's how to do it:

LMS virtual libraries have a name (displayed in menus), a unique (configurable) id and a 'realID' which is what LMS uses internally. Since realIDs can change with rescans, it's safer to use the unique ID of the virtual library because, unlike names, it has to be unique.
If you're using the Virtual Library Creator plugin and you have enabled the display of virtual library IDs in the plugin's preferences, the ID is displayed on the Edit page of each virtual library.

In your dynamic playlist use the -- PlaylistVirtualLibraryID (recommended) or the -- PlaylistVirtualLibraryName followed by a number.

Using the dynamic playlist example from above that would be -- PlaylistVirtualLibraryID1:PLUGIN_VLC_FAMILY_LIBRARY
or maybe -- PlaylistVirtualLibraryName1:Family Christmas Songs.

Then you can use PlaylistVirtualLibraryID1 or PlaylistVirtualLibraryName1 in your sqlite statement and DPL will replace these values with the virtual library's realID. The ID/numbering starts with 1 and increases by 1 with each additional PlaylistVirtualLibrary parameter.

Action/CLI parameters:
The PlaylistStartAction and PlaylistStopAction parameters allow you to execute a CLI command when a dynamic playlist is started or stopped:

-- PlaylistStartAction[id]:cli:[cli command]
-- PlaylistStopAction[id]:cli:[cli command]

Example: When you add a Customkip filter in a Dynamic Playlist Creator template, DPLC uses these 2 parameters to enable or disable a secondary CustomSkip filter set to filter tracks at playtime.

-- PlaylistStartAction1:cli:customskip setsecondaryfilter TEST.cs.xml
-- PlaylistStopAction1:cli:customskip clearsecondaryfilter

Important:

  • Use the complete file name (incl. file extension).
  • The file name is case-sensitive. Using the example above: CustomSkip would consider TEST.cs.xml and test.cs.xml two different filter sets.
  • The PlaylistStopAction parameter will disable the secondary CustomSkip filter set as soon as Dynamic Playlists stops (adding new songs). So if DPL can't find more tracks matching your search criteria, it stops being 'active' and disables the secondary filter on exiting. The remaining unplayed songs in your client playlist will no longer be filtered by the secondary CustomSkip filter set because DPL disabled it on exiting. If that happens a lot to you I recommend setting the max. number of unplayed tracks DPL adds to a low number so DPL doesn't stop and disable the secondary CS filter too soon.

The ID starts with 1 and increases by 1 with each additional PlaylistAction parameter.
For more information on CustomSkip filters please visit the CustomSkip wiki.

User Input Parameters

And then there are parameters requesting input from the user that is used in the SQLite statement.
Their ID starts with 1 and increases by 1 with each additional PlaylistParameter: -- PlaylistParameter1, -- PlaylistParameter2 and so on.
In other words: the -- PlaylistParameter1 part asks the user for input which can then process in your SQLite statement using placeholders like 'PlaylistParameter1' (wrapped in single quotes).

You can choose from predefined parameters or create a custom parameter:

  • Predefined parameters are available for artist, album, genre, multiplegenres, year, multipleyears, multipledecades, playlist, multiplestaticplaylists and virtuallibrary.
    They will present the user with a list of artists, albums, genres, years, decades, static playlists or virtual libraries to choose from. They follow the same pattern as this example for artists: -- PlaylistParameter1:artist:Select artist: or multiple genres: -- PlaylistParameter1:multiplegenres:Select genres:
  • list parameter: the dynamic playlist example above shows another kind of parameter, the list parameter, that lets users choose from custom list items with custom values:
    -- PlaylistParameter1:list:Limit to PLAYED songs:0:all songs,1:unplayed songs,2:played songs
  • And finally you can create your own custom parameter, sort of a list parameter using SQLite query results. Requesting users to choose a (single) decade is one example:
    -- PlaylistParameter1:customdecade:Select decade:select cast(((tracks.year/10)*10) as int),case when tracks.year>0 then cast(((tracks.year/10)*10) as int)||'s' else 'Unknown' end from tracks where tracks.audio=1 group by cast(((tracks.year/10)*10) as int) order by tracks.year desc.
    Custom parameters must always be prefixed with custom (customdecade in this example).
  • The PlaylistPreselectedArtists and PlaylistPreselectedAlbums are special cases. They don't request user input when you start your dynamic playlist. Instead you add artists/albums to a list (preselecting them from the context menu) while browsing your music library. When you start a dynamic playlist with these playlist parameters DPL will provide the necessary artist/album IDs. All you have to do is add one or two lines to your SQLite statement and DPL will take care of the rest. Here are examples for
    preselected artists:
    join contributor_track on contributor_track.track=tracks.id and contributor_track.role in (1,4,5,6) and contributor_track.contributor in ('PlaylistPreselectedArtists')
    and preselected albums:
    tracks.album in ('PlaylistPreselectedAlbums')


SQLite statement

This is what LMS uses to fetch the tracks. DPL expects track ids (and a track's primary artist for balanced shuffling):

select tracks.id, tracks.primary_artist from tracks

You can use 2 kinds of playlist parameter placeholders in your SQLite statement that DPL will replace with actual values:

  • the user input playlist parameters mentioned above and
  • a set of playlist parameters that DPL will fill in automatically.

DPL will automatically replace these (non-configurable) parameters with current values:

  • 'PlaylistPlayer' => client MAC address
  • 'PlaylistCurrentVirtualLibraryForClient' => if there's a virtual library enabled for the client other than the complete library
  • 'PlaylistVariousArtistsString' => your (localized) string for Various Artists if you want to filter for that
  • 'PlaylistVariousArtistsID' => contributor.id for Various Artists if you want to filter for that

You can change the value of these parameters on the DPL settings page:

  • 'PlaylistLimit' => limit the max. number of tracks added to your playlist. No limit if you add the -- PlaylistLimitOption:unlimited.
  • 'PlaylistTrackMinDuration' => minimum track length
  • 'PlaylistTopRatedMinRating' => minimum rating for tracks to be considered top rated
  • 'PlaylistPeriodPlayedLongAgo' => time period for tracks to be considered played long ago
  • 'PlaylistExcludedGenres' => list of genres to exclude from results
  • 'PlaylistMinArtistTracks' => ignore artists with less tracks
  • 'PlaylistMinAlbumTracks' => ignore albums with less tracks

All parameters have to be wrapped in single quotes as shown above.

I recommend taking a look at the dynamic playlists that come with the plugin. It's a good starting point for your own dynamic playlists and might save you some time.

Clone this wiki locally