<?sphp $this->text('pagetitle') ?>
 
Home of the Squeezebox™ & Transporter® network music players.

Dynamic Playlist plugin

From SqueezeboxWiki

Revision as of 05:46, 20 July 2017 by Erland (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Overview

The Dynamic Playlist plugin is a SqueezeCenter(formerly known as SlimServer) plugin that doesn't actually do much by it self. If you just install the Dynamic Playlist plugin by itself it won't do anything besides showing the saved static playlists you have previously created in SqueezeCenter. Basically the same as standard SqueezeCenter provides with the "Playlists" menu. The only advantage over standard SqueezeCenter in this situation is that it can play a static playlist bit for bit. The standard SqueezeCenter adds all tracks in a static playlist to the playing playlist, the problem with this is if the static playlist is really long it will slow down some operations quite a bit. Dynamic Playlist plugin will add the first 10 track and when one has been played it will add the 11'th track and so on.

The real purpose of the Dynamic Playlist plugin is to make it easier for other plugins to implement different type of playlists. The Dynamic Playlist plugin also shows all supported playlists below the same menu instead of having them in several different menus, the advantage is that the user doesn't have to care which plugin that implements a specific playlist. So by it self the Dynamic Playlist plugin doesn't do much, the reason I wrote is was to make it easier for other plugins to generate playlists and through them provide more functionallity. At the moment at least the following plugins provides playlists through the Dynamic Playlist plugin:

  • SQL Playlist plugin:
    • Similar to iTunes smart playlists, if you don't know SQL you are limited to the predefined playlists types which should cover most of the cases. If you know SQL only the sky is the limit.
  • TrackStat plugin:
    • Provides a lot of different playlists based on statistic data in SqueezeCenter. It provides playlists directly to Dynamic Playlist plugin but also some different playlist types through the SQL Playlist plugin.
  • Random Playlist plugin:
    • Provides the similar playlists as the standard Random Mix plugin but makes it possible to exclude genres and already played tracks.
  • Custom Scan plugin:
    • Provides a playlists through SQL Playlist plugin for playing similar artists according to LastFM and tracks with a specific tag.
  • iTunes Party Shuffle plugin:
    • Provides shuffled playlists from iTunes, see plugin dokumentation for more information.

There might also be other plugins that integrate with Dynamic Playlist plugin which I'm not aware of yet.

Installation

  1. Remove any previous version of Dynamic Playlist from the SqueezeCenter Plugins directory if you have manually installed it earlier (this is not needed if you have installed it through Extension Downloader)
  2. Goto SqueezeCenter Settings/Advanced/Extension Downloader and select to install Dynamic Playlist. You might need to add Erland's repository to see it, see here for more information regarding this: SqueezeCenter_Repositories. If you don't want to install it through Extension Downloader, you can also download it from the download page and manually unzip the new version in the SqueezeCenter Plugins directory
  3. Optionally Install other plugins that extends Dynamic Playlist with more functionality
  4. After you have installed everything you might also want to look at:

If you are using SlimServer 6.5 or earlier, you may want to use the old guide instead.

Bugs and new features

The current list of known bugs and wishes for new features can be found here:

If you want to encourage future development of this plugin you should also consider making a donation

http://erland.isaksson.info/donate

Additional configuration options

If you goto the Dynamic Playlist section in the Advanced section of SqueezeCenter Settings it is possible to change a number of different option that changes the behaviour of the Dynamic Playlist plugin, for example:

  • Disable playlists you don't use. This is useful if you for example uses the TrackStat plugin which provides a lot of playlists while you might only be interested in a few of them.
  • Selecting if static playlists should be played in random order or not
  • Enable/Disable filters, for example the filter provided through the Custom Skip plugin
  • Selecting favourite playlists. Favourite playlists will be shown in a separate group in the user interface to make it easier to find them.

Integration with Custom Skip plugin

The Dynamic Playlist plugin can optionally use the Custom Skip plugin for skipping certain songs. This is useful for example if you have a few artist which you don't want to play or want to make sure no christmas music is played during the summer. The integration with the Custom Skip plugin works as follows:

  1. Dynamic Playlist plugin retreives the next tracks to be played
  2. Each of the tracks is validated towards the active filters in the Custom Skip plugin
  3. If a track matches a filter it is skipped, if it don't matches it will be added to the current playlist and played

The Dynamic Playlist plugins also provides a number of Custom Skip filters itself that is useful in some situations, these are

  • Recently added album
Skip songs from albums that have been recently added to current dynamic playlist. This is really useful if you want to make sure that a random playlist is real random by not repeating tracks from the same album for maybe 10 tracks. It should be noted that this Custom Skip filter is not very useful to have as a filter that is always active, instead it's recommended that you use the SQL Playlist plugin to create the random playlist and configure it to activate this filter when the playlist is started. This way the filter will only be active when running random playlists and not at other times. Another note is that this filter depend on the Dynamic Playlist plugin so they only work for playlists that are played through the Dynamic Playlist plugin.
  • Recently added artist
Skip songs by artists that have been recently added to current dynamic playlist. This is really useful if you want to make sure that a random playlist is real random by not repeating tracks from the same artist for maybe 10 tracks. It should be noted that this Custom Skip filter is not very useful to have as a filter that is always active, instead it's recommended that you use the SQL Playlist plugin to create the random playlist and configure it to activate this filter when the playlist is started. This way the filter will only be active when running random playlists and not at other times. Another note is that this filter depend on the Dynamic Playlist plugin so they only work for playlists that are played through the Dynamic Playlist plugin.

Connection to remote buttons

The Dynamic Playlist plugin supports to add shortcuts to play a specific playlist by hitting a remote button. This is done through the custom.map file in SqueezeCenter.

An entry like this would start to play the "Random songs" playlist provided by SQL Playlist plugin when you hit the 0 button:

0 = modefunction_Plugins::DynamicPlayList::Plugin->play_sqlplaylist_randomtracks

If you want the playlist to continue if it is already running, you can instead use:

0 = modefunction_Plugins::DynamicPlayList::Plugin->continue_sqlplaylist_randomtracks

The string is combined as follows: [button]=modefunction_Plugins::DynamicPlayList::Plugin->[action]_[playlistid]

Where

  • [button] - The button to connect it to, see SqueezeCenter documentation for more information
  • [action] - "play" if you like to restart the playlist, "continue" if you like to continue the playlist if it is running or start it if it isn't running
  • [playlistid] - The identifier for the playlist, you will find this as a parameter in the urls in the web interface. For SQL PlayList it is basically "sqlplaylist_[filename]" where [filename] is the filename in which the playlist is stored besided the extension.

CLI interface

The Dynamic Playlist plugin offers a CLI interfase with the following commands. If you want the answers to look the same in both SlimServer 6.5, 6.2 and SqueezeCenter you will need to use the version of the commands with a MAC address of the SqueezeBox first. Playlists which requests parameters from the user will currently not be available in the CLI commands that read available playlists, the reason is simply that there is currently no way to specify the parameter values in the CLI interface.

  • Get all enabled playlists
dynamicplaylist playlists
00:04:20:06:22:b3 dynamicplaylist playlists
  • Get both enabled and disabled playlists
dynamicplaylist playlists all
00:04:20:06:22:b3 dynamicplaylist playlists all
  • Start playing playlist dynamicplaylist_random_track, restart the playlist if it is already playing
00:04:20:06:22:b3 dynamicplaylist playlist play dynamicplaylist_random_track
  • Start playing playlist dynamicplaylist_random_track, continue the playlist at current position if it is already playing
00:04:20:06:22:b3 dynamicplaylist playlist continue dynamicplaylist_random_track
  • Add songs from playlist dynamicplaylist_random_track to currently playing playlist
00:04:20:06:22:b3 dynamicplaylist playlist add dynamicplaylist_random_track
  • Stop adding songs to currently playing playlist
00:04:20:06:22:b3 dynamicplaylist playlist stop

Database structure

The Dynamic Playlist plugin create an extra database table dynamicplaylist_history where it stores information about tracks that has been added to the current playlist. This table is useful to know of if you write smart playlists yourself, the reason is that it will keep a log of played tracks and it will contain all tracks even though they have been removed from the current playlist. By using this table in smart playlists you can quite easy create a random playlist that never repeat the same track twice.

The SQL Playlist plugin uses this table for exactly this purpose to make sure its smart playlist only play each track once.

Dynamic playlists as separate plugins

You can implement your own dynamic playlists by implementing the methods described below in your plugin. The plugin must be enabled for it to be detected by Dynamic Playlist plugin.

The functions are called like:

  • getDynamicPlayLists is called whenever Dynamic Playlist plugin needs a fresh list of available playlists, this happens at startup and when you goto the Dynamic Playlists web interface or menu on the SqueezeBox.
  • getNextDynamicPlayListTracks is called when Dynamic Playlist is running out of tracks in the current playlist and more tracks is needed. This method is only called on the plugin which implements the playlist that is played.

If you want to do something when a playlist is started or when a playlist is stopped in your own plugin you should do this by providing start/stop actions in the getDynamicPlayLists function as shown in the samples below.

# Returns a map with a an entry for each playlist, 'myplugin_mycoolplaylist' in the sample below
# The playlist entry must contain a 'name' but it can also contain additional items which you
# need later when tracks are requested for the playlist.
# The 'url' parameter is optional and will be a link in the web interface which the user
# can click on to get to the settings for the playlist
# The 'groups' parameter is optional and will but the playlist in the specified groups, in the example
# below the playlist will be available in: "Albums/Cool" and "Cool"
# The 'parameters' parameter is optional and will result in that the user is forced to select values
# for the specified parameters before the playlist is acutally played. Playlists with parameters will
# currently not be available in the CLI interface. If the first parameter is of type album, artist, playlist
# genre or year this will also result in a PL button in the browse pages, clicking on an artist in the
# browse page will set that artist id as the first parameter. More samples for parameter definitions can
# be found as a number of template playlists possible to create in the SQLPlayList plugin web ui.
# This method will be called by the DynamicPlaylist plugin whenever the playlists shall be shown
sub getDynamicPlayLists {
        my ($client) = @_;

        my %result = ();
        my %playlist = (
                'name' => 'My Cool Playlist',
                'url' => 'plugins/MyCoolPlugin/index.html',
                'groups' => [['Albums','Cool']['Cool']]
        );

        # *** Starting optional part for requesting parameters from the user ***
        my %parameter1 = (
                'id' => 1, # A number between 1-10
                'type' => 'album', # Can be one of: album, artist, genre, year, playlist, list, custom
                'name' => 'Choose album', # Text that should be shown to the user when asking for parameter
                'definition' =>  # Only valid if type is list or custom
        );                         # If type = list the following will show the user Value1 and Value2 and the value
                                   # sent back to your plugin will be 1 or 2
                                   # 1:Value1,2:Value
                                   # If type = custom the definition is a sql statement with two columns id and name
                                   # The following will show the user a list of all artist starting with "A"
                                   # select id,name from contributors where name like 'A%'
                                   # If type = custom the sql can also contain the text 'PlaylistParameter1' and this
                                   # will be replaced with the value of the first parameter
                                   # If the SQL the two first column needs to be id and the visible text, the third column
                                   # is optional and should contain the first letter of the sorting key if available, see
                                   # parameter2 example below.
                                   # There is also a special keyword 'PlaylistActiveLibrary' that always will be replaced
                                   # with the id number of the currently active library in the Multi Library plugin or with 
                                   # 0 if no library is active.                                 
                                   
        my %parameter2 = (
                'id' => 2, # A number between 1-10
                'type' => 'custom', # Can be one of: album, artist, genre, year, playlist, list, custom
                'name' => 'Choose artist starting with A', # Text that should be shown to the user when asking for parameter
                'definition' => 'select id,name,substr(namesort,1,1) from artist where name like '\'A%\ #See description above
        );
        
        my %parameters = (
                1 => \%parameter1, # The key 1 must match the 'id' value in the parameter
                2 => \%parameter2  # The key 2 must match the 'id' value in the parameter
        );
        $playlist{'parameters'} = \%parametrs;
        # *** Ending optional part for requesting parameters from the user ***

        # *** Starting optional part for executing actions at playlist start/stop ***
        my %action1 = (
                'type' => 'cli', # Can be one of: cli
                'data' => 'customskip setsecondaryfilter myfilter.cs.xml'       
        );                         # If type = cli the data value shall contain the complete CLI command
                                   
        my %action2 = (
                'type' => 'cli', # Can be one of: cli
                'data' => 'customskip clearsecondaryfilter' #See description above
        );
        
        my @startactions = [\%action1];
        my @stopactions = [\%action2];
        $playlist{'startactions'} = \@startactions;
        $playlist{'stopactions'} = \@stopactions;
        # *** Ending optional part for executing actions at playlist start/stop ***

        $result{'myplugin_mycoolplaylist'} = \%playlist;
        return \%result;
}
# Returns the next tracks, this method will be called by DynamicPlaylist plugin when more tracks are needed
# playlist = This is the same map for the playlist as you returned in the getDynamicPlayLists method
# limit = The number of tracks that should be returned
# offset = The offset of the track from the beginning of the playlist
# parameters = The parameters together with the values the user has entered (The parameters part of the sample 
#              below is just to show how to read the parameters)
sub getNextDynamicPlayListTracks {
        my ($client,$playlist,$limit,$offset,$parameters) = @_;

        my @result = ();

        # *** Starting optional part for reading values for requested parameter values
        if($parameters->{1}->{'value'} eq '1') {
                # Do some stuff if first parameter is 1, this is just a stupid example that doesn't do anything useful
        }
        # *** Ending optional part for readin values for requested parameter values

        my $items;

        # NOTE! This part is for SqueezeCenter 6.3 and earlier it doesn't work for Slimserver 6.5, SqueezeCenter and later
        #$items = $ds->find({
        #        'field'  => 'track',
        #        'find'   => {'audio' => 1},
        #        'sortBy' => 'random',
        #        'limit'  => $limit,
        #        'cache'  => 0,
        #});

        for my $track (@$items) {
                push @result, $track;
        }
        return \@result;
}

Skipping filters as separate plugins

It is also possible to implement a skipping filter in a separate plugin, you do this by implementing the functions below.

Note!
Even though it is possible to implement a skip filter with the metods described here its is a much better way to do it by integrating with the Custom Skip plugin. The Custom Skip plugin provides a user interface for editing filter parameters and creating filters so you will save a lot of time by integrating with the Custom Skip plugin instead of writing the functions listed here.

# Will be called whenever Dynamic Playlist needs a fresh list of available filters
sub getDynamicPlayListFilters {
	my $client = shift;
	my %myFilter = (
		'name' => 'Custom Skip',
		'url' => 'plugins/CustomSkip/customskip_list.html',
		'defaultenabled' => 1
	);

	my %myFilters = (
		'customskip' => \%myFilter
	);
	return \%myFilters;
}


# Will be called whenever a track needs to be evaluated towards a filter
sub executeDynamicPlayListFilter {
	my $client = shift;
	my $filter = shift; # This is the filter that should be evaluated, its the same has as myFilter which was returned from the getDynamicPlayListFilters function earlier
	my $track = shift; # This is the track object that should be checked against the filter specified in the filter parameter
	
	# TODO: Implement skipping logic, the return values should be
	#  1 = Track should be played
	#  0 = Track should be permanently skipped
	# -1 = Track should be skipped now but retried later

	return 1;
}


Database structure

The Dynamic Playlist stores the tracks added to the current playlist to make it possible to create playlists that doesn't repeat already played tracks within the same playlist.

The information is stored in the dynamicplaylist_history table in the database which have the following columns:

  • client - The MAC address of the player, in the format: xx:xx:xx:xx:xx:xx
  • position - The position in the playlist
  • id - The unique id of the track, this is the same value as in tracks.id
  • url - The url of the track, this is the same value as in tracks.url
  • added - Indicates the time when the track was added to the current playlist
  • skipped - Set to 1 if the track was found supposed to be added to a playlist but was skipped due to an active filter, for example a filter in the Custom Skip plugin

Entries will be removed from this table when SqueezeCenter is restarted and when a new playlist is started for a player through the Dynamic Playlist plugin.

The relation between this table and the tracks table is defined as:

dynamicplaylist_history.id=tracks.id