[SET pageicon help] [SET title SLIMP3 Plugins] [SET techinfo 1] [INCLUDE helpheader.html]

Introduction

This document illustrates the basic framework upon which to build a Plugin or module compatible with the SLIMP3 server software. The SLIMP3 server provides a method to load custom modules at startup which are then made available to the user via remote control menus. Each plugin serves as an area within SLIMP3 remote menu system, available from within the Plugins menu. Plugin files are stored in the "Plugins" folder which is in the same folder as the SLIMP3 server software. The Plugin interface can provide a very powerful control and has complete access to the functionality of the SLIMP3 server. As with the rest of the SLIMP3 server, plugin modules are created using the Perl language.

Perl Module Basics

Here are a couple of basic calls that should be made at the beginning of the Plugin code:

use strict;

This tells perl to do some useful error checking to help avoid the use of undeclared variables, or ambiguous references to functions. All references must be fully qualified (ie SLIMP3::Animation::showBriefly() instead of showBriefly()).

package Plugins::pluginname;

Where pluginname is the name of the module (which should be the same as the filename, without the .pm extension.) This defines the 'namespace' for the module. It essentially sets up the module as an entity of its own, within the server environment. This allows you to then refer to the functions and variables within this plugin by the full reference Plugins::pluginname::function.


SLIMP3 Plugin Hooks

Each level in the SLIMP3 menu hierarchy is considered a "mode" by the SLIMP3 server. Each time the server is started, it reads the Plugins directory for modules. Each is added, by name, into a list. Each plugin is given a mode, and a set of functions that are defined within that module. The plugins can each be enabled or disabled at will from the web interface. The plugin module itself must define a mode and fuctions in a form that the server is expecting. This comes from two functions: sub setMode() and sub getFunctions(). A third subroutine, sub getDisplayName() is required to provide the name that the server should display for the plugin. Simple examples of these three functions are below. We will now build a template based on these main functions.

Example 1

  sub setMode() {
     my $client = shift;
     $client->lines(\&lines);
  }

  sub getFunctions() {
     return \%functions;
  }

  sub getDisplayName() { return "My Plugin Name")}

			

Modes

The remote buttons are context sensitive, meaning that they can serve different roles when the SLIMP3 is in different modes. The setMode() subroutine defines this mode. Within this subroutine, there must be a definition for $client->lines, which is the text to be displayed on the SLIMP3 while in this plugin mode. Typically, this is labelled just as above, though it can be any name you wish. The lines subroutine, or other name if you have chosen one, returns two strings. One for each line of the display. They can be updated at any time from any point in the plugin module by using the line:

SLIMP3::Display::update($client);

Also included in the setModes subroutine are any commands or functions that must be run each time the plugin is called. This may be loading an array for a menu system, default settings, or running any number of other subroutines that are needed for the operation of the plugin.

You may also want to add extra modes under your plugin. There is a function call that tells the server to add your new mode with its setMode and getFunctions references.

SLIMP3::Buttons::Common::addMode('newmodename', getNewModeFunctions(), \&::PluginName::setNewMode);

and then you can include the following in your plugin to hook-in to your new mode:

sub setNewMode() {
   my $client = shift;
   $client->lines(\&newModeLines);
}

sub getNewModeFunctions() {
   return \%newModeFunctions;
}

Functions

The SLIMP3 server handles all commands from the remote control for each mode by creating a hash table of functions, each button having a subroutine associated with it. The subroutine getFunctions() returns a reference to this hash, and can be any label you wish, although typically %functions is used. The call to point to this list is shown above in example 1. The function list, should look something like this example taken from rescan.pm, which is included with the SLIMP3 server:

Example 2

   my %functions = (
     'up' => sub  {
        my $client = shift;
        SLIMP3::Animation::bumpUp($client);
     },
     'down' => sub  {
        my $client = shift;
        SLIMP3::Animation::bumpDown($client);
     },
     'left' => sub  {
        my $client = shift;
        SLIMP3::Buttons::Common::popModeRight($client);
     },
     'right' => sub  {
        my $client = shift;
        SLIMP3::Animation::bumpRight($client);
     },
     'play' => sub {
        my $client = shift;
        my @pargs=('rescan');
        my ($line1, $line2) = (string('PLUGIN_RESCAN_MUSIC_LIBRARY'), string('PLUGIN_RESCAN_RESCANNING'));
        SliMP3::Command::execute($client, \@pargs, undef, undef);
        SLIMP3::Animation::showBriefly($client, $line1, $line2);
     }
  );

Each remote button (eg. 'play') points to a subroutine to be performed each time that button is pressed. In the case above, pressing play sets up local variables, starts a rescan of the entire library, then shows two lines on the display for a short time to tell the user that the rescan has been started. The line "my $client = shift;" is very important here to keep track of the player status, and to pass on in server function calls such as:

