373 lines
12 KiB
Plaintext
373 lines
12 KiB
Plaintext
Introduction
|
|
============
|
|
|
|
Cantata is a GUI front-end for MPD. The code is forked from QtMPC. However,
|
|
both the code itself, and the GUI are now *very* different to QtMPC.
|
|
|
|
|
|
Dependencies
|
|
============
|
|
|
|
Cantata requires the following Qt4 libraries:
|
|
|
|
1. QtCore
|
|
2. QtGui
|
|
3. QtNetwork
|
|
4. QtDBus (required ony for Linux builds)
|
|
|
|
Cantata many also use the following optional libraries:
|
|
|
|
1. KDElibs4
|
|
2. QtWebKit - uses for the artist/album information page. If QtWebKit is not
|
|
found, the page will not be built.
|
|
3. TagLib - used for the tag edit dialog, replaygain, track organizerm, and
|
|
for UMS device support.
|
|
4. LibMTP - used to support MTP devices.
|
|
5. FFMPEG (libavcodec) - used by ReplayGain detection code.
|
|
6. SpeexDSP - used by ReplayGain detection code.
|
|
7. MPG123 - used by ReplayGain detection code.
|
|
|
|
|
|
Translations
|
|
============
|
|
|
|
Cantata started out as a KDE4 application, but as of v0.9.0 all both the KDE
|
|
and Qt-only builds have the same functionality. Because of its KDE base, the
|
|
translation files are based upon KDE's i18n framework - these are located
|
|
within the 'po' folder.
|
|
|
|
Translations for Qt-only builds are created from the KDE translations using
|
|
'lconvert'. To work-around issues with plural translations, Qt builds will
|
|
contain extra strings to handle plural forms.
|
|
|
|
e.g.
|
|
|
|
KDE will have:
|
|
msgid "1 Track"
|
|
msgid_plural "%1 Tracks"
|
|
msgstr[0] ""
|
|
msgstr[1] ""
|
|
|
|
Qt will have:
|
|
msgid "1 Track"
|
|
msgstr ""
|
|
msgid "%1 Tracks"
|
|
msgstr ""
|
|
|
|
In the code, cantata will use "%1 Tracks" for any count other than 1. If the
|
|
language you are translating into has more plural forms (i.e. the above two
|
|
strings are not sufficient), then please translate both into the form
|
|
"Tracks: N" - e.g.
|
|
|
|
Qt will now have:
|
|
msgid "1 Track"
|
|
msgstr "Tracks: 1"
|
|
msgid "%1 Tracks"
|
|
msgstr "Tracks: %1"
|
|
|
|
|
|
Covers
|
|
======
|
|
|
|
When displaying covers, Cantata will load album covers in the following order:
|
|
|
|
...if MPD folder exists, is not specified as a http URL, and is readable, then
|
|
cantata will look for the following within the folder containing the song:
|
|
|
|
1. ${configuredName}.jpg - if set
|
|
2. ${configuredName}.png - if set
|
|
3. cover.jpg
|
|
4. cover.png
|
|
5. AlbumArt.jpg
|
|
6. AlbumArt.png
|
|
7. folder.jpg
|
|
8. folder.png
|
|
9. ${file}.jpg
|
|
10. ${file}.png
|
|
11. ${albumArtist} - ${album}.jpg
|
|
12. ${albumArtist} - ${album}.png
|
|
13. ${album}.jpg
|
|
14. ${album}.jpg
|
|
15. Image embedded within current songs tags.
|
|
16. ANY other jpg, or png
|
|
|
|
...then Cantata will check its cache folder (~/.cache/cantata/covers), for :
|
|
|
|
17. ${albumArtist}/${album}.jpg
|
|
18. ${albumArtist}/${album}.png
|
|
|
|
...if compiled for Linux
|
|
|
|
19. Matching Amarok cover
|
|
20. Matching Clementine cover
|
|
|
|
...if the MPD folder was specified as a http URL
|
|
|
|
21. ${url}/${dirFromFile}/cover.jpg - or ${url}/${dirFromFile}/${configuredName}.jpg (if set)
|
|
22. ${url}/${dirFromFile}/cover.png - or ${url}/${dirFromFile}/${configuredName}.png (if set)
|
|
|
|
...lastly
|
|
|
|
23. Query last.fm using ${albumArtist} and ${album}. Cantata will attempt to
|
|
download the image specified with the "extralarge" size.
|
|
|
|
Downloaded images will be saved as cover.jpg/png within the song folder if
|
|
possible. If not, then they will be saved in Cantata's cache folder.
|
|
|
|
|
|
For artist images:
|
|
|
|
...if MPD folder exists, is not specified as a http URL, and is readable, then
|
|
cantata will look for the following within the folder containing the song:
|
|
|
|
1. ${albumArtist}.jpg
|
|
2. ${albumArtist}.png
|
|
3. artist.jpg
|
|
4. artist.png
|
|
|
|
... the above will be repeated for each parent folder (until we reach the MPD
|
|
root folder)
|
|
|
|
...then Cantata will check its cache folder (~/.cache/cantata/covers), for :
|
|
|
|
5. ${albumArtist}.jpg
|
|
6. ${albumArtist}.png
|
|
|
|
...lastly
|
|
|
|
7. Query last.fm using ${albumArtist}. Cantata will attempt to download the
|
|
image specified with the "extralarge" size.
|
|
|
|
Downloaded artist images are saved to Cantata's cache folder.
|
|
|
|
|
|
Amarok Radio Streams
|
|
====================
|
|
|
|
The script amarok2cantata.sh may be used to covert Amarok Radio plugins
|
|
into an XML file suitable to be imported into Cantata. The script is
|
|
rather basic and requires the Amarok plugin to list its streams in 'main.js'
|
|
with the following syntax:
|
|
|
|
Station( "NAME", "URL")
|
|
|
|
Each station *must* be on its own line, and must be all in *one* line.
|
|
|
|
'script.spec' is used to ascertain the Amarok plugin name, for this the
|
|
script will look for the line starting with "Name="
|
|
|
|
|
|
Dynamic Helper Script - Local Mode
|
|
==================================
|
|
|
|
When a dynamic playlist is loaded in Cantata, the cantata-dynamic helper script
|
|
is executed in the background to do the actual song selection. In this way the
|
|
dynamic playlist can still function even when cantata is terminated. It is
|
|
possible for this script to be controlled on the command line (although it was
|
|
never written with this in mind).
|
|
|
|
The list of dynamic playlists may be obtained by looking in
|
|
~/.config/cantata/dynamic
|
|
|
|
To 'load' a dynamic play list, all you need to do is symlink the desired one in
|
|
~/.config/cantata/dynamic to ~/.cache/cantata/dynamic/rules. Then you can start
|
|
the helper by calling '/usr/bin/cantata-dynamic start' (or first call
|
|
'/usr/bin/cantata-dynamic stop' to stop any current play list).
|
|
|
|
To pass connection details, cantata-dynamic reads the same environment variables
|
|
as mpc - namely MPD_HOST and MPD_PORT
|
|
|
|
e.g. the following bash script (not tested!) will stop any current dynamic
|
|
playlist, load the 'MyPlaylist' playlist, and start this on the mpd at
|
|
'hostname:1234' with password 'pass'
|
|
|
|
# Stop current dynamic playlist
|
|
/usr/bin/cantata-dynamic stop
|
|
# Clear the playqueue (this requires mpc)
|
|
MPD_HOST=pass@hostname MPD_PORT=1234 mpc clear
|
|
# 'Load' new playlist
|
|
if [ -f "$HOME/.cache/cantata/dynamic/rules" ] ; then
|
|
rm "$HOME/.cache/cantata/dynamic/rules"
|
|
fi
|
|
ln -s "$HOME/.config/cantata/dynamic/MyPlaylist.rules" "$HOME/.cache/cantata/dynamic/rules"
|
|
# Restart dynamic script
|
|
MPD_HOST=pass@hostname MPD_PORT=1234 /usr/bin/cantata-dynamic start
|
|
|
|
|
|
Dynamic Helper - Server Mode
|
|
============================
|
|
|
|
In addition to the above, the helper script may be installed on the system
|
|
containg MPD, and run in 'server' mode. When run in this mode, it is intended
|
|
that the script be run system-wide and started when the system (or MPD) is
|
|
started. e.g. The script should be started as:
|
|
|
|
<install dir>/cantata-dynamic server <location of config file>
|
|
|
|
e.g.: /usr/bin/cantata-dynamic server /etc/cantata-dynamic.conf
|
|
|
|
When run as described above, the script will automatically daemonize itself.
|
|
|
|
Cantata's 'Connection' settings page contains entries to configure the host and
|
|
port of where the dynamic script is running. If Cantata is configured in this
|
|
manner, then it will attempt to talk to the helper via its HTTP API, and will
|
|
not start/stop a per-user instance of the script. If the config is left blank,
|
|
then cantata will assume the script is to be run in local mode.
|
|
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
The server mode has a simple ini-style configuration file, that has the
|
|
following paramters (shown here with the default values):
|
|
|
|
pidFile=/var/run/cantata-dynamic/pid
|
|
filesDir=/var/lib/mpd/dynamic
|
|
activeFile=/var/run/cantata-dynamic/rules
|
|
mpdHost=localhost
|
|
mpdPort=6600
|
|
mpdPassword=
|
|
httpPort=6601
|
|
httpControlPage=0
|
|
|
|
'filesDir' This controls where the dyamic rules are stored. The user the script
|
|
is run as should have read/write permissions to this folder.
|
|
|
|
'activeFile' When a set of rule is made 'active', all cantata does is create a
|
|
symbolic link from the rules file to the file specified in 'activeFile'
|
|
|
|
'mpdHost', 'mpdPort', and 'mpdPassword' are the connection details of the MPD
|
|
server.
|
|
|
|
'httpPort' is the port to be opened by the script to allow it to be controlled.
|
|
|
|
'httpControlPage' If set to '1' then if you point a browser to
|
|
'http://<host>:<httpPort>' then the script will return a simple web-page
|
|
containing a list of the dyamic rules (which if clicked will become 'active'),
|
|
and a button to stop dynamic mode. Set to '0' to disable this page.
|
|
|
|
|
|
Installation
|
|
-------------
|
|
|
|
Within the dynamic/init are example configuration and init files. Copy one of
|
|
the example init scripts (or create a new one) to /etc/init.d/cantata.dynamic -
|
|
and create the appropriate links in /etc/rc?.d
|
|
|
|
Copy dynamic/init/cantata-dynamic.conf to /etc, and edit as appropriate.
|
|
|
|
|
|
API
|
|
---
|
|
|
|
This is a brief (and probably incomplete) explanation of the HTTP API.
|
|
Currently it is only used by Cantata.
|
|
|
|
GetStatus
|
|
Mode: HTTP GET
|
|
URL: http://host:port/status
|
|
Params: statusTime=${clientStatusTime}
|
|
Return: String containing
|
|
STATE:<current status>
|
|
RULES:<name of currently active rule>
|
|
TIME:<epoch time since started, or last rule modification>
|
|
|
|
<current status> may be:
|
|
IDLE - dynamic mode is not running
|
|
NO_SONGS - no songs matched current rules
|
|
HAVE_SONGS - dynamic mode running, and songs found
|
|
STARTING - dynamic mode is starting
|
|
|
|
The client should store the TIME value, and use it to determine whether
|
|
any rules have been changed since it last retrieved the list.
|
|
|
|
ListPlaylists:
|
|
Mode: HTTP GET
|
|
URL: http://host:port/list
|
|
Params: statusTime=${clientStatusTime}
|
|
Return: String containd list of current rules. if 'withDetails' is set to
|
|
'1' then the contents of the rules are also returned.
|
|
|
|
Example return:
|
|
FILENAME: Wibble.rules
|
|
Rule
|
|
Artist: Wibble
|
|
FILENAME: Heavy Metal.rules
|
|
Rule
|
|
Genre: Heavy Metal
|
|
|
|
GetPlaylist:
|
|
Mode: HTTP GET
|
|
URL: http://host:port/${playlist}
|
|
Params: statusTime=${clientStatusTime}
|
|
Return: Returns the contents of the specified 'playlist'. Or, a string
|
|
starting with 'ERROR:' in the case of failure.
|
|
|
|
DeletePlaylist:
|
|
Mode: HTTP DELETE
|
|
URL: http://host:port/${playlist}
|
|
Return:
|
|
|
|
SavePlaylist:
|
|
Mode: HTTP POST
|
|
URL: http://host:port/save
|
|
Params: name=${playlist} [Required]
|
|
BODY: Playlist content
|
|
Return:
|
|
|
|
SetActive:
|
|
Mode: HTTP POST
|
|
URL: http://host:port/setActive
|
|
Params: name=${playlist} [Required]
|
|
start={1/0} If set to '1' dynamic mode is also started.
|
|
|
|
ControlDynamizer:
|
|
Mode: HTTP POST
|
|
URL: http://host:port/control
|
|
Params: state={start/stop} [Required]
|
|
|
|
|
|
In order to detect whether the set of stored rules has changed, a client should
|
|
supply the 'statusTime' parameter with the value set to the last 'TIME' value
|
|
returned by a 'status' call. (If the client has no current value, use '1') The
|
|
script will then return the current statusTime, as well as the string
|
|
UPDATE_REQUIRED if the client should update its list of playlists (by calling
|
|
the 'ListPlaylists' API)
|
|
|
|
|
|
Credits
|
|
=======
|
|
|
|
Cantata contains code/icons from:
|
|
Amarok - amarok.kde.org (Media device detection)
|
|
Clementine - www.clementine-player.org (Lyrics searches)
|
|
Quassel - quassel-irc.org (Qt-only keyobard short-cut config support)
|
|
Solid - solid.kde.org (Device detection for Qt-only builds)
|
|
libebur128 - https://github.com/jiixyj/libebur128
|
|
wikipedia icon - Social Media Mini by Paul Robert Lloyd License: Commons licence: Attribution-Share Alike 2.0 UK: England & Wales
|
|
gear icon - Token by http://brsev.deviantart.com License: Creative Commons Attribution Non-commercial (by-nc)
|
|
|
|
|
|
Windows
|
|
=======
|
|
|
|
To compile for windows:
|
|
|
|
1. Install Qt, MinGW, cmake, TagLib. TagLib will probably need compiling.
|
|
2. Call cmake (e.g.):
|
|
cmake ../src -G "MinGW Makefiles" -DTAGLIB_INCLUDES=z:\taglibtaglib\include -DTAGLIB_LIBRARIES=z:\taglib\lib\libtag.dll.a -DTAGLIB_MP4_FOUND=1 -DTAGLIB_ASF_FOUND=1
|
|
3. make! :-)
|
|
|
|
This build is as per Qt-only, but does not have support for dbus, local dynamic
|
|
playlists, device support, or replaygain calculation.
|
|
|
|
To run you will also need Oxygen icons.
|
|
|
|
|
|
TagLib
|
|
------
|
|
|
|
Windows version of taglib was build from TagLib 1.8, using the following cmake command:
|
|
cmake .. -G "MinGW Makefiles" -DWITH_ASF=1 -DWITH_MP4=1 -DCMAKE_INSTALL_PRFIX=z:\taglib
|
|
|