Amarok/Development/Scripting HowTo 2.0
This page is about Amarok 2.0. For information on scripting in Amarok 1.4, see Script-Writing HowTo.
Introduction
We Amarok developers try our best to make Amarok the most awesome player ever. However sometimes there is a feature that we haven't implemented, either because we haven't gotten to it yet or because it wouldn't make sense for everyone. But have no fear! With Amarok 2.0's powerful QtScript framework you have access to nearly the entire Qt API: the same framework Amarok developers used to write Amarok itself. The possibilities are limited only by your imagination and your knowledge of Qt and JavaScript. We can't do anything about the former, but we'll try to help you out with the latter here. :)
Just a warning at the start: the layout of the sql tables is not guaranteed, so writing data into the SqlDatabase yourself is strongly discouraged. We are buffering a lot of stuff, so while Amarok is running you are virtually guaranteed to produce inconsistent states. Also some values in the database can make Amarok crash, e.g. a track without an album.
A DBus interface is also provided for interfacing with Amarok from external applications or plasmoids.
The DBus Interface for External Applications
DBus is a interprocess communication framework; so it really has the same purpose as DCOP. However the DBus interface in Amarok 2.0 has only a small subset of the power of the DCOP interface in Amarok 1.4: in the case of Amarok the true successor of DCOP is QtScript (see next section).
The Amarok 2.0 interface implements MPRIS 1.0 DBus API. User of MPRIS can get information about Amarok's state, tracks and basic playlist manipulation.
QtScript In-Process Scripts
Amarok 2.0 provides access to a set of Amarok-specific objects and the Qt API via JavaScript.
JavaScript
Amarok scripts are written in the language JavaScript 1.5 using the QtScript engine. If you are familiar with JavaScript from web developing you are in good shape, but its important to note that web browser specific extensions like DOM and some functions are not available.
Resources
A good resource for JavaScript is (not surprisingly) provided by the Mozilla community.
- JavaScript Guide - A thorough overview of the language.
- API documentation for the standard functions and objects - This documents some functions only available in JavaScript 1.6, which Amarok does not support; they are marked as such.
- Quick reference - a Nokia Qt (4.8) provided list of objects and functions in ECMA script/javascript.
There are also many other JavaScript guides and tutorials on the Internet. Though often web-browser oriented, many are still relevant.
Qt Bindings
Qt is the C++ GUI toolkit and library used by Amarok and KDE. Using the same technology behind the Qt Java bindings QtJambi, Amarok provides JavaScript bindings to most of the Qt API. This allows you to create widgets and windows, use advanced XML parsing methods, create animations, browse the web, open a TCP port and much more.
Currently the JavaScript binding documentation is a simplistic list of methods and properties. However the C++ documentation and tutorials can still be used. Usually when developing a Amarok Script you can refer to the Trolltech C++ Qt documentation; the JavaScript docs are needed when they might differ slightly from the C++ API. This might happen when:
- C++ features being used that JavaScript doesn't support.
- templates
- Function overriding. If you see a set of functions in the Qt C++ docs with the same name, but different argument types then function overloading is being used and the Qt Bindings might have picked only one of them to support (generally the most complete function). Just refer to the binding docs to figure out which they used. Note that the Qt bindings do support different functions with the same name if they vary in the number of arguments.
- Classes that are redundant with built-in JavaScript types. Just use the JavaScript types instead. Examples include:
- QList, use Array instead
- QString, use String instead
- QVariant, use Object instead
Resources
- Qt's C++ Qt 4.8 documentation - the motherload. Has tutorials, explanatory papers and most importantly the API documentation.
- JavaScript Qt binding documentation - lists all the methods and properties available from the QtScript bindings.
Amarok Objects and Convenience Methods
If your writing an Amarok script, there's a good chance you mostly want to manipulate and query Amarok. There are objects available to every Amarok script that do just that; they are documented on our Script APIs.
Types of Scripts
Some scripts play a special role within Amarok: their role is defined in their .spec file. They all have access to all of the Qt and Amarok objects.
- Lyrics
- Internet Service - this script creates a new service available in the Internet tab: a powerful way to integrate your favorite audio-file-oriented web service into Amarok.
- Cover fetcher
Amarok Script Console
Amarok is bundled with the Amarok Script Console; its a script itself and can be started from the script manager. You can use it for testing out snippets of code and manipulating JavaScript, Qt and Amarok objects.
Simply enter 1 or more lines of code and press CTRL-enter. It shows the result of the final line or any exceptions that occur. Note that if you use the 'var' keyword, you won't be able to access that variable in subsequent entries.
Lyric Scripts
If you are writing a lyrics script, there are a few things to keep in mind. First of all, the way that lyric scripts get notified of requests for lyrics is they must connect to the AmarokLyricsScript::fetchLyrics signal, like so:
Amarok.Lyrics.fetchLyrics.connect( myLocalFunctionNameHere );
Make sure that your function has a signature of type:
function handler( artist, title, url ) {}
If the url parameter is empty, then Amarok is requesting a lookup for a certain song. However, if the url is not empty, Amarok already has a url and it it wants the script to fetch the lyrics directly. This only happens when the user has chosen a certain lyric from a bunch of suggestions.
In order to send the downloaded lyrics back to Amarok, your script should call:
Amarok.Lyrics.showLyrics( xml );
The parameter to this function has to be in following XML-format:
<lyric artist="artist name" title="song title" page_url="http://provided.by"> text text text text text text ... </lyric>
If your script wished to display rich-text lyrics, you can also call
Amarok.Lyrics.showLyricsHtml( html )
This function expects an html page, and will not be parsed for artist/title. When there where no exact match, but some suggestions, use following format:
<suggestions page_url="http://provided.by"> <suggestion artist="artist name" title="song title" url="http://url.to/the/specific/lyrics" /> ... </suggestions>
- When there is no track found:
<suggestions page_url="http://provided.by"> </suggestions>
Note here that the URL that you supply for each suggested song is the same that is sent back to fetchLyrics. That is, if the URL argument to fetchLyrics is non-null, it is because a user chose one of your suggestions, and you know that it is one of the urls that you supplied. So usually the URL is non-null when the same lyric script is called a second time on the same song, once a suggestion has been chosen.
Script Files
Scripts consist of a script.spec file and a main.js file. The main.js file is the script file thats loaded and executed.
Generally when your writing your script, you'll just edit the files directly. Amarok looks for scripts in the $KDEHOME/share/apps/amarok/script/yourscriptname/ directory. $KDEHOME is likely .kde, .kde4 or .amarok-nightly if you use Neon.
When your ready to distribute the script, just tar it up in a file.
$ tar -czvf yourscriptname.amarokscript.tar.gz yourscriptname/
The ".amarokscript.tar.gz" suffix is required. Be sure it has a sub-directory named for your script, the main.js, script.spec and any supporting files.
There is currently no way to interact with the context view (middle pane) via scripts but there are plans to change this
script.spec
Script.spec provides some info to Amarok's Script Manager about your script. It's in the standard .desktop file format. A sample follows.
[Desktop Entry] Icon=get-hot-new-stuff-amarok Type=script ServiceTypes=KPluginInfo Name=Crazy Streams
Comment=A script that sets up a service with a few crazy internet radio stations
X-KDE-PluginInfo-Author=Nikolaj Hald Nielsen [email protected] X-KDE-PluginInfo-Name=Crazy Streams X-KDE-PluginInfo-Version=1.0 X-KDE-PluginInfo-Category=Scriptable Service X-KDE-PluginInfo-Depends=Amarok2.0 X-KDE-PluginInfo-License=LGPL X-KDE-PluginInfo-EnabledByDefault=false
It's a copy of the radio_station_service but I changed all instances of 'cool' to 'crazy' so I could differentiate between them. In the code, name, version and category are the important parts.
All scripts have access to the Amarok Statusbar, OSD, playlist and collection. A sample main.js file that shows some of these features follows:
Amarok.alert("I did something!"); Amarok.Window.Statusbar.setMainText( Amarok.Playlist.totalTrackCount() + " tracks in the playlist"); Amarok.Window.OSD.setText("TestOSD"); Amarok.Window.OSD.show();
Scripts can also connect to signals emitted by Amarok. A simple script that displays the number of tracks in the playlist whenever a track is added or removed could be written like this:
function tracks() { Amarok.Window.Statusbar.setMainText(Amarok.Playlist.totalTrackCount() + " tracks in the playlist"); } Amarok.Playlist.CountChanged.connect( tracks );
Legal
If you use the Qt Bindings, you are legally obligated to release your script under the GPL v2 or v3 license, under the terms of Qt 4.4's Open Source licensing. At least, it seems likely this is the case, IANAL.