Skip to content

Instantly share code, notes, and snippets.

@samtherussell
Last active January 7, 2024 19:34
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save samtherussell/335bf9ba75363bd167d2470b8689d9f2 to your computer and use it in GitHub Desktop.
Logitech SqueezeServer JSONRPC API
Squeezebox API
--------------
This document outlines the JSON RPC interface with a squeezeserver to control and obtain information about squeezeboxes.
JSON : JavaScript Object Notation
RPC : Remote Procedure Call
Uses POST requests sent to:
http://<squeezeserver_address>:9000/jsonrpc.js
With Content-Type header set to
application/json
And a JSON object in the body.
{'method': 'slim.request', 'params': [<player_mac_address>, <command>]}
where <player_mac_address> is the squeezebox's MAC address that you are controlling (or "-" to get server info).
and <command> is the command you want to send.
# Simple commands:
- PLAY: ["play"]
- PAUSE: ["pause"],
- POWER ON: ["power", "1"],
- POWER OFF: ["power", "0"],
- VOLUME UP: ["mixer","volume","+<i>"], # <i> is a base 10 number. (volume goes from 0-100)
- VOLUME DOWN: ["mixer","volume","-<i>"],
- SET VOLUME: ["mixer","volume","<i>"],
- SLEEP IN SECONDS: ["sleep","300"],
- SLEEP END OF SONG: ["jiveendoftracksleep"],
- SKIP: ["playlist","index","+1"],
- PREVIOUS: ["playlist","index","-1"],
- UNSYNC FROM ALL PLAYERS: ["sync","-"]
So to pause the squeezebox with mac address FF:FF:FF:FF you would send the JSON object:
{'method': 'slim.request', 'params': ["FF:FF:FF:FF", ["play"]]}
To get a player's status use the command:
STATUS: ["status","-"]
To SYNCHRONISE two players together:
'params': [<master>, ["sync",<slave>]]
where <master> and <slave> are the player MAC address strings.
The slave player will follow the master player.
To SWITCH PLAYER from one squeezebox to another.
'params': [<either>["switchplayer","from:" + <source>,"to:" + <destination>]]
where <source>, <destination> and <either> are the player MAC address strings.
The music will be sent from the source player to the destination player.
You can get the connected players with:
use get number of players first:
'params': ["FF:FF:FF:FF", ["player","count", "?"]]
Then using returned _count:
'params': ["FF:FF:FF:FF", ["players","0", <count>]]
You can search for music accroding to a search term by:
SEARCH: ["search", <i>, <j>, "term:" + <search_term>]
where <search_term> is the search term,
<i> is the beginning index, and <j> the finish index. ie. for the first 10 results: i=0, j=10.
Once you have obtained the "id" of the music you want to play, you can set it to play on a squeezebox:
- ["playlistcontrol", "cmd:"+<cmd>, "artist_id:"+<artist_id>]
- ["playlistcontrol", "cmd:"+<cmd>, "album_id:"+<album_id>]
- ["playlistcontrol", "cmd:"+<cmd>, "track_id:"+<track_id>]
where command is one of:
- PLAY NOW: "load"
- ADD TO END: "add"
- ADD NEXT: "insert"
@Ishidres
Copy link

Thanks, very helpful!

@foxsam21
Copy link

foxsam21 commented Jul 21, 2019

To get a player's status use the command:
STATUS: ["status","-"]

Does this work using this library or is it only by querying the server directly?

@samtherussell
Copy link
Author

Sorry for not replying. This is the Squeeze Server JSON RPC api. https://github.com/samtherussell/squeezebox-controller library interfaces with the Squeeze Server using this api, but so could any thing else if it so wished.

@mvgrimes
Copy link

Thanks for this. One fix for getting the list of players:

'params': ["FF:FF:FF:FF", ["player","0", <count>]]

should be:

'params': ["FF:FF:FF:FF", ["players","0", <count>]]

@samtherussell
Copy link
Author

Thanks for this. One fix for getting the list of players:

'params': ["FF:FF:FF:FF", ["player","0", <count>]]

should be:

'params': ["FF:FF:FF:FF", ["players","0", <count>]]

Done. Thanks for the suggestion

@nbeversl
Copy link

If you are doing this from an IP address other than the server's, how do you get around the CORS issue?

@samtherussell
Copy link
Author

Sorry, I ran these requests from a python program not a webpage so I don't know. My intuition would be you'd have to disable CORS protection in the browser or make your webserver do the request not the client browser.

@dcsooner
Copy link

dcsooner commented Feb 15, 2021

Warnings here that I don't have much of a coding background. Running LMS on an RPi with the Chromecast add-in to play on my speakers. Do you know how to incorporate this into webCoRE? Below is a piston I'm trying to write to play a playlist, but I'd probably first need to start with a single file. Also, I'm having trouble using the commands to figure out the track or album IDs.

image

@samtherussell
Copy link
Author

Sorry I don't know and don't a have a system to test on at the moment but could image it would take the form:

["playlistcontrol", "cmd:load", "playlist_id:<playlist_id>"]

@labor4
Copy link

labor4 commented Apr 9, 2022

here is some example rabbit hole to get the track artwork

bash, jq, curl
tested local and Qobuz

MYSERVER="192.168.x.x"
MYSERVERPORT="9000"
MYMACADDR="dc:a6:32:cd:b4:44" #player
 

MYTRACKID=$(curl -g -X POST -d '{"id":1,"method":"slim.request","params":["'$MYMACADDR'",["'status'","-",1]]}' http://$MYSERVER:$MYSERVERPORT/jsonrpc.js 2>/dev/null |jq -r ".result.playlist_loop[].id")


MYSONGINFO=$(curl -g -X POST -d '{"id":1,"method":"slim.request","params":["'$MYMACADDR'",["'songinfo'","-",100,"'track_id:$MYTRACKID'"]]}' http://$MYSERVER:$MYSERVERPORT/jsonrpc.js 2>/dev/null)

    
MYCOVERID=$(echo $MYSONGINFO | jq -r  ".result.songinfo_loop[] | select(.coverid) | .coverid") 

MYARTWORKURL=$(echo $MYSONGINFO | jq -r  ".result.songinfo_loop[] | select(.artwork_url) | .artwork_url") 

    
if [[ "$MYARTWORKURL" != "" ]];then
    HTTPCOVER=http://$MYSERVER:$MYSERVERPORT$MYARTWORKURL
elif [[ "$MYCOVERID" != "" ]];then
    HTTPCOVER=http://$MYSERVER:$MYSERVERPORT/music/$MYCOVERID/cover.jpg
else
    HTTPCOVER=
fi 

echo $HTTPCOVER

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment