Writing XMMS2 Clients
Clone this wiki locally
Before setting out to write an XMMS2 client, you should familiarise yourself with the XMMS2 'middleware' (provided by libxmmsipc and used transparently by libxmmsclient).
It is strongly recommended that you check out the code from the xmms2-tutorial Git repository to learn the basics of writing XMMS2 clients.
Please ensure that you use the latest stable xmms2 version when following the tutorials.
The rest of this page documents various issues you might encounter while working on your client, as well as some conventions and recommendations you should follow.
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.
- Clients should respect the XMMS_PATH environment variable, if set.
- Clients may store their config data $XDG_CONFIG_HOME/xmms2/clients, or ~/.config/xmms2/clients/ if unset. (NOTE: This is a new change in DrGonzo). However, you won't need to hardcode this path - a new function (xmmsc_userconfdir_get) exists in client library to retrieve the path to the xmms2 configuration directory - that is, $XDG_CONFIG_HOME/xmms2.) Simple clients may get by with single conf files, like myclient.conf, while more complex clients may use a subdirectory, such as advancedclient/.
- Clients should not store daemon config keys and values in their own config - they should query the daemon instead. (some exceptions apply, for example, the IPC path to use)
- The XMMS2 daemon can start clients as part of its own startup process, and also shut them down when exiting. To use this feature, place a symlink to your client (or a launcher script) in $XDG_CONFIG_HOME/xmms2/startup.d/ and a shutdown script in $XDG_CONFIG_HOME/xmms2/shutdown.d/. Note that these paths are the defaults and may be modified via the core.startuppath and core.shutdownpath configuration properties.
- Clients must not stop playback and/or cause the daemon to shut down - by default - when they are closed or otherwise terminated by the user. Clients may provide a non-default option for the user to specify that playback should be stopped and/or that the daemon should be shut down on exit.
- Any single client may open any number of connections to the daemon. However, it is recommended that, in most cases, only one connection is used for the whole session. Clients that remain running for extended periods (unlike the command line client) should not simply connect, perform a command, then disconnect every time an action is requested by the user. In some cases, it might be beneficial to have up to two connections to the daemon - one 'normal' connection and a second connection for handling 'slower' commands, such as querying the medialib.
- Clients - especially those communicating with xmms2d asynchronously - should set a disconnect callback (xmmsc_disconnect_callback_set, or the disconnect_func argument of XMMS.connect in the Python bindings). This callback will be executed when xmms2d is shutting down and it could, for example, close the client program, or do whatever is necessary to reset the client's state so that it can connect to the daemon again.
- Clients may display a stream's URL or filename if the stream doesn't have any metadata indicating its title. (e.g. missing ID3 tags in MP3 files)
- Clients that show some representation of the playlist should connect to the playlist_changed broadcast in order to keep their copy of the playlist data consistent with the playlist on the daemon.
- Some signal results may be sent at a very high rate, for example the playback_time signal, which delivers values representing milliseconds played. This might in turn cause clients to unnecessarily process every such result and update a number of widgets - which can cause unpleasant effects such as flickering. To prevent this, clients should update their widgets only when necessary (for example, if a half second difference is calculated between the last result value and the latest result value). Clients may also delay the restarting of the signal result (which effectively throttles the rate at which the results are sent).
- To enable drag & drop between clients some guidelines must be followed. The target entry for medialib ids is "application/x-xmms2mlibid", and "application/x-xmms2poslist" for playlist positions. Both should be of type int32_t array.
- XMMS2 clients can store and retrieve binary data from the daemon (using the so-called bindata API). A suitable client (such as xmms2covers) may store image data and set the appropriate album art related properties after querying suitable web services and matching songs with album covers (or via some equivalent mechanism). Other clients may then retrieve the stored image data for display.
- It is generally discouraged to use threads in XMMS2 clients - especially graphical clients, where race conditions could disrupt the proper functioning of a graphical toolkit's event loop (and the process of moving messages back and forth over xmmsipc). If you must absolutely use threads, you must make sure to implement proper locking and mutual exclusions to maintain the consistent state of your program.
- Collections with names starting with underscore ("_autosaved", "_active"), should not be shown to the user.
- When processing the result from a browsing request the 'realpath' property should be used instead of path, if it exists.
- Once you get your client working, drop us an e-mail to let us know about your work, and add your client to the XMMS2 Clients page.