SLIMP3::Animation::showBriefly($client, $line1, $line2);

Examples of remote control fucntions include: 'up','down','play,'add' (REC button),'left','right','numberScroll' and 'stop' The full button to function map is found in the Default.map file, which is in the IR directory under the SLIMP3 server directory.


Lines

The lines subroutine returns the text that the SLIMP3 will display while using your plugin. The setMode() function creates the reference for the lines subroutine, and your lines subroutine name must match that. Each mode may have its own set of lines, and each is named after the reference created in each setMode. The input for this function is the current client information, and the return is two strings for main display and optionally a pair of strings which may need to be overlayed on top of the first pair, right justified. The lines are sent to the display at any time using the command:

SLIMP3::Display::update($client);

The simple line subroutine, below, is taken from Rescan.pm.

Example 3

sub lines {
   my ($line1, $line2);
   $line1 = string('PLUGIN_RESCAN_MUSIC_LIBRARY');
   $line2 = string('PLUGIN_RESCAN_PRESS_PLAY');
   return ($line1, $line2);
};

Strings

The plugin API also allows you to add in your own localisation. The format of the strings list follows the same format as the strings.txt file used by the SLIMP3 server for localization. The function strings() can be used used within the plugin to extract a strings for the user's specified language. Defining the strings is done as follows:

Example 4

sub strings() { return '
PLUGIN_STRING_ONE
<tab> EN <tab> English version of line one
<tab> FR <tab> Version française de la ligne une
'};
and to use your strings in your module, you make the call to strings in any place where you would use a text string. For example, referring to the getDisplayName() call from Example 1:
sub getDisplayName() { return "My Plugin Name" }
can be changed to
sub getDisplayName() { return strings('PLUGIN_NAME') }
where your strings function contains:
sub strings() { return '
PLUGIN_NAME
<tab> EN <tab> My Plugin Name
'};

One special note, the format of the strings list is very strict. The whitespace must be a tab, not spaces, which is why the tabs are shown above.


Summary

Using the existing plugins as examples (one appears below) and this document as an explanation of what each section of the plugin can do, you should now be able to start working on a plugin of your own. Remember that this is only a framework to allow you to hook into the SLIMP3 server. There are always many other ways to implement the features of a plugin. As long as your provide the lines from the examples above, the server will try to work with your Plugin. The rest can be just about anything you want, including using any of functions and subroutines within the SLIMP3 server. Remember, there's more than one way to do it.

Happy Coding!


Appendix: Sample Plugin

# Rescan.pm by Andrew Hedges (andrew@hedges.me.uk) October 2002
#
# This code is derived from code with the following copyright message:
#
# SliMP3 Server Copyright (C) 2001 Sean Adams, Slim Devices Inc.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2.
use strict;

###########################################
### Section 1. Change these as required ###
###########################################

package Plugins::Rescan;

use SliMP3::Playlist;
use SliMP3::Strings qw (string);

sub getDisplayName() {return string('PLUGIN_RESCAN_MUSIC_LIBRARY')}

sub strings() { return '
PLUGIN_RESCAN_MUSIC_LIBRARY
	EN	Rescan Music Library
	
PLUGIN_RESCAN_RESCANNING
	EN	Server now rescanning...

PLUGIN_RESCAN_PRESS_PLAY
	EN	Press PLAY to rescan your music folder
'};

##################################################
### Section 2. Your variables and code go here ###
##################################################


sub setMode() {
	my $client = shift;
	$client->lines(\&lines);
}

sub enabled {
	my $client = shift;
	return !SliMP3::iTunes::useiTunesLibrary();
}

my %functions = (
	'up' => sub  {
		my $client = shift;
		SliMP3::Animation::bumpUp($client);
	},
	'down' => sub  {
	    my $client = shift;
		SliMP3::Animation::bumpDown($client);
	},
	'left' => sub  {
		my $client = shift;
		SliMP3::Buttons::Common::popModeRight($client);
	},
	'right' => sub  {
		my $client = shift;
		SliMP3::Animation::bumpRight($client);
	},
	'play' => sub {
		my $client = shift;
		my @pargs=('rescan');
		my ($line1, $line2) = (string('PLUGIN_RESCAN_MUSIC_LIBRARY'), string('PLUGIN_RESCAN_RESCANNING'));
		SliMP3::Command::execute($client, \@pargs, undef, undef);
		SliMP3::Animation::showBriefly($client, $line1, $line2);
	}
);

sub lines {
	my ($line1, $line2);
	$line1 = string('PLUGIN_RESCAN_MUSIC_LIBRARY');
	$line2 = string('PLUGIN_RESCAN_PRESS_PLAY');
	return ($line1, $line2);
}
	
################################################
### End of Section 2.                        ###
################################################

sub getFunctions() {
	return \%functions;
}

1;
[INCLUDE helpfooter.html]