API/Protocol
Servify API/Protocol
Short description of the currently available commands to Servify.
Servify message specification
+---------------------------+
Header | Version (int32) | <- 4 bytes, big endian
| Version (char) | <- 4 bytes
| Length of Payload (int32) | <- 4 bytes, big endian
+---------------------------+
Payload | Json message |
+---------------------------+
*/
/**
Payload
Json
base64-encoded binary data fields
utf-8 textual data
*/
/* =============================================================================
* Commands
/* =============================================================================
/* -------- Play -------- */
{
"commandType": "playTrack",
"trackNo": 0
}
/* -------- Stop -------- */
{
"commandType": "stopPlayback"
}
/* -------- Play Next Track -------- */
{
"commandType": "nextTrack"
}
/* -------- Play Previous Track -------- */
{
"commandType": "previousTrack"
}
/* -------- Pause Playback -------- */
{"commandType": "togglePause"}
/* -------- Pong -------- */
{
"commandType": "pong"
}
/* -------- List Users Playlists -------- */
{
"commandType": "listPlaylists"
}
/* -------- Browse Playlist -------- */
{
"commandType": "browsePlaylist",
"spotifyURI": "sdkfj23fmwlk23df"
}
/* -------- Browse Artist -------- */
{
"commandType": "browseArtist",
"spotifyURI": "sdkfj23fmwlk23df"
}
/* -------- Browse Album -------- */
{
"commandType": "browseAlbum",
"spotifyURI": "sdkfj23fmwlk23df"
}
/* -------- Enqueue track/album/playlist to PlayQueue -------- */
{
"commandType": "enqueue",
"spotifyURI": "sdkfj23fmwlk23df",
"spotifyURIs":
[
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df"
]
}
/* -------- StarTrack -------- */
{
"commandType": "starTrack",
"spotifyURI": "sdkfj23fmwlk23df",
"onOff": true
}
/* -------- Dequeue track from PlayQueue -------- */
{
"commandType": "dequeue",
"trackNo": 0
}
/* -------- Dequeue All tracks from PlayQueue -------- */
{
"commandType": "dequeueAll"
}
/* -------- Toggle Shuffle -------- */
{
"commandType": "toggleShuffle"
}
/* -------- Toggle Repeat -------- */
{
"commandType": "toggleRepeat"
}
/* -------- Volume -------- */
{
"commandType": "volume",
"value": 72.3
}
/* -------- Seek -------- */
{
"commandType": "seek",
"value": 72.3
}
/* -------- Search -------- */
{
"commandType": "search",
"searchString": "Alban"
}
/* -------- Toggle Mute -------- */
{
"commandType": "toggleMute"
}
/* -------- Artwork Request -------- */
{
"commandType": "artworkRequest",
"artworkType": "all"|"coverArt"|"artistPhoto",
"size": "small"|"medium"|"large",
"spotifyURI":"sdkfj23fmwlk23df",
"spotifyURIs":
[
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df"
]
}
##
## Playlist manipulation
##
/* -------- AddTrackToPlaylist -------- */
{
"commandType": "addTrackToPlaylist",
"tracks":
[
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df",
"sdkfj23fmwlk23df"
],
"playlistURI": "sdkfj23fmwlk23df"
}
/* =============================================================================
* Common types
/* =============================================================================
/* ======== Artist ======== */
{
"name": "Dan Cooper",
"spotifyURI": "dasjflaksdfj"
"albums":
[
#albumStub#,
#albumStub#
]
}
/* ======== ArtistStub ======== */
{
"name": "Dan Cooper",
"spotifyURI": "dasjflaksdfj"
}
/* ======== Track ======== */
{
"name": "track1",
"duration": 210,
"artist": "Dan Cooper",
"album": "The Album"
"popularity": 65,
"spotifyURI": "dasjflaksdfj"
}
/* ======== Album ======== */
// type: album, single, compilation, unknown
{
"name": "My album",
"year": "1985",
"spotifyURI": "dasjflaksdfj",
"albumType":"single",
"artists":
[
#artistStub#,
#artistStub#
],
"tracks":
[
#track#,
#track#,
#track#,
#track#,
]
}
/* ======== Album Stub ======== */
// type: album, single, compilation, unknown
{
"name": "My album",
"year": "1985",
"spotifyURI": "dasjflaksdfj",
"albumType":"single",
"artists":
[
#artistStub#,
#artistStub#,
]
}
/* ======== Playlist ======== */
{
"name": "My playlist",
"creator": "username",
"spotifyURI": "sdkfj23fmwlk23df",
"tracks":
[
#track#,
#track#,
#track#,
#track#
]
}
/* ======== Playlist stub ======== */
{
"name": "My playlist",
"creator": "username",
"spotifyURI": "sdkfj23fmwlk23df",
"trackCount":34
}
/* =============================================================================
* Messages
/* =============================================================================
/* -------- Hello -------- */
{
"messageType": "hello",
"severType": "Servify/C#",
"serverVersion": "1.0",
"messageVersion": "1.0"
}
/* -------- Ping -------- */
{
"messageType": "ping"
}
/* -------- Volume -------- */
{
"messageType": "volume",
"volume": 89.5
}
/* -------- Alert -------- */
{
"messageType": "alert",
"type": "error" | "info" | "warning"
"message": "This is an error message"
}
/* -------- Album -------- */
{
"messageType": "album",
"album": #album#
}
/* -------- Artist -------- */
{
"messageType": "artist",
"artist": #artist#
}
/* -------- Playback -------- */
{
"messageType": "playback",
"isPlaying": true,
"track": #track#,
"trackNo": 3
}
/* -------- Progress -------- */
{
"messageType": "progress",
"timeString": "03:22",
"percentage": 25.63,
"milliseconds": 2333
}
/* -------- Shuffle -------- */
{
"messageType": "shuffle",
"isShuffle": true
}
/* -------- Mute -------- */
{
"messageType": "mute",
"isMuted": true
}
/* -------- Repeat -------- */
{
"messageType": "repeat",
"isRepeat": true
}
/* -------- Play Queue -------- */
{
"messageType": "playQueue",
"tracks"
[
#track#,
#track#,
#track#,
#track#
]
}
/* -------- Artwork -------- */
{
"messageType": "artwork",
"type": "coverArt",
"spotifyURI": "sdkfj23fmwlk23df",
"spotifyURIs":
[
"sdkfj23fmwlk23df"
"sdkfj23fmwlk23df"
"sdkfj23fmwlk23df"
],
"size": "small",
"imageData": <>
}
/* -------- List of Playlists -------- */
{
"messageType": "listOfPlaylists",
"playlists":
[
#playlist stub#,
#playlist stub#,
#playlist stub#
]
}
/* -------- Playlist -------- */
{
"messageType": "playlist",
"playlist": #playlist object#
}
/* -------- SearchResult -------- */
{
"messageType": "searchResult",
"searchString": "Alban",
"tracks":
[
#track,
#track,
#track,
#track,
#track,
#track
],
"albums":
[
#albumStub,
#albumStub,
#albumStub,
#albumStub
],
"artists":
[
#artist,
#artist,
#artist,
#artist
]
}
August 17th, 2011 - 15:03
I’m a bit impatient so until I get a chance to try this out…
In order to use the API it’s an HTTP GET/POST request and response cycle using plain JSON? The payload doesn’t have to be bundled in any way?
I could even use curl to communicate with Servify?
This really looks good are you going to open the code or do you want to protect your IP?
Where’s your donate button :)?
August 25th, 2011 - 21:31
Anthony, each request/response must have a header as described in the protocol document.
September 30th, 2011 - 14:49
Could you post a simple example, please? An example header and an example for say, getting all playlists. Oh, and please open the code for the servify/C#. No good reason for keeping it closed, eh?
October 2nd, 2011 - 01:24
Ravi: a code (java) example of how to send messages to Servify:
DataOutputStream dataStream = new DataOutputStream(socket.getOutputStream());
dataStream.writeInt(1);
dataStream.writeBytes(“H3X!”);
dataStream.writeInt(payload.length());
dataStream.writeBytes(payload);
dataStream.flush();
payload is a string such as:
{“commandType”: “toggleShuffle”}
See the API/Protocol stuff here on h3x.se for more info about different messages.
January 13th, 2012 - 00:50
Hello!
Can we use this somehow to dump songs to hdd. And use other players to listen to it.
Applian Media Catcher won’t work.
Thanks
January 15th, 2012 - 00:25
Dave; no
January 28th, 2012 - 04:39
Hi mate,
Classic 4:30am mistake:
βHEX!β should be “H3X!”
Hence the incorrect magic string. Feel free to delete my noise π
January 29th, 2012 - 01:52
Alex, good that you got it working.. and yes, classic mistake π
June 2nd, 2012 - 19:29
Any plans on adding support for local files?
June 3rd, 2012 - 13:56
Patrik, no. Not at this time.
July 13th, 2012 - 18:23
Hey..
would i be able to use servify with jQuery?
By doing something like an $.ajax call with the right headers defined?
and if so how should the headers be?
October 3rd, 2012 - 01:49
Hello I ahave just discovered you program and I am having trouble sending the header. This is what im sending, can you see anything wrong?
Any help greatly appreciated.
POST / HTTP/1.1
HOST: 192.168.1.134:1337
Content-Type: application/json
1
H3X!
Content-Length: 30
{“commandType”: “stopPlayback”